Possible to copy vector point motion from bone influence?
Moderators: Víctor Paredes, Belgarath, slowtiger
Possible to copy vector point motion from bone influence?
What I mean is, would it be possible to calculate on a bone key frame the position of the points moved by the bones so that this motion could be "copied" as point motion to the vector layer instead of bone movement?
This would be great for doing lip sync switches using bones to manipulate the mouth.
-vern
This would be great for doing lip sync switches using bones to manipulate the mouth.
-vern
I guess you want the points positions to be stored as keys in the Point Motion animation channel. That is tricky, because the updated shape would be distorted immediately by bone influence.
IMO You would need to use a duplicate vector layer with all the points released. The points in the mesh of that duplicate layer would be positioned the same as in the original vector layer. I think that would be feasible.
I think the best solution is a menu script that acts on the currently selected bone layer (and its child layers). It would need to create a duplicate bone layer without the bones, but with the bone animation transformed into point animation.
IMO You would need to use a duplicate vector layer with all the points released. The points in the mesh of that duplicate layer would be positioned the same as in the original vector layer. I think that would be feasible.
I think the best solution is a menu script that acts on the currently selected bone layer (and its child layers). It would need to create a duplicate bone layer without the bones, but with the bone animation transformed into point animation.
Last edited by Rasheed on Tue Dec 05, 2006 1:34 pm, edited 1 time in total.
Yes, I don't need the bone motion to be kept anyway.
Actually, if the points were "immediately distorted" by the bones that would be fine. I would just drag that layer out of the bone folder anyway. I would make a duplicate of the vector layer first so I have a "backup" so to speak.
I would be using the bone layer as a switch layer creation tool.
I just wasn't sure if actual point motion is even "recorded" in AS when those points are moved by a bone.
-vern
Actually, if the points were "immediately distorted" by the bones that would be fine. I would just drag that layer out of the bone folder anyway. I would make a duplicate of the vector layer first so I have a "backup" so to speak.
I would be using the bone layer as a switch layer creation tool.
I just wasn't sure if actual point motion is even "recorded" in AS when those points are moved by a bone.
-vern
Well, the point motion is recorded into keys only relative to the layer. So I needed two layer scripts to pull this off.
You create an original vector layer, which you put into the bone layer, and you create an exact copy of the vector layer, which you can put anywhere you want in the document.
Put this script into the original layer:
And this script into the copy layer:
And presto!
It copies the points of one vector layer into another and records all point motion through the global variable Pos. This variable is a table containing all the vectors of all the frames (well, except frame zero) of all the points in the original layer.
The keys are recorded in the copy layer by selecting every point and use the member function UpdateSelectedChannels() of the moho object. After that, the points are deselected.
To run the scripts do the following:
So, I think it is best if you have several layers to transform, do one at a time, so you end up with copies of your original layers. However, for some reason it crashed Moho each time I changed layers. So restart Moho for each layer you want to transform and save liberally.
BTW Here is your movie redone with my scripts:

click on image to watch video on YouTube
Here is the Moho file (without the sound): lips_copy.moho.zip
You create an original vector layer, which you put into the bone layer, and you create an exact copy of the vector layer, which you can put anywhere you want in the document.
Put this script into the original layer:
Code: Select all
-- org layer script.lua
function LayerScript(moho)
local mesh = moho:Mesh()
if ( mesh == nil or mesh:CountPoints() == 0 or moho.frame == 0 ) then
return
end
local frame = moho.frame
if ( Pos == nil ) then
Pos = {}
end
if (Pos[frame] == nil ) then
Pos[frame] = {}
for i=0, mesh:CountPoints() - 1 do
local pt = mesh:Point(i)
Pos[frame][i] = pt.fPos
end
end
end
Code: Select all
-- copy layer script.lua
function LayerScript(moho)
local mesh = moho:Mesh()
if ( mesh == nil or mesh:CountPoints() == 0 or moho.frame == 0 ) then
return
end
local frame = moho.frame
if ( Pos ~= nil and Pos[frame] ~= nil ) then
for i=0, mesh:CountPoints() - 1 do
local pt = mesh:Point(i)
pt:SetPos( Pos[frame][i], frame )
pt.fSelected = true
pt.fAnimPos:AddKey(moho.frame)
end
moho:UpdateSelectedChannels()
mesh:SelectNone()
end
end
It copies the points of one vector layer into another and records all point motion through the global variable Pos. This variable is a table containing all the vectors of all the frames (well, except frame zero) of all the points in the original layer.
The keys are recorded in the copy layer by selecting every point and use the member function UpdateSelectedChannels() of the moho object. After that, the points are deselected.
To run the scripts do the following:
- make a copy of the original layer
- turn off all onion skinning
- go to frame zero
- embed the org layer script in the original layer
- embed the copy layer script in the copied layer
- run the animation
- go to frame zero
- remove the layer scripts from the original and copied layers.
So, I think it is best if you have several layers to transform, do one at a time, so you end up with copies of your original layers. However, for some reason it crashed Moho each time I changed layers. So restart Moho for each layer you want to transform and save liberally.
BTW Here is your movie redone with my scripts:

click on image to watch video on YouTube
Here is the Moho file (without the sound): lips_copy.moho.zip
HOLY COW!!!!
I LOVE YOU MAN! I want to send you candy and flowers and... wash your car... and... and...
<gasp> <thunk>
I passed out there for a minute. I can't believe you did this so fast. I have been wanting this for ages and never thought to post it.
THIS IS EXACTLY WHAT I NEEDED!
The process is very fast. And it makes keys on every frame which is actually kind of freaking cool! I have all those keys to pick from if I need to.
This is kick arse! I am jumping up and down! I can use this to do SO MUCH with switch layers for lip sync... whatever.
THANK YOU RASHEED!
-vern
I LOVE YOU MAN! I want to send you candy and flowers and... wash your car... and... and...
<gasp> <thunk>
I passed out there for a minute. I can't believe you did this so fast. I have been wanting this for ages and never thought to post it.
THIS IS EXACTLY WHAT I NEEDED!
The process is very fast. And it makes keys on every frame which is actually kind of freaking cool! I have all those keys to pick from if I need to.
This is kick arse! I am jumping up and down! I can use this to do SO MUCH with switch layers for lip sync... whatever.
THANK YOU RASHEED!
-vern
I was just thinking that there are a LOT of people who do point animation in AS who don't like to use the bones.
This could be a good way for them to get bone motion into the point animation. It really opens up the options.
You could do rough motion with bones, tweak with points, then combine them both into point motion, and continue tweaking either with bones or points etc.
What would be the possiblilty of creating a menu script for this? Instead of using a layer script, use a menu script like the copy bones script?
You would go to a key frame of a bone layer, select the mesh at that point and "Copy Points", go to the copied layer and "Paste Points".
This would eliminate LUA having to "know" which layer had what points etc. You would be ON the layer, no need for running through a list.
-vern
This could be a good way for them to get bone motion into the point animation. It really opens up the options.
You could do rough motion with bones, tweak with points, then combine them both into point motion, and continue tweaking either with bones or points etc.
What would be the possiblilty of creating a menu script for this? Instead of using a layer script, use a menu script like the copy bones script?
You would go to a key frame of a bone layer, select the mesh at that point and "Copy Points", go to the copied layer and "Paste Points".
This would eliminate LUA having to "know" which layer had what points etc. You would be ON the layer, no need for running through a list.
-vern
Can it be somewhat different?
I will start on this tomorrow and it will take probably considerably more time, because I have never written a menu script before. It will be good experience for the scripting tutorial I'm writing right now (see here). This tutorial isn't extensive enough to publish, but you can have a look at it).
- if there is not yet a copy of the currently selected vector layer, then :
- make a copy of the current vector layer above the selected vector layer
- name it after the selected layer, with " (copy)" attached to the layer name
- else :
- clear all keys in the point motion animation channel in the copied layer
- find the frames in the parent layer which have keys in the bone animation channels
- in the found frames, put keys in the point motion animation channel of the copied layer, based on the points positions in the selected layer
I will start on this tomorrow and it will take probably considerably more time, because I have never written a menu script before. It will be good experience for the scripting tutorial I'm writing right now (see here). This tutorial isn't extensive enough to publish, but you can have a look at it).
Forget about this, I tried another version of the "org script layer.lua" (see below). It now only puts keys in those frames of the copied layer if there is a key in the parent bone layer of the original vector layer.Rasheed wrote:Can it be somewhat different?
- if there is not yet a copy of the currently selected vector layer, then :
- make a copy of the current vector layer above the selected vector layer
- name it after the selected layer, with " (copy)" attached to the layer name
- else :
- clear all keys in the point motion animation channel in the copied layer
- find the frames in the parent layer which have keys in the bone animation channels
- in the found frames, put keys in the point motion animation channel of the copied layer, based on the points positions in the selected layer
See here what the result is:

The purple rectangle is the one controlled by the bone in Layer 2. The brown rectangle is "Layer 1 copy".
This means if you want to transform bone animation into points animation, you will need to fill every frame with a key. If you do not, the inbetweens of the copied layer will be different from those in the layer that is controlled by bones.
____
Here is the test code I used to investigate this. It uses a separate function FindHasKeys to keep the main function readable.
DO NOT USE THE SCRIPT BELOW, BECAUSE ITS METHOD IS FLAWED!!!
Code: Select all
-- org layer script2.lua
--
-- in combination with the copy layer script, this script will only put keys
-- in the frames of the copied layer if this layer's parent layer has bones in
-- these frames
--
-- Note that this method is flawed, because bone animation is something else
-- than points animation. Each key in the copied layer has to be present,
-- otherwise the points animation will deviate from the bone animation.
--
-- So, DO NOT USE THIS SCRIPT!!!
function LayerScript(moho)
local frame = moho.frame
local mesh = moho:Mesh()
local layer = moho.layer
local parent = layer:Parent()
if ( mesh == nil or mesh:CountPoints() == 0 or parent == nil
or moho.frame == 0 ) then
return
end
hasKey = FindHasKey(moho, parent)
if ( hasKey == nil ) then
return
end
if ( not hasKey[frame] ) then
return
end
if ( Pos == nil ) then
Pos = {}
end
if (Pos[frame] == nil ) then
Pos[frame] = {}
for i=0, mesh:CountPoints() - 1 do
local pt = mesh:Point(i)
Pos[frame][i] = pt.fPos
end
end
end
function FindHasKey(moho, parent)
local prevLayer = moho.layer
moho:SetSelLayer(parent)
local boneCount = moho:CountBones()
if ( boneCount == 0 ) then
moho:SetSelLayer(prevLayer)
return nil
end
local skel = moho:Skeleton()
local endFrame = moho.document:EndFrame()
local hasKey = {}
for b = 0, boneCount - 1 do
local bone = skel:Bone(b)
local bAnimPos = bone.fAnimPos
local cAnimPos = bAnimPos:CountKeys()
local bAnimAngle = bone.fAnimAngle
local cAnimAngle = bAnimAngle:CountKeys()
local bAnimScale = bone.fAnimScale
local cAnimScale = bAnimScale:CountKeys()
local bIKLock = bone.fIKLock
local cIKLock = bIKLock:CountKeys()
local frame = 1
while ( ( cAnimPos > 0 or cAnimAngle > 0 or cAnimScale > 0
or cIKLock > 0 ) and frame <= endFrame ) do
if ( bAnimPos:HasKey(frame) ) then
hasKey[frame] = true
cAnimPos = cAnimPos - 1
end
if ( bAnimAngle:HasKey(frame) ) then
hasKey[frame] = true
cAnimAngle = cAnimAngle - 1
end
if ( bAnimScale:HasKey(frame) ) then
hasKey[frame] = true
cAnimScale = cAnimScale - 1
end
if ( bIKLock:HasKey(frame) ) then
hasKey[frame] = true
cIKLock = cIKLock - 1
end
frame = frame + 1
end
end
moho:SetSelLayer(prevLayer)
return hasKey
end
What!?!? Is this an answer to this old suggestion???
http://www.lostmarble.com/forum/viewtopic.php?t=3991
If so OOOO AAAHH. I have homework to do when I get home but going to play with that this weekend if so.
http://www.lostmarble.com/forum/viewtopic.php?t=3991
If so OOOO AAAHH. I have homework to do when I get home but going to play with that this weekend if so.
[url=http://burtabreu.animationblogspot.com:2gityfdw]My AnimationBlogSpot[/url:2gityfdw]
All this happened TODAY?!
You guys are amazing!
You guys are amazing!
----
Terrence Walker
Studio ArtFX
LEARN HOW TO Make YOur Own Animated Film!
Get Video Training to Show You How!
Terrence Walker
Studio ArtFX
LEARN HOW TO Make YOur Own Animated Film!
Get Video Training to Show You How!
While layer translation cannot be captured with this method, everything that has to do with point motion inside a layer can be copied reliably, as long as you do one vector layer at a time, and restart AS (or Moho) for the next layer.
This is a bug and I will not fix this, because I want to write a menu script, that will automatically create a copy of a layer with the points motion in it.
BTW, here is a SWF file I exported from a Moho file I treated this way.
Test2.swf
(source: Test2.moho.zip)
This is a bug and I will not fix this, because I want to write a menu script, that will automatically create a copy of a layer with the points motion in it.
BTW, here is a SWF file I exported from a Moho file I treated this way.
Test2.swf
(source: Test2.moho.zip)