Page 1 of 2

Get position of a point after being affected by a bone

Posted: Sun Jun 27, 2010 6:51 am
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.

Posted: Sun Jun 27, 2010 9:57 am
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!

Posted: Sun Jun 27, 2010 11:46 am
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.

Posted: Sun Jun 27, 2010 6:12 pm
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.

Posted: Sun Jun 27, 2010 11:18 pm
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

Posted: Sun Jun 27, 2010 11:33 pm
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.

Posted: Mon Jun 28, 2010 1:48 am
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...

Posted: Mon Jun 28, 2010 2:40 am
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)

Posted: Mon Jun 28, 2010 3:19 am
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

Posted: Mon Jun 28, 2010 10:12 am
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

Posted: Wed Jun 30, 2010 4:09 pm
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!

Posted: Tue Jul 06, 2010 4:39 pm
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

Posted: Tue Jul 06, 2010 5:45 pm
by dreeko13
great tool!

love to see the bone version!

Posted: Tue Jul 06, 2010 5:57 pm
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...

Posted: Tue Jul 06, 2010 6:22 pm
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