- Prefers to be called
- Hareid, Norway
- 5 years 10 months ago
- Last seen
- 22 hours 1 min ago
Actually, my solution posted earlier was horrible, and shouldn't be used. Something was gnawing at the back of my head, and was confirmed when I took another look at it with a lot more items. It is very, very inefficient choking at around 20 items for me. I still think that creating the grid beforehand is the most flexible solution though, but not for the reasons as posted above (or sort of at least).
The node you want to use for this sort of thing is the "Change Item in List". Then it's only a matter of calculating the index from a position in the window, get the item you want to change, do the processing, and change the item in the list. Optionally just have a different item that is the selected one. That way the rest of the list remains unchanged meaning there is no processing required for the most part. In turn this means that you can have huge selectable grids without using much processing power. This way should also be more compatible with your way of thinking about the flow if I understood you right. In the attached example I use a build list, but it is more for convenience in both testing and showing the concept. The "Build List" node can be swapped out for a list of images or objects or whatever you want to display.
So, this is the basic gist of the procedure:
I'm attaching the composition itself, and the "Grid With Index" subcomposition - because nobody wants to deal with what's inside it on a regular basis. You will need to put this in your user modules folder along with MM.Points to make the example composition work. Not sure if it's a user hack but I usually place my render node to the left if I need window info. There is usually only one wire going to the render node, so I'll just hide that one and color/comment the node going to it to neaten things up.
It seems like there is some lag when starting a composition, so you'll need to press the mouse button once after starting or resizing the window to make it display properly. I don't know why. If Jaymie or someone from team Vuo can take a look at it, they might have a few pointers as to why this happens though.
Using this approach a 100 x 100 grid of layers, and with mouse position as the selector still works on my old MBP. Laggy, but works, which is a feat considering it's 10,000 layers. 200 x 200 lags to the point of breaking the composition, but if your UI depends on 40,000 separately selectable items by hovering the mouse I think you have other issues than a laggy interface. Interestingly, using mouse buttons it works with around a second of lag at 200 x 200, and technically still works at 500 x 500, but I wouldn't call it usable. However at 250,000 layers I'm surprised it runs at all. Especially considering this is with old intel integrated gfx and Haswell series CPU. So depending on your hardware, your experience may be quite a bit different.
Haha, it was way to late in the evening when writing that, and I didn't exactly do a good job of explaining! Good to see you got it working! One cool (or annoying) thing with your approach is that it should be fairly easy to animate the overlay using the Smooth with *** nodes so that it glides to the next one instead of popping over. A thing to keep in mind when using Build/Process List is that the whole function of the loop has to be contained within that node hierarchy, or you'll get errors. This means that you can't pass a value from inside the loop to an outside node without it being part of the "Finished Building" port. I suspect the issue might lie there in your first iteration.
To explain my approach a bit better (hopefully), system nodes are lime, math nodes are yellow, input is blue, constructors are magenta and the build loop is orange. In addition the hold nodes are there to sync outside values to the loop and are colored violet.
It works by first getting the window dimensions and setting the start/end of a "Points along Line (2D)" to the left/right points of the window. The width is then divided by the amount of elements you want, that gives you the per-layer dimensions, and also a "bounding box" for checking the mouse position. Height is hard-coded to 1 in this instance, but the height calculation is the same as for width if you want a 2D grid (or 3D, but then you'll need depth and a different input than the mouse to get a 3D point to check).
This data is then fed into a "Build List" node that checks the mouse position and then create the layers based on that input (changes color if the point is within the rectangle bounds of the point). This way you set up, create and check all parameters before making the layers, what I clumsily referred to as "selecting forwards". This as opposed to creating the layers and doing the selection and manipulation after the fact (or selecting backwards).
For me the flexibility that points provide usually is a lot easier to relate to, but as it is more of an abstract way of thinking about compositing it can be a bit of a task to wrap your head around it. In that vein, the composition I posted isn't restricted to layers, but can be images or objects, or even points to generate other points from (which can again be used to tile layers/objects/images/points. To swap it around, the only node you need to change is the "Make Rectangle Layer". To organize things in a circle, swap out the "Make Points Along Line", insert a MM.Spirograph node (for simplicity) and add the calculations for height.
I do think that the learning curve might be a bit steep, and see the need for simple UI nodes. I also understand that it's hard to make a one-size-fits-all node for these things without it being an unwieldy and huge node to account for all permutations of how to select things. Most of it should by now be possible to do with subcomps, which I think is the preferred way of solving it as they can easily be changed by the end user.
You could try something like this:
Looks a bit excessive, but should scale up pretty easily to 2d and 3d grids as well. The general idea is to select forwards, not backwards. That way you check the points and create and modify any layers/images/objects on those points based on an arbitrary input (mouse position in this case).