Basic question about Mel


#1

Hey guys I’m just getting started in using codes in maya for my rigs and I have a question, how can I say to maya :

For each new frame, add MyObject.Attr1 to MyObject.Attr2 ?

In my instance, I want to have control over an object’s rotation by animating the number of turns per second and if I simply say MyObject.RotateX = (MyObject.TurnsPerSec * 360 * time1.OutTime) / 24, I can’t make it slow down without reversing the direction of the rotation.
This is why I need to add a value each frame instead of simply myultiplying my value with the number of frames ^^

Thank you very much :slight_smile:


#2

I’m not sure what you exactly want to do. If you have this expression:

MyObject.RotateX = (MyObject.TurnsPerSec * 360 * time1.OutTime) / 24

And you animate the attribute MyObject.TurnsPerSec, the rotation speed should change. So where is your problem?


#3

Of course it will work perfectly if I increase this value, but if I reduce it, it will not slow down, it will reverse the direction of the rotation, this is why I don’t need to multiply the number of turns per sec and the crurent frame, but I need to add a value every second. Basically I need to have a mathematical sequence :

a(n) = a(n-1) + MyObject.TurnsPerSec * 360 / 24

with n = current frame = time1.OutTime
a = MyObject.RotateX

instead of a function

f(x) = MyObject.TurnsPerSec * 360 * x / 24

With f(x) = MyObject.RotateX
x = time1.OutTime


#4

Not sure why you experience a reversed animation. I tried it in an expression:

pCube1.rotateY = (pCube1.tps * 360 * time1.outTime) / 24.0;

And it worked perfectly even if I prefer frame or time instead of time1.outTime.

As an alternative, you could try to retrieve the attribute, increase it and put it back again:


float $rx = pCube1.rotateY;
$rx += 1;
pCube1.rotateY = $rx;


#5

Haggi, if tps is the speed of the rotation, then setting it to zero in the original expression will always set the total rotation to zero, so you would expect some forward and reverse depending on how tps was animated. But I’m pretty sure he wants it to accumulate rotation at the rate of tps.

So combine your last suggestion with part of KevinBORJONPIRON’s original expression…

float $rx = pCube1.rotateY;
$rx += pCube1.tps * 360 / 24.0;
pCube1.rotateY = $rx;

I think that would do it.

I always end up baking out the result of these kind of expressions to avoid the weird stuff that happens when scrubbing in the timeline and when reopening a scene.

David


#6

Oh, yes. You are right, now I get it. Not enough coffee today…


#7

Hey guys, thank you very much for your help.

float $rx = pCube1.rotateX;
$rx += pCube1.tps * 360 / 24.0;
pCube1.rotateX = $rx;

If $rx = pCube1.rotateX and pCube1.rotateX = $rx, as I understand it, it is a loop and maya can’t compute it correctly (try it, it is a mess in Maya :/). I think this expression lacks the time element (time1.OutTime).

I don’t really know how to do this, but as I understand it, we have to keep the result of the precedent frame in an array and add to it pCube1.tps * 360 / 24.0.

the reasoning is :

a(time1.OutTime) = a(time1.OutTime - 1) + pCube.tps * 360 / 24

So for instance, if

time1.OutTime = 6 and pCube.tps = 1
pCube.RotateX = 90

Then for time1.OutTime = 7 and pCube.tps = 10
pCube.RotateX = 90 + 10 * 360 / 24 = 240

What do you think guys ?


#8

The cycle you are concerned about would not be a problem in an expression. And the time element is implicit since the expression is run once per frame.

Here’s a simple example. I added a float attr called “speed” to pCube1. I animate speed with keyframes.
The expression that sets the rotation would look like this:

if (frame == 1) {
    pCube1.rotateX = 0;
}
else {
    float $x = pCube1.rotateX;
    print (pCube1.rotateX + "
");
    pCube1.rotateX = $x + pCube1.speed;
}

In my example I’m resetting the rotation at frame 1, so that the rotation starts from the same value each time.

This expression would give a different result if you hit play, compared to jumping to a frame. Thats the reason I mentioned baking it to keyframes in my first post. Alternatively you could write a more complicated expression to iterate over every frame at each step and sample the speed attr at each frame, but this would involve using a getAttr which is usually frowned upon in expressions for performance reasons. I usually try to avoid anything complicated like that. Often the animators would prefer to simply just key the rotation directly. But the expression I showed here works for keying speed instead.

David


#9

Hey man, thank you so much, it seems to work perfectly :smiley: Or at least it’s the most efficient way to do it I’ve got so far :smiley: