Follow Curve - maintain joint volume - layer script WIP

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Follow Curve - maintain joint volume - layer script WIP

Post by heyvern »

This developed from a discussion in the feature request area. It started out as a discussion on the idea of a new feature for creating bending joints for limbs that maintain volume. Genete showed us a demonstration of a feature in Synfig that looked fantastic so I decided to try this in AS with a layer script.

The script will "bind" a point to a spline. This point will "follow" along the curve of the spline as a bone is rotated. This can be used to adjust shapes as the joints bend creating better limb bends and shapes that maintain volume as they bend. The volume of the shape is maintained automtically so no animated point motion is needed, however the points of the curve that controls the point can be animated as well if needed.

In the screen capture sample below there are only those two bones for the limb or joint. The inner point moves along the short spline as the bone bends the joint.

http://www.lowrestv.com/anime_studio/sc ... -curve.htm

This is a rough script right now. I need to develop a process for implementation. Once I get this working any number of splines can be added to move not only points but bones as well. A bones motion could be controlled by a spline. Motion of a bone could be "drawn" on a vector layer.

-vern
Genete
Posts: 3483
Joined: Tue Oct 17, 2006 3:27 pm
Location: España / Spain

Post by Genete »

Congratulations!
This will be a hit! :)
-G
User avatar
DK
Posts: 2896
Joined: Mon Aug 09, 2004 6:06 am
Location: Australia

Post by DK »

Holy guacamole Vern! Yipeeeeee!!!!

EDIT: Vern, just out of curiosity. Do you think the animation derived from this script will output to swf format?

Cheers
D.K
Last edited by DK on Sat Jan 24, 2009 4:13 am, edited 1 time in total.
User avatar
mkelley
Posts: 1647
Joined: Fri Nov 02, 2007 5:29 pm
Location: Sunny Florida
Contact:

Post by mkelley »

Looks good -- I assume the motion will be "relative" (which is to say the if the arm itself moves or is rotated the motion of the curve stays relative to the arm position at first definition).
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Yes this DOES export to SWF or Flash format. Just tested it. Of course it isn't "optimized" which would be expected.

To better understand the concept think of these "path" constraints just like "bones". They are like mini bone paths... uh... sort of. You constrain point/s to these paths as you might bind a point or points to a bone. You treat these "constraint paths" just like any other vector. They can be bound to a bone or flexi-bound what ever.

The key is that any point bound to this path follows the path where ever it goes. If the path is bound to a spinning bone a point will traverse the path as it is spun by the bone.

The thing I need to do now is to finish the set up and expand the concept for longer paths. I have to do some math... stuff... to figure out how to use more than 3 point splines.

Here's what the script does:

A vector layer has a mesh. A mesh is made up of curves. A curve is made up of points/segments. Each segment has two points.

In the test script the path I'm using has two segments. there is a function or property called:

Code: Select all

PointOnSegment(segID, percent)
First I need to identify the curve. Then to find a point along the curve I have to identify each segment of the curve. In this example there are two segments (3 points). So I have segID = 0 (0 is the first segment) And then I convert the bone's rotation to a percent value to find a spot along that segment.

There are two segments so I have to fiddle with the math and "split" the percentage so the point travels 100% to the end of the first segment and then skips to the next one and does the same thing.

This is easy with two segments, but if the path has 4 or 6 or 20 segments, I need to come up with a formula to make a percentage along each segment so it adds up to the WHOLE segment.

I was thinking of just limiting this to 2 segments for the joint volume issue. A 3 point path is all that would be needed in that case... but I hate to limit it to just 3 points and I know there is way to calculate the whole path. I can count the segments and divide 100% by whatever... times... uh... something.... blah blah blah. I'll figure it out eventually. ;)

I will have to use named bones and point groups to "match" a path to it's "point". I am doing that in the example above. I have a named group for the joint path and a named group for the point that moves along the path. Works like a charm. The movement along the path is driven by the bone rotation. There has to be some way to "drive" the point along the path and obviously a bone rotation is the way to do this. I suppose it could be modified for bone translation or scale as well.

the other option I want to add is multiple points following a path. If a set of points follow the path they could be set to follow along using "relative" locations. Instead of all jumping to one single point they jump to that location relative to their original location. This should be fairly easy to include... and leads to my other exciting use for this script...

The "2.5D" head/body turning. Imagine a curved path. An ellipse that defines a circular path for a head turn. This path would be moved and distorted by simple bone motion to change it's shape.

Other bones that control the facial features would be forced to travel along this path by another bone. This provides a simple and totally user controlled mechanism for creating head turns.

Because BONES are moving along the path instead of points you could add in additional bones to distort the paths as well. Just like my complex face rig with over 200 bones you could have a turning head able to do lip sync from any angle using a tiny fraction of those bones to achieve this.

You could have a series of paths for different parts of the face; eyes, nose, mouth etc. This completely eliminates the need for those "springy" bones I've been using for face rigs. The drawn PATH defines this circular motion creating a 3D turn using very few bones and very simple scripting.

I haven't worked out all the details to pull this off but it's going to be WAY easier than how I was doing it before using ALL bones. Using drawn paths to "predefine" the rotation path will solve a ton of issues and provide a lot of ability to "visibly" tweak this rotation. You will be able to "see" the rotation path.

Other things that can be done with this haven't really been explored yet. The options seem endless. Total motion controlled by drawn vectors. At some point with more options you could theoretically "draw" the motion instead of key framing a ton of bones. All the motion could be driven by the paths and just a few bone rotations. Or maybe the points on the path determine the motion and no key frames are needed.

This is further down the road but I'm very excited about the possibilities.

-vern
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Just so you guys know. One of my feature requests is a place to "store" data in the file format. If this were added to AS you wouldn't need to name bones with special names or use point groups with special names, you could assign properties to bones and groups and store this in the file format. When the file is opened this info is read back in.

I could create a pop up to select bones or points or point groups to be added to joint paths etc. This would work for ANY script. This is one one of those "simple" features that would expand AS a bazillion percent.

This should probably be my number one feature request... but I have a few number ones it's hard to pick. ;)

Because there are so few lua scripters we don't get a ton of support for our feature requests. No one seems to understand that those features have a lot more potential for the non scripting users.

-vern
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Sounds amazing Vern!

Uh, you mention it being swf compatible. Is this not a layer script?

Yeah, we definitely need a better way to store info other than writing a ton of text files for each project. I have a few ideas about working around this, but my heads in another script right now.


If you pull this one off, Mike's going to have to work hard to make a feature near as revolutionary. Maybe that alone will be enough to draw his focus to some more scripting access.

:wink:
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Yes it is a layer script but it modifies the position of points which apparently exports to SWF without problems. I just did a test and it works.

Funny thing, I had tons of trouble at first. I had this line in the code:

Code: Select all

moho.layer:UpdateCurFrame()
I always use this to update point positions. I thought I had to have it. If I leave this line in this script the points don't move to the new location. It doesn't work. I took this line out and it works fine.

-vern
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Well I solved the line segment calculation. So now a curve with any number of points will work. I've also added point curvature to the equation. As the bone bends the inside point gets "pointier" till the point is peaked. This REALLY fixes the whole joint bend issue.

I had to "cheat" to do this. Point curvature can only be set using a key frame. To avoid putting a key on every frame I set the key for curvature of that one point on frame 1. The key frame on frame 1 changes and then is "seen" on all frames after it so it appears to animate but does not add keys on every frame. I used this trick before with z axis shifting of layers for layer order scripting.

The one thing I really want to do now is figure out a way to have "reversible" joints. Joints that work in either direction. That might be a tad tricky using negative values... but it should work. I should be able to just set the points to the default location when the rotation goes above or below 0 for either side of the joint and the path. A duplicate path would be needed for each side of the joint, or possibly the same path can be used for both and just reverse the point locations.

-vern
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Latest example with point curvature added and upper bone rotation. The joint "curve" is bound to the upper bone showing how the other point follows along no matter where the curve is.

Also as you can see this is an SWF. So Flash export works fine.

http://www.lowrestv.com/anime_studio/sc ... curve2.swf

Hard to see in the animation but there is an issue regarding the number of points in the path and how close together they are. The closer the points are the "slower" the point will travel through that segment. I think this could be a good thing. However I could try to figure out how to evenly distribute the motion equally over the whole path... kind of tricky though based on how AS divides curves using the points as segment markers... actually this could be really really tricky.

-vern
User avatar
DK
Posts: 2896
Joined: Mon Aug 09, 2004 6:06 am
Location: Australia

Post by DK »

Great stuff Vern. Keep it coming.

Cheers
D.K
Genete
Posts: 3483
Joined: Tue Oct 17, 2006 3:27 pm
Location: España / Spain

Post by Genete »

I think this could be a good thing. However I could try to figure out how to evenly distribute the motion equally over the whole path... kind of tricky though based on how AS divides curves using the points as segment markers... actually this could be really really tricky.
To do that you have to be able to calculate the segment length, add them all and then assign a percentage value to each point on the curve based on the total length and each segment lenght.

I think that there is not interface to retrieve a segment length.
-G
User avatar
funksmaname
Posts: 3174
Joined: Tue May 29, 2007 11:31 am
Location: New Zealand

Post by funksmaname »

this is groundbreaking! can't wait for the script release :)
Go Vern!
User avatar
heyvern
Posts: 7042
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Well, it's still early yet but I'm getting a performance hit. I've got four limbs with automated paths for each side of the joint (symmetrical bending joints) and there seems to be "issues" with managing the lua tables. I'm going to keep tweaking the code and see if I can speed it up or improve it.

This could just be my slow Mac that I'm using right now for this (PC is busy doing other things). I will test it on the PC later to see if that's the case.

http://www.lowrestv.com/anime_studio/sc ... curve3.swf

Here's the general setup so far:

Name the bone that drives the joint "expansion" with a .path extension, like "left_forearm.path"

Name the path/group to guide the point on the "positive" side of the bone rotation "left_forearm.path".
Name the single point group on the positive side of the joint "left_forearm.point".

Name the joint path on the "negative" side of the joint "left_forearm-reverse.path"
Name the single point group on the negative side of the joint "left_forearm-reverse.point".

Sounds like a lot but it's really easy and doesn't take very long especially considering the alternatives. You can leave out the "reversed" part if you only need a joint that bends in one direction. The script can adapt to that.

In this current implementation the bone driving the rotation must be at 0 degrees on frame 0. I will see how hard it will be to change this but right now it's not a big deal as this would be straight in line with the upper arm. Remember that orienting a child bone to 0 degrees "matches" the orientation of the parent. It still might be nice to have some tweaking allowed on frame 0 of course.

After that it's all automated. This setup may change.

-vern
User avatar
synthsin75
Posts: 10280
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

I have a question. Could you setup a circular path? I know that may be asking too much, but I like joints (especially elbows) that can rotate all the way around. So this circular path would work for both sides simultaneously, or I'd have two overlapping paths.

Just a thought. :wink:

Awesome work so far.
Post Reply