PDA

View Full Version : Faking Stopmotion


ljilekor
10-28-2006, 06:23 AM
Hello,

I'm on a production where 3D characters have to be integrated into live stopmotion.
The challenge is to match the imperfections that naturally occur in stopmotion character animation.

It's kinda funny: the collegues in stopmotion are doing their ultimate best (big up to the guys) to make the animation as smooth as possible while we, in the 3D section, are looking for ways to '**** it up'.

I figured that the best way to do it is to animate smoothly (12fps for normal movements / 24fps for fast stuff and moving camera stuff) and then randomize the current time with a maximum of 1.0 frames.
To work properly (avoid going back in time), the error range (StopMotion_Error_Range) shouldn't exeed 1 frame.
eg. on current time frame 10, the resulting frame should be between 9.5 and 10.5.

SM_time = CUR_time + random(-0.5 frames, 0.5 frames)

eg. frame 0 = 0
frame 1 = 0.956
frame 2 = 2.135
frame 3 = 2.863
frame 4 = 4.032
...

The following code is an example of the expression it on just one channel :

float $SMERR = SM_CTRL.StopMotion_Error_Range/2.0;
float $cFrame = `currentTime -q` + rand ( -$SMERR, $SMERR);

float $U_ARM_rx[]=`keyframe -at rx -t $cFrame -q -eval U_ARM`;
SM_U_ARM.rotateX = $U_ARM_rx[0];

//
print ($cFrame"\n");
//


It's quite simple and it works kinda fine. The problem is that each time I playback, other resulting frames are calculated due to the random function.
To resolve this there's a simple sollution. Use the seed function! (only the 1st line is different)

seed 666;
float $SMERR = SM_CTRL.StopMotion_Error_Range/2.0;
float $cFrame = `currentTime -q` + rand ( -$SMERR, $SMERR);

float $U_ARM_rx[]=`keyframe -at rx -t $cFrame -q -eval U_ARM`;
SM_U_ARM.rotateX = $U_ARM_rx[0];

//
print ($cFrame+"\n");
//


Well... euuhmm... No. It doesnt work...

Everything works fine when tested in the MEL editor.
The print function at the bottom of the expression returns the correct randomized frames for $cFrame.

But the result doesn't take the random into account... (when StopMotion_Error_Range=1 I just get a 1 frame offset, no random)

Is this a stupid MEL bug... (again) or am I doing something wrong?

Thanks in advance for helping me out.

dbsmith
10-29-2006, 03:30 AM
Hmm, I gave it a go myself and didnt have any problems. Im not sure I fully understand the problem or what you are trying to do.

Anyway, i expanded your script a bit. What I did was basically created an object, set a keyframe for its X rotation value, so it was 0 at frame 1 and 90 at frame 50.
When the current time is frame 50, I ran my script so it saves out the keyframed value, but jitters the time randomly and sets a keyframe at the new random value. Is this what you were trying to achieve? Please give more details.


seed 666;

float $SMERR = 1.0/2.0;

float $cFrame = `currentTime -q` + rand ( -$SMERR, $SMERR);



float $U_ARM_rx[]=`keyframe -at rx -q -eval U_ARM`;

print ($U_ARM_rx[0]+"\n");

timeSliderClearKey;

currentTime $cFrame;

//set Attribute here eg

setAttr "U_ARM.rotateX" $U_ARM_rx[0];

setKeyframe -at rotate;

print ($cFrame+"\n");

//

tredeger
10-29-2006, 04:45 PM
Wouldn't the straight forward way to get a stop motion look be to animate strictly with stepped keys? Or is this too labor intensive for the time budget?

Ironhalo
10-30-2006, 11:21 PM
correct me if im wrong, but wont the 'by frame' option render frames 1,4,7, etc based on the number specified? ive never tried it for stop motion, but it shoudl work.

ljilekor
11-01-2006, 12:42 AM
Thx a lot 4 ur concern.

In fact, the problem isn't really the script nor the way it functions. It would work perfectly if there wasn't this one single problem :

The fact that the rand() function doesn't seem to work properly once I combine it with the seed() function.
When combining the two functions to get repeatable random results, the correct values(randomized ones) are printed out for $cFrame. But the result in the viewport is apparently not correct because the expression driven SM arm (in this case) has EXACTLY a 1 STEP offset with its driver, the '3Dmotioncurved' arm. Instead of showing the 'xform' at the calculated $cFrame.

I know I could key the results to the SM arm each step (on 1's or on 2's or ...) and then set the tangents to stepped. But I think this is a bit of an overkill... If that's the only way it works I'll do it. It's a shame that such a heavy sollution should be needed. Espacially if I need to go back and forth from 3Dcurves to fakeSM constantly to preview the stuff.

It's just that fakin' seed() that does what it should do without doing what it should do... :twisted:

This really looks like a bug...:banghead:
When I have some time, I'll make a little scene to illustrate the problem.


Thx again

dbsmith
11-01-2006, 02:37 AM
An example scene and script would be great, this is quite interesting. Have you tried something other than expressions, such as a custom mel/hypershade node connection network?
I mean, I would think that the rand() seed() problem is not so much a problem with them itself, but maybe how and where you are using them? Thats my gut feeling anyway.

large-x
11-01-2006, 09:59 AM
From what I understand, seeding with the same number (666) and calling rand with a constant value (SM_CTRL.StopMotion_Error_Range/2.0) should always give you the same value.

Giving the seed a constantly changing but repeatable variable, such as time or frame, will probably give the right effect.

float $SMERR = SM_CTRL.StopMotion_Error_Range/2.0;
int $cTime = `currentTime -q`;
seed $cTime;
float $cFrame = $cTime + rand ( -$SMERR, $SMERR);
float $U_ARM_rx[]=`keyframe -at rx -t $cFrame -q -eval U_ARM`;
xform -r $U_ARM_rx[0] 0 0;

ljilekor
11-01-2006, 01:39 PM
From what I understand, seeding with the same number (666) and calling rand with a constant value (SM_CTRL.StopMotion_Error_Range/2.0) should always give you the same value.

Giving the seed a constantly changing but repeatable variable, such as time or frame, will probably give the right effect.

Gadamn! 666, the number of the beast had me by the balls.:eek: A messiah came down and delevered me from it's eeeevil spell.
Thx Large-X for showing me the true path to enlightment. Now that u showed me, I wonder how I could ever ve been soooo stupid.

:bowdown: :bowdown: :bowdown:

PS: I tried Hypershading by using a random on the time node but I needed to control the separate parts of my character, not global time.

sugarandfat
02-14-2007, 02:51 PM
How would I have to modify that script to fit, say, the translate.x of a sphere, or any other channel that I already have keyframed and want to randomise?

Daniel.

Allpeace
02-20-2007, 11:39 AM
PS: I tried Hypershading by using a random on the time node but I needed to control the separate parts of my character, not global time.

How about creating a new time node and connecting that one to your animation curves?

I hope you post the final result, because it sounds really interesting.

sparaig
02-20-2007, 11:33 PM
Hello,

I'm on a production where 3D characters have to be integrated into live stopmotion.
The challenge is to match the imperfections that naturally occur in stopmotion character animation.

It's kinda funny: the collegues in stopmotion are doing their ultimate best (big up to the guys) to make the animation as smooth as possible while we, in the 3D section, are looking for ways to '**** it up'.

I figured that the best way to do it is to animate smoothly (12fps for normal movements / 24fps for fast stuff and moving camera stuff) and then randomize the current time with a maximum of 1.0 frames.
To work properly (avoid going back in time), the error range (StopMotion_Error_Range) shouldn't exeed 1 frame.
eg. on current time frame 10, the resulting frame should be between 9.5 and 10.5.

SM_time = CUR_time + random(-0.5 frames, 0.5 frames)

[...]

Thanks in advance for helping me out.

Interesting that that works so well. A more physically accurate simulation would be to randomly jitter the translate/rotate values of random parts of each animated figure in the scene, assuming that they had changed from the last frame. That you don't need to do this to get the "right" effect suggests that the stop-motion guys are doing an amazing job in the first place.

ljilekor
02-21-2007, 02:04 AM
A more physically accurate simulation would be to randomly jitter the translate/rotate values of random parts

Thought that at first. After some research, we saw that this option wasn't the right one... It's about randomizing the motion, not too much 'everything'.



That you don't need to do this to get the "right" effect suggests that the stop-motion guys are doing an amazing job in the first place.

Damn right.



btw, I finished a script that allows too add the stopmotion feel. It's a brute force approach... but it's quite versatile. The user is able to edit different SMFakers on different collections of objects. This way SM settings can be finetuned and even keyed. eg. global motion on 1's, limbs on 2's, ... all this with a variable inaccuracy factor.
Have to dig it up somewhere... Post it asap.

ljilekor
02-21-2007, 11:36 AM
So here's the little mel. As I said... brute force but versatile...

CGTalk Moderation
02-21-2007, 11:36 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.