Get position of a point after being affected by a bone

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

Moderators: Víctor Paredes, Belgarath, slowtiger

ponysmasher
Posts: 370
Joined: Wed Aug 04, 2004 6:23 pm
Location: Los Angeles
Contact:

Get position of a point after being affected by a bone

Post by ponysmasher »

Picture time!

Let's say I have a character with his arm up like this:
Image

He lowers his arm, but now his shoulder looks bad:
Image

So I fix it with some point animation:
Image

Then he raises his arm again:
Image

If I copy the point keyframes of his shoulder from earlier then all is well:
Image

But if I try to do it using a script, the points move to the exact point they were at frame 0, before the bone ever moved:
Image

Is there a way to copy the keyframes like AS does but using script?

Right now I'm using the fAnimPos value.
Rudiger
Posts: 786
Joined: Sat Dec 17, 2005 5:25 pm

Post by Rudiger »

Wow, cool character!

You should be able to do what you are saying, as long as you are not trying to do your own brain surgery. That is, write the same key you are reading from. Are you getting the value from fAnimPos and well as setting fAnimPos? Are you specifying the frame correctly? Perhaps, if I see some code, I can tell what's going wrong.

It might also be better to get your corrective morphs from an action instead of the main timeline. Then you could have actions called shoulder_up and shoulder_down and, whenever there is a key on the shoulder bone, your script could insert one of those two actions depending on the angle of the shoulder bone. Something I'm working on, is to actually control the weight of the corrective action applied, depending on the angle of the bone.

Good luck!
ponysmasher
Posts: 370
Joined: Wed Aug 04, 2004 6:23 pm
Location: Los Angeles
Contact:

Post by ponysmasher »

Thanks!

The script is not just for that, it's just how I discovered the error. I've made something that I call "point time machine". Yeah, I didn't know what else to call it...

http://www.dauid.com/tools/scripts/ds_point_time.zip

What it does is you select points and then move the mouse right or left while holding down the mouse button. If you move left it will get the point positions and curvature from earlier frames ("the past"), and if you move to the right it takes values from later frames, ("the future").

You can also specify a frame that it will always start from so you could, for example, put keyframes for all the mouths you will need on frames 99-113 and then copy them to other frames just by moving the mouse.

Kind of hard to explain but it's a tool that would fit in my workflow.

I've also made a "bone time machine" but that seems to be working. For now...

Oh, and I'm getting the fAnimPos values but setting the fPos. But I think I tried setting the fAnimPos as well.
Rudiger
Posts: 786
Joined: Sat Dec 17, 2005 5:25 pm

Post by Rudiger »

Sounds like a very innovative tool! It's great to see more scripters on this forum!

I had assumed it was a layer script, but since it is a tool script, then you definitely want to set a keyframe on fAnimPos and not fPos. Any thing you do to fPos will only be temporary, until the next time AS updates it. When setting a key with fAnimPos, remember to do add the key first, then set its value:

eg
point.fAnimPos:AddKey(frame)
point.fAnimPos:SetValue(frame, value)

I will look at your script more closely when I get the chance.
Genete
Posts: 3483
Joined: Tue Oct 17, 2006 7:27 am
Location: España / Spain

Post by Genete »

For the original question in your post title you can use the following functions:

Code: Select all

Class: M_Bone

fPtMatrix (LM_Matrix)

the transformation matrix for the influence the bone has over vector points
And

Code: Select all

Class: Matrix

void Transform(vec2)

Apply a matrix transformation to a 2D vector object.
vec2 (Vector2): a vector to transform Return value: none
Hope that helps you in this or other scripts.
Nice innovative tool indeed.
-G
Rudiger
Posts: 786
Joined: Sat Dec 17, 2005 5:25 pm

Post by Rudiger »

Genete wrote:For the original question in your post title you can use the following functions:

Code: Select all

Class: M_Bone

fPtMatrix (LM_Matrix)

the transformation matrix for the influence the bone has over vector points
And

Code: Select all

Class: Matrix

void Transform(vec2)

Apply a matrix transformation to a 2D vector object.
vec2 (Vector2): a vector to transform Return value: none
Hope that helps you in this or other scripts.
Nice innovative tool indeed.
-G
Hi Genete,

Have you ever been able to do anything useful with a bone's fptMatrix variable? I've found that it only can be used to transform a point if the point isn't under the influence of any other bones. IE I don't know of an easy way to combine the influence of several bones on each point.
ponysmasher
Posts: 370
Joined: Wed Aug 04, 2004 6:23 pm
Location: Los Angeles
Contact:

Post by ponysmasher »

Hm, nothing happens at all when I use fAnimPos. I think that's why I went with fPos. I'm just learning by trial and error.

This is the part of the code that currently does nothing:

Code: Select all

pt.fAnimPos:AddKey(curFrame) 
newPosV=pt.fAnimPos:GetValue(newFrame)
pt.fAnimPos:SetValue(curFrame, newPosV)
I'm going to look into the whole matrix thing, but then you'd have to get infromation about what bones affect the selected point right?

I have a feeling this is going to hurt my head...
Rudiger
Posts: 786
Joined: Sat Dec 17, 2005 5:25 pm

Post by Rudiger »

ponysmasher wrote:Hm, nothing happens at all when I use fAnimPos. I think that's why I went with fPos. I'm just learning by trial and error.

This is the part of the code that currently does nothing:

Code: Select all

pt.fAnimPos:AddKey(curFrame) 
newPosV=pt.fAnimPos:GetValue(newFrame)
pt.fAnimPos:SetValue(curFrame, newPosV)
I'm going to look into the whole matrix thing, but then you'd have to get infromation about what bones affect the selected point right?

I have a feeling this is going to hurt my head...
Not sure if it matters, but you could try switching the first and second lines around, like so:

Code: Select all

newPosV=pt.fAnimPos:GetValue(newFrame)
pt.fAnimPos:AddKey(curFrame) 
pt.fAnimPos:SetValue(curFrame, newPosV)
Genete
Posts: 3483
Joined: Tue Oct 17, 2006 7:27 am
Location: España / Spain

Post by Genete »

Rudiger wrote:Have you ever been able to do anything useful with a bone's fptMatrix variable? I've found that it only can be used to transform a point if the point isn't under the influence of any other bones.
The function is applied for a bone only, yes. It is a bone-point relationship.
rudiger wrote:IE I don't know of an easy way to combine the influence of several bones on each point.
I think that you should multiply the influence matrixes to obtain the compund transform matrix. Also I think you have to conside the hierarchy of bones and to multiply in between the bone tranform matrix too. Never have worked with it before. I'm just guessing.
Start with two root bones and one point and see what happens. Then continue with two bones parent and child bones and one point and see how does it work. Also try to apply single operations (i.e. only scale one bone or only roate one bone) to make more predictable and hand made calculable results.
-G
User avatar
heyvern
Posts: 7043
Joined: Thu Sep 01, 2005 8:49 pm

Post by heyvern »

I have tried and tried to use bone influence matrix. I was never able to figure out how to use it. It could be my lack of... uh... math knowledge. :)

I wanted to create "invisible" bones. Create a "pseudo" bone entirely from a script that could influence points with out needing a "real" bone. Then I could put all of my "fancy" bones in my scripts as "fake" bones to avoid cluttering up the preview with a bunch of bones.

------

There is a way to do what you want moving points like that without scripting. I have a trick I used in the "Fritz" character that comes with AS in the partners content.

If you look at his hips/thighs bone set up there are a set of bones with constraints. One bone "stops" at a certain point and another bone continues. It creates a sort of "point" motion when a bone reaches a specific rotation. Basically it is based on parenting and angle constraints. A child bone stops rotating using an angle constraint but the parent keeps going rotating the child with it. In the opposite direction the child keeps going but the parent stops. this creates a mirror image of motion on either side of the hips/thighs. I used this to create the smooth overlapping thighs at the hips.

Hips and shoulders are ALWAYS a freaking pain in the arse to rig. I hate using point motion so I try to find bone solutions that give the results I need.

-vern
User avatar
Víctor Paredes
Site Admin
Posts: 5826
Joined: Tue Jan 25, 2005 3:18 pm
Location: Barcelona/Chile
Contact:

Post by Víctor Paredes »

Wow. I'm just arriving home and I get this surprise. What fantastic scripts!
thank you very much, they are just clever.
I'm working right now in a project with it. It makes everything 300% easier!

thank you!
Image Image Image Image Image Image
Moho co-owner

Previously Rigged animation supervisor: My father's dragon, Wolfwalkers & Star Wars Visions "Screecher's Reach"
My personal Youtube Channel
User avatar
Víctor Paredes
Site Admin
Posts: 5826
Joined: Tue Jan 25, 2005 3:18 pm
Location: Barcelona/Chile
Contact:

Post by Víctor Paredes »

Ponysmasher, I'm using your point time machine script for lipsync and it works awesome. thank you very much!
I'm getting a much better lipsync than using papagayo and in less than the half of time, all thanks to your incredible new tool.

I'm not working with switch layers or phonemes, I'm animating a vector mouth made by four points (plus a lower lip line made by tree points). First, I made a keyframe of the mouth closed. Then the character started saying an "A" so I opened the mouth and modified the curvature a little. Then the character said a "M" so, using your script, I get the closed mouth keyframe I did recently. I continued animating an O, and then a closed mouth again. Once I get A, M and O, I continued animating the lipsync using your tool and just adjusting some mouths in certain cases.
When I adjusted a mouth intermediately get a new mouth for the future. Your tool make the process so easy, it's great. thank you again :D
Image Image Image Image Image Image
Moho co-owner

Previously Rigged animation supervisor: My father's dragon, Wolfwalkers & Star Wars Visions "Screecher's Reach"
My personal Youtube Channel
User avatar
dreeko13
Posts: 187
Joined: Fri Oct 13, 2006 12:29 am
Contact:

Post by dreeko13 »

great tool!

love to see the bone version!
ponysmasher
Posts: 370
Joined: Wed Aug 04, 2004 6:23 pm
Location: Los Angeles
Contact:

Post by ponysmasher »

dreeko13 wrote:great tool!

love to see the bone version!
Here you go: http://dauid.com/tools/scripts/ds_bone_time.zip
selgin wrote:Ponysmasher, I'm using your point time machine script for lipsync and it works awesome.
Glad that you found it useful! I still haven't found a solution to the original question in the thread though. Very annoying.
I found a way to get relative positions but I can't get it to update in realtime. When using the tool it looks like nothing is happening, but if you scrub the timeline afterwards it updates. So close...
ponysmasher
Posts: 370
Joined: Wed Aug 04, 2004 6:23 pm
Location: Los Angeles
Contact:

Post by ponysmasher »

Well, what do you know. I managed to fix it with a sort of cheat.

Since it would only update when scrubbing the timeline I added some code that would jump ahead one frame and then back (but within a loop so it's not anything you'd notice), and it works.

The "set it" button doesn't work properly now though. Will have a look and upload the new script as soon as I find a solution.

EDIT: Now everything seems to work (Yaay).
I've updated the earlier link: http://dauid.com/tools/scripts/ds_point_time.zip
Last edited by ponysmasher on Tue Jul 06, 2010 6:57 pm, edited 1 time in total.
Post Reply