Maya gotchas - the lastPosition attribute of particles

Posted 15 October, 2012 Anthony Tan (staring at yet another render. But still loving it for some reason..)

« previous | next »

The more you get into dynamics and simulation-y stuff, the more it behooves you to know about the quirks out there - like how the lastPosition attribute is a bit mis-marketed - it's the last position of the particle BEFORE dynamics affected it.

That's one helluva nuance

According to the Maya documentation, the lastPosition attribute of a particle records "the position of the particles at the end of the previous timestep."

What it actually records is the position of the particle at the previous timestep BEFORE DYNAMICS. That's like, a huge distinction.. in my (admittedly limited) understanding of the dynamics system, each cycle of operation involves:

  1. a call being made to the pre-dynamics code;
  2. control being passed to the solver; and
  3. your post-dynamics code being called.

I'd expect the lastPosition attribute to reflect the last position a particle reached in this cycle but here's a simple test to illustrate.

Scene setup

Just paint some particles down and while you're at it, and we'll get straight into the Expression Editor. For creation, you'll want to set the following so our particles drift. (velocity = <<1,0,0>>; and then stick this code in to probe what the values are like before and after dynamics. Obviously one goes in the before dynamics slot, and one goes in the after dynamics slot.

if(particleId == 0){
	print("------Frame"+ frame +"------\n");
	print("Runtime BEFORE dynamics\n");
	print("curPos     : "+ (position-position0) +"\n");
	print("lastPos    : "+ (lastPosition-position0) +"\n");
	print("\n");
}


if(particleId == 0){
	print("Runtime AFTER dynamics\n");
	print("curPos     : "+ (position-position0) +"\n");
	print("lastPos    : "+ ( lastPosition-position0) +"\n");
	print("------------------\n\n");
}
(I'm just correcting for the initial particle position so it's clearer and there's less noise, and the particleId trap just means we're not spammed with output..)

step through a couple of frames and you'll see some output that roughly looks like this:

------Frame13------
Runtime BEFORE dynamics
curPos     : 0.4583333333 0 0
lastPos    : 0.4166666667 0 0

Runtime AFTER dynamics
curPos     : 0.5 0 0
lastPos    : 0.4166666667 0 0
------------------

------Frame14------
Runtime BEFORE dynamics
curPos     : 0.5 0 0
lastPos    : 0.4583333333 0 0

Runtime AFTER dynamics
curPos     : 0.5416666667 0 0
lastPos    : 0.4583333333 0 0
------------------

Anything obvious? lastPosition doesn't change during a timestep (that's good)...but it isn't the same as the final position, post-dynamics at the previous timestep. In this specific example, the lastPos at frame 14 should've been 0.5 (imho) since that's where the particle ended up. If you want that, you'll have to create your own lastPostionPP attribute and store it yourself.

I can't decide whether or not I call this a bug or a feature.. the negative value for lastPos at the first frame suggests something odd (because how the hell can the last position of the particle be anything other than the birth value before you've run any dynamics?). However, without knowing more about the internal guts of the solver and the dynamics framework, this could actually be sane - I just don't know.. all I do know is that it's one of those gotcha moments...

Oh, and don't even get me started on nDynamics and nucleus. It's great, but it's not for the accuracy-minded.. (try the same exercise using nParticles and a nucleus solver. See how you can't rely on the value to match past 3 d.p. See why you need techies like us around? *mutter*)

(Maya 2012x64 btw)

 
previous
Clean Poly Combine & mergeAndCull - better ways to merge polys than PolyUnite
next
Maya gotchas - nParticles getting velocity from like, nowhere