5
$\begingroup$

I am wondering if there is a way, using geometry nodes, to "draw" a curve from a moving object.

Here I've created a short animation of a line segment using geometry nodes. I would like the endpoint of this segment to draw out a curve as it rotates. This would create a helix around the x-axis as the animation plays.

RotatingLineSegment

My Thoughts:

I am aware that one way to draw a curve would be to just parameterize said curve and draw it using math, like explained in this answer. This is fine when the curves are simple. In my example, the line segment is just tracing a helix and this is easy to parameterize mathematically. However, I would like to be able to animate my line segment in much more complicated ways and see the resulting curve it traces out without having to stop and parameterize the curve every time.

I'm thinking that if I can access the position of my line segment's endpoint, then I can plug this in to a Set Position node that controls a Mesh Line whose count grows with the Scene Time. So far, however, I've been unable to figure out how to access the position of the endpoint of my line segment, and I'm not even sure if I'm going in the right direction with that thought process. Help is appreciated!

In case it is important, here is my node setup for the animated line segment. NodeSetup

$\endgroup$
3
  • $\begingroup$ Is a solution which uses stuff outside of geometry nodes along the way also ok? I could imagine a procedural solution for short trails (a couple points) and a non procedural solution for the entire path which can then be animated to appear. I don't think you can do this using only GN because there is no node to sample an animation directly. $\endgroup$
    – HenrikD
    Commented Oct 4, 2022 at 21:15
  • $\begingroup$ I'm open to a solution that's not entirely node based. I'm just using geonodes because I can use them to control my object (here it's the line segment) with specific equations. I'm also very new to Blender so I could be overlooking something easy outside of geonodes that can help me. $\endgroup$
    – wgrenard
    Commented Oct 4, 2022 at 22:04
  • 1
    $\begingroup$ you can try blenderartists.org/t/convert-object-motion-path-to-curve/679316/… however I don't want to just copy his code into an answer here. $\endgroup$
    – HenrikD
    Commented Oct 4, 2022 at 22:28

2 Answers 2

8
$\begingroup$

A possible solution could look like this:

enter image description here

The trick here is that I pre-calculate the result at the beginning, and then simply remove the points that are above the current frame.

The positions of the Mesh Line are calculated in the same way as the transformation of the rotating line.

enter image description here

And here is another variation of the solution shown here, which is based on curves and reduces the duplicate nodes:

enter image description here


(Blender 3.2+)

$\endgroup$
6
  • $\begingroup$ I think there is another way, it's just making a loop from a mesh line that has as many vertices as current frame number (considering the first frame as #1). This means the setup gets very slow later in the animation, and of course it can't rely on the inputs you can't generate inside the node - e.g. another object, which data you can't access for any frame but the current. Other than that you can use a drivers with Python outside of the sandbox whitelist to save calculated data, but by many this will be considered cheating as well... $\endgroup$ Commented Oct 5, 2022 at 18:56
  • $\begingroup$ I think Animation nodes is in the moment the better choice for these kind of animations. $\endgroup$
    – Chris
    Commented Oct 5, 2022 at 19:25
  • $\begingroup$ I appreciate this answer, thanks! I'm still going through and thinking about this to see how well I can apply it to more complicated animations of the base line segment. Since this solution seems to be based on calculating the traced out curve, it seems like it may get complicated if I try to make the line segment do anything too tricky. $\endgroup$
    – wgrenard
    Commented Oct 5, 2022 at 19:39
  • $\begingroup$ @MarkusvonBroady I'm not sure if this is too off topic to add as an answer to this question, but I'm really curious to know more about what you mean by "use drivers with Python outside of the sandbox whitelist to save calculated data." Do you have any resources I could look into to learn more about that? $\endgroup$
    – wgrenard
    Commented Oct 5, 2022 at 19:44
  • 1
    $\begingroup$ @wgrenard Well, as long as you use the frame number as the basis for your calculation, you can calculate everything in advance using this value. $\endgroup$
    – quellenform
    Commented Oct 5, 2022 at 19:53
5
$\begingroup$

Currently Geometry Nodes, like almost everything else in Blender, are evaluated separately for each frame, there's no temporal continuity in a logical sense. You can't easily access a previous position of something, similarly how in a shader you can't easily access a neighboring sample/pixel. You can figure out what's supposed to be there, if you have an access to the logic that draws it. This means for more complex problems you could calculate the object position for each previous frame, with a triangular growth of performance cost, as a 1000 frame long animation would require all 1000 frames to be calculated just on the last frame; average 500 frames calculated per frame. A 2 hours long animation at 60 FPS would increase the average performance cost of the node tree $2 × 3600 ÷ 2 × 60 = 216,000$ times!

Also, quellenform's or my proposed solution above wouldn't be able to calculate positions in cases when they are based on external data like object position.

So what are the alternatives? First is using a driver. However a simple driver won't allow you to read a previous state. What you need is to use Python, and access functionality outside of the whitelisted sandbox set, in order to either:

  • at the beginning of evaluation read a state saved earlier, and at the end of evaluation save the final state for the frame;
  • at the beginning of evaluation evaluate previous frame and read data from it.

The first of the approaches requires somehow using a driver to store data, which would be unreadable even for driver hacking standards. The alternative still suffers from the triangular growth problem, because it's recursive (not to mention you may run out of memory through a very long recursion).

So rather than using a driver with just a little out-of-sandbox hack to access a previous frame, this ends up to be a complex solution, where you duplicate an attribute array for each frame, deal with a problem that it may have a different length before/after evaluation, deal with the fact your geonodes modifier might be just one of many, deal with caching, but also with a way to allow to refresh the cache... This problem is too complex for drivers, and if you just want to use Python for an iterative animation, here are good starting points:

How to add driver expression result from previous frame to current frames expression (way to compound expression output?)

Distributed interaction visualization

Pin cloth solution

An exception from the stateless nature of Blender, where each but the first frame depends on a previous one, is physics. This solution uses my previous answer where I figured how to dynamically change the PIN group by using geonodes:

Assign vertex group in Geometry Nodes (v3.3)

The idea is simple: based on frame number apply a PIN mask to your vertices - only those vertices will be moved by the cloth modifier, and the rest will stay in place.

Modifier stack: (refer to the linked answer for their settings)

Geonodes Main:

(faces are needed for boolean, but then excess vertices are removed just to end up with a mesh line)

Cloth settings:

Possibly not all of these settings are needed, the idea is that the cloth modifier is not actually supposed to simulate anything - it only keeps the previous positions and updates the positions of the PIN group:

I start the animation and simulation at frame #0, because the vertices start at index 0 and I wanted to keep the node trees simple:

Geonodes Postprocess:

Result

$\endgroup$
2
  • 1
    $\begingroup$ Very interesting solution! $\endgroup$
    – quellenform
    Commented Oct 7, 2022 at 0:35
  • $\begingroup$ Thanks for this, it's very interesting! I've done coding in the past and I always come at problems with the mindset of being able to save values and access them later, which as you explain just doesn't work in GeoNodes. I do want to take the time to learn scripting, so thanks for those links. $\endgroup$
    – wgrenard
    Commented Oct 7, 2022 at 2:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .