
i have a script request! (Poses)
Moderators: Víctor Paredes, Belgarath, slowtiger
- synthsin75
- Posts: 10271
- Joined: Mon Jan 14, 2008 11:20 pm
- Location: Oklahoma
- Contact:
Selgin, here is a fixed version of the script - I had the collectgarbage() routine in an area that killed the script.
Genete - Thanks for the reply and questions. The reason for calcualting the variables *before* the for loop is that in an interpreted language, including VB/VB6, javascript, etc each iteration of the loop *MUST* re-calculate the variable - which can totally kill performance. My recommendations have always been to delclare a variable before the loop and use that as then the calculation only happens once regardless of whether or not there are 1000 iterations. (That would be 999 less calculations to occur).
While a standard calculation isn't such a big deal, the code in question calls a function to "get" the count beffore it subtracts one from it... this can be costly. Since I don't know the code behind of the .count method, I assume the worst (it gets calc'd every time).
So, as a best practices, it is safest to simply declare a variable (minor memory use and gauranteed to be done only once).
As for the garbage collection - open up your task manager (if using windows) and comment out the LAST garbagecollect() function and run AS using any of the above files. Watch the memory grow exponentially until finally the system hangs. Then uncomment the collectgarbage() function and watch as the memory doesn't grow at all.
Indicative of the "auto" garbage collector either not working correctly or the code being done inefficiently for the language.
I played a little bit with redoing the function/splitting it up so that memory was better used for the last for loop - there can be easily 4000 points created every time you move the "Bone" and they never get cleared, so they just add up.
Great script - as I said earlier, I can pinpoint issues with scripts easier than I can create them myself for some reason...
Code: Select all
--Embed this script into all the vector layers that want to copy poses from frames 1,2,3,4, ..., maxposes
--it must be under a bone type layer and the following ROOT named bones MUST exists:
-- posek (with k form 1 to maxposes)
-- bonelesector
-- Copyright 2008 Genete
-- Released for free.
-- Thanks to Selgin for that great idea.
-- It can be extended for other animated values (curvatures, widths, shape fill colors, shape outline color, etc.)
-- Also weights w[k] can be overweigthed by the pose bone legth. It would allow some sort of variable action weights...
-- Under development...
-- Modififed June 5th, 2008:
-- Tim Fischer: Added local variables to speed up looping (interpreted languages recalculate every iteration so a variable can be much faster)
-- Added garbage collection routine to free memory (Auto GC doesn't appear to work). This fixes hanging, etc
poses = {}
maxposes = 2
bone = {}
boneselector = nil
function LayerScript(moho)
local w = {}
local distance
local posk
local pos_selector
local r
local length
local k
local layer = moho.layer
local frame = moho.frame
local skel = moho:ParentSkeleton()
if (skel == nil) then
print ("No parent skeleton found in layer:".. layer:Name())
return
end
local mesh = moho:Mesh()
if (mesh==nil) then
print ("No mesh found in layer:".. layer:Name())
return
end
if (frame <=maxposes) then
-----------------------------------look for the bones
for k=1, maxposes do
bone[k] = nil
local fc1 = skel:CountBones()-1 -- added to speed up loops
for i=0, fc1 do
local bonei = skel:Bone(i)
local bonek = "pose" .. tostring(k)
if (bonei:Name() == bonek) then
bone[k]=bonei
elseif (bonei:Name() == "boneselector") then
boneselector=bonei
end
end
if (bone[k] == nil) then
print("bone "..k.." is missing")
return
end
end
if boneselector == nil then
print("boneselector is missing")
return
end
collectgarbage(maxposes)
---------------------------------
--------------------------------- creates a new array for the layer
poses[layer]={}
poses[layer]["points"]={}
for k=1, maxposes do
poses[layer]["points"][k]={}
local fc2 = mesh:CountPoints()-1 -- added to speed up loops
for i=0, fc2 do
poses[layer]["points"][k][i]=mesh:Point(i).fAnimPos:GetValue(k) --store all the points/pose/positions
end
collectgarbage(fc2)
end
return
end
pos_selector = boneselector.fPos --position of the selector bone.
length = boneselector.fLength*boneselector.fAnimScale:GetValue(moho.frame) --current length of the boneselector
for k=1, maxposes do
w[k]=0
posk = bone[k].fPos
distance = posk - pos_selector
r = distance:Mag()
w[k]=weight(r, length)
end
local wtot=0.0 --total weight
for k=1, maxposes do
wtot =wtot +w[k]
end
if (wtot == 0.0) then return end
local fc3=mesh:CountPoints()-1 -- added to speed up loops
for i=0, fc3 do --- move the points.
local pimoved =LM.Vector2:new_local()
pimoved:Set(0,0)
for k=1, maxposes do
pimoved = pimoved + poses[layer]["points"][k][i]*w[k]/wtot
end
local pi=mesh:Point(i).fPos:Set(pimoved)
end
collectgarbage (fc3)
end
function weight (r, l)
if (r <= l) then
local w =r/l-1
--print(w)
return w
else
return 0.0
end
end
While a standard calculation isn't such a big deal, the code in question calls a function to "get" the count beffore it subtracts one from it... this can be costly. Since I don't know the code behind of the .count method, I assume the worst (it gets calc'd every time).
So, as a best practices, it is safest to simply declare a variable (minor memory use and gauranteed to be done only once).
As for the garbage collection - open up your task manager (if using windows) and comment out the LAST garbagecollect() function and run AS using any of the above files. Watch the memory grow exponentially until finally the system hangs. Then uncomment the collectgarbage() function and watch as the memory doesn't grow at all.
Indicative of the "auto" garbage collector either not working correctly or the code being done inefficiently for the language.
I played a little bit with redoing the function/splitting it up so that memory was better used for the last for loop - there can be easily 4000 points created every time you move the "Bone" and they never get cleared, so they just add up.
Great script - as I said earlier, I can pinpoint issues with scripts easier than I can create them myself for some reason...
-Tim
Genete and all,
One more *very interesting tidbit*. I looked at that PDF as well for scripting the garbage collector, but guess what?
That is not the version of Lua that AS is using... the garbage collector was re-written in a later version (5.1.3??) and isn't called that way any longer.
So maybe with the latest 5.6 update AS scripting is using the latest Lua?
I don't know, but the commands from the PDF would *not* work in AS...
go figure.
One more *very interesting tidbit*. I looked at that PDF as well for scripting the garbage collector, but guess what?
That is not the version of Lua that AS is using... the garbage collector was re-written in a later version (5.1.3??) and isn't called that way any longer.
So maybe with the latest 5.6 update AS scripting is using the latest Lua?
I don't know, but the commands from the PDF would *not* work in AS...
go figure.

-Tim
The reason for calcualting the variables *before* the for loop is that in an interpreted language, including VB/VB6, javascript, etc each iteration of the loop *MUST* re-calculate the variable - which can totally kill performance
Aaaargh! silly interpreted language!!!! I though it was intelligent and only calculate the end of the 'for' loop one time!!!! I learned lua a year ago (if write those scripts can be called "learn") and didn't know that!!!
Regarding to garbage collection I'm running a linux box and don't feel any memory performance improvement. It gets a lot of memory with or without your addition.
Anyway it is a good new to have you here. You can help us (self learned coders) to improve our impulsive scripts

-G
-
- Posts: 279
- Joined: Thu Mar 30, 2006 6:12 pm
- Location: Verona, New Jersey
Hi guys,
This is a great script and a great idea and all, but there's a couple of areas where I feel a little hmm.... limited by it. I'm not a scripter or anything but I wonder if there's any way to make it so that, if need be, point animation can operate within the script. I mean, I often have points during an animation where I realize that I simply need to move a point manually because what I'm getting from the bones is warping the design in such a way that the image and the animation doesn't look right. This script doesn't allow point movement while the script is in play.
Also, I wonder about the affect of bones from parent layers on the points of the vector layers that are under control of this script. You either might get a odd warping or no warping at all, which could also be odd. -I've never tried it, but it seems like plausible issues.
Is there any way to address this in the script?
Thanks,
S
This is a great script and a great idea and all, but there's a couple of areas where I feel a little hmm.... limited by it. I'm not a scripter or anything but I wonder if there's any way to make it so that, if need be, point animation can operate within the script. I mean, I often have points during an animation where I realize that I simply need to move a point manually because what I'm getting from the bones is warping the design in such a way that the image and the animation doesn't look right. This script doesn't allow point movement while the script is in play.
Also, I wonder about the affect of bones from parent layers on the points of the vector layers that are under control of this script. You either might get a odd warping or no warping at all, which could also be odd. -I've never tried it, but it seems like plausible issues.
Is there any way to address this in the script?
Thanks,
S
- synthsin75
- Posts: 10271
- Joined: Mon Jan 14, 2008 11:20 pm
- Location: Oklahoma
- Contact:
Uh, since this script is based on your actions, just add the needed point motion to the action/s. Or am I missing your point?
I think what you're asking for (allowing point motion on top of an action) would require the script to write regular references of the actions to the timeline.
As is, this script doesn't do that (and I'd image that'd take some doing). It seems to work much like meshinstance. All of the information in the actual layer is discarded and replaced by the info from your action.
But only Genete could tell you for sure.
I think what you're asking for (allowing point motion on top of an action) would require the script to write regular references of the actions to the timeline.
As is, this script doesn't do that (and I'd image that'd take some doing). It seems to work much like meshinstance. All of the information in the actual layer is discarded and replaced by the info from your action.
But only Genete could tell you for sure.

I played around with this for just a few minutes. I don't know how it would work exactly. I think you might have to copy frame 0 to an "extra" pose frame. Or grab the point positions from frame 0 and calculate the difference in motion to the other frames with out the pose blending.I wonder if there's any way to make it so that, if need be, point animation can operate within the script...
The "actual" position of the points on every frame would need to be incorporated equally into the equation for blending the poses. What ever the result of the point motion from poses is, would then be modified by whatever motion is set on the keys by key frames (whether there is a key frame on the frame or not).
The "actual" position of the points (without the poses) is "really" the last pose (the last key frame for the points determines the fPos of the point for later frames). That pose gets extra "influence" when trying to add in point motion to a key frame ON TOP of the blended pose motion.
You wold need a way to get the position of each point with NO pose motion blending added (frame 0) then get the difference of that motion from any hand done point motion on a frame, and add that to the calculation for the pose blending.
It might just be easier to adjust the poses if you need to tweak points. It might be done if I can spend more than 5 minutes goofing with it.
There is no influence from other bones. Only the pose motion controls the points. All other influence is ignored.Also, I wonder about the affect of bones from parent layers on the points of the vector layers that are under control of this script. You either might get a odd warping or no warping at all, which could also be odd. -I've never tried it, but it seems like plausible issues.
-vern
Dagnabbit...
Can't make it work. I think it could work... but if the script is sluggish now adding this feature might make it more so.
You would need to subtract the calculated pose motion to get the "unaltered" position of each point on the frame, as if there was no script changing the points position.
This would be the "base" that the script would then "alter" to add the pose motion to. then any point motion added "by hand" would just be "added" to the motion of the poses.
Currently when you try to acquire the fPos of the point on a frame, you get the "altered" value from the script. So this is wrong. If you add that to the points position you get wonky results. You need access to the UNALTERED value FIRST. Then it would work. It's that bit I had trouble with.
The result would be EXACTLY like using point motion on an interpolated switch layer. If you move points on keys on a switch layer that interpolates between layers, you get the motion of that key frame "added" to any interpolation.
Maybe there is an easy way to do this.
I think this is a FANTASTIC suggestion.
-vern
Can't make it work. I think it could work... but if the script is sluggish now adding this feature might make it more so.
You would need to subtract the calculated pose motion to get the "unaltered" position of each point on the frame, as if there was no script changing the points position.
This would be the "base" that the script would then "alter" to add the pose motion to. then any point motion added "by hand" would just be "added" to the motion of the poses.
Currently when you try to acquire the fPos of the point on a frame, you get the "altered" value from the script. So this is wrong. If you add that to the points position you get wonky results. You need access to the UNALTERED value FIRST. Then it would work. It's that bit I had trouble with.
The result would be EXACTLY like using point motion on an interpolated switch layer. If you move points on keys on a switch layer that interpolates between layers, you get the motion of that key frame "added" to any interpolation.
Maybe there is an easy way to do this.
I think this is a FANTASTIC suggestion.
-vern
- synthsin75
- Posts: 10271
- Joined: Mon Jan 14, 2008 11:20 pm
- Location: Oklahoma
- Contact:
If there were any way to make the script add the actions to the timeline as a normal reference, the point motion addition would already be there. I guess the problem is that this script utilizes the control bone's interpolation instead of the interpolation between action keyframes.
Vern, I think your proposed action assignment by hotkey script would probably be the best solution for this.
Vern, I think your proposed action assignment by hotkey script would probably be the best solution for this.

I almost got it working.
I see this script as a switch layer on steroids. There would be no way to get the kind of key frame "blending" using "linear" interpolation. It's the ability to create new completely different combinations that make this script so fantastic.
-----
What would be cool is being able to access actions without inserting them. Right now actions I think are a bit rough around the edges. They feel as if they are still a fairly new addition due to the lack of much script access.
The perfect solution would be if actions and the keys could be accessed as easily as the main time line keys. then instead of inserting keys in the first frames of the time line you would just use keys from the action.
-vern
I see this script as a switch layer on steroids. There would be no way to get the kind of key frame "blending" using "linear" interpolation. It's the ability to create new completely different combinations that make this script so fantastic.
-----
What would be cool is being able to access actions without inserting them. Right now actions I think are a bit rough around the edges. They feel as if they are still a fairly new addition due to the lack of much script access.
The perfect solution would be if actions and the keys could be accessed as easily as the main time line keys. then instead of inserting keys in the first frames of the time line you would just use keys from the action.
-vern
- synthsin75
- Posts: 10271
- Joined: Mon Jan 14, 2008 11:20 pm
- Location: Oklahoma
- Contact:
What if you made a parse then open file menu script? You'd have to have AS already open, but then you should be able to search the text file for action names and key data, shouldn't you?The perfect solution would be if actions and the keys could be accessed as easily as the main time line keys. then instead of inserting keys in the first frames of the time line you would just use keys from the action.
I hate parsing the file format. In AS the script interface does all the heavy lifting for you. Parsing the file format is like "reinventing the wheel". Making a script do what AS already does. You have to figure out where all the information is and translate it line by line from the file. Pain in the arse. I would rather not go down that road.
-vern
-vern
In fact this script is very simple.slice11217 wrote:Hi guys,
This is a great script and a great idea and all, but there's a couple of areas where I feel a little hmm.... limited by it. I'm not a scripter or anything but I wonder if there's any way to make it so that, if need be, point animation can operate within the script. I mean, I often have points during an animation where I realize that I simply need to move a point manually because what I'm getting from the bones is warping the design in such a way that the image and the animation doesn't look right. This script doesn't allow point movement while the script is in play.
Also, I wonder about the affect of bones from parent layers on the points of the vector layers that are under control of this script. You either might get a odd warping or no warping at all, which could also be odd. -I've never tried it, but it seems like plausible issues.
Is there any way to address this in the script?
Thanks,
S
First you store a fixed (but can be modified) number of poses in the first frames (they can be stored in the negative frames after fantastic heyvern discovery.
They are like the child vector layers of a switch layer but they are fixed. They have not option to have a animation by the time as far as it hasn't its own time line.
There are two benefits from the usage of switch layers:
1) Visual control of the interpolated pose
2) You can stop at any intermediate pose and / or can combine several poses at the same time.
There is not way to override interpolated point motion unless you could modify the poses along the time line.... Oh! it would be possible to get the poses form the current animated values of some special child vector layers! Even it can be done using a switch layer instead a bone layer to allow easy hide the poses! It would allow avoid the need of store poses in the first frames!
Give me some free time to redo the script and see what happen.

BTW, reviewing the script I've found that the line:
Code: Select all
local pi=mesh:Point(i).fPos:Set(pimoved)
Code: Select all
mesh:Point(i).fPos:Set(pimoved)
-
- Posts: 279
- Joined: Thu Mar 30, 2006 6:12 pm
- Location: Verona, New Jersey
Well see, this is partly what I'm addressing: if I'm animating and I run into a problem (which happens far more frequently than I'd like for it to), and I need a pose that I didn't anticipate then I'm screwed. The script as it stands right now requires that you anticipate everything you're going to need up front. I don't know about anyone else but this is very difficult to do.Genete wrote: First you store a fixed (but can be modified) number of poses in the first frames (they can be stored in the negative frames after fantastic heyvern discovery.
I tried the following but it didn't work: using DarthFurby's head turn file with the script applied to it, I went to one of the vector layers. I picked a random point on the timeline and set a keyframe on the point motion. Then I went to another random point on the timeline and set another, making sure that the two poses would be quite different. My hypothesis was that if I set the two keyframes on the point motion and then removed the script from the layer, that the animation would hold. Alas, it did not.
Child vector layer as also fixed, but less so. While a child vector is selected I can set point motion animation but while it is interpolating from one child to another, I cannot.Genete wrote: They are like the child vector layers of a switch layer but they are fixed. They have not option to have a animation by the time as far as it hasn't its own time line.
I've never been able to combine more than two switch child vector layers at any time. Moreover, the only visual control of an interpolated pose that's available is the timing of it, and I'd personally prefer to be able to manipulate the ease the in/out of that manually.Genete wrote: There are two benefits from the usage of switch layers:
1) Visual control of the interpolated pose
2) You can stop at any intermediate pose and / or can combine several poses at the same time.
Here's the thing:
The advantage of this script is that you can visually choose whatever pose you need at any given point on the timeline. You can even easily choose gradations of one pose to another and if you set it up right you can go from any pose to any other and choose a interpolation of one pose to the other. This you can't do with a switch layer. You can do this with single frame actions but these can be confusing to set up (I keep going in and out of action mode when setting them up), and also you lose the visual interaction that this script has to its advantage. Actions are plenty easy to use, but not as easy as using this script.
I've personally never been bothered by having to set the start frame at a later point in the timeline anyway since it makes for an easier transition into After Effects if the start frame is on a '00' frame ( 1:00, or 2:00, etc.) Anime Studio's default is to start on frame 0:01 which forces the animator to think in terms of subtracting a frame when transitioning to other software. I could personally care less if the stored frames happened after the 0 frame or before. I'd rather see the frame numbering be a user-defined aspect rather than permanent one. Our current frame 0 could then be a frame '00' or something, perhaps 'XX' or 'ZZ'.
The disadvantage of this script is that once you've set up those poses, that's it! -You can't go in and modify things as you go, you're hardwired in. You have to anticipate what you're going to need up front or suffer the consequences. I'd like to be able to use this script to block in acting, set up head turns, or (and this hasn't been discussed yet) twist the body (which would probably require two poseselector bones), and then go in and modify and finesse what I feel needs to be finessed. In this sense the script is kind of limited.
Also, for head turns it seems you'd need to create a rather vast library of mouth phenomes and eye positions, eyebrow expressions, etc. in every pose -Lots of work! I'm already spending far more time setting up and rigging characters than I am actually animating them. Clients unfortunately are starting to get a little confused into thinking that animating via AS takes longer than drawing it by hand as a result. I end up having to reassure them that the animation is faster, it's the setup that takes a while, and once that's done it doesn't need to be done again.
Anyway, hopefully this makes it a little clearer as to what I'm thinking about. I like the script, I just want more!
-S
Why? I'm not sure I understand when you say you are "locked in" and can't make changes? The poses are based on named bones, need more poses just increase the "maxpose" variable and add in new poses and bones. If you need to tweak the poses later then, tweak the points on the frame of the pose with onion skin turned on. The only thing that might be a problem is how far ahead do you start the animation so there is rooom to add more poses?The disadvantage of this script is that once you've set up those poses, that's it! -You can't go in and modify things as you go, you're hardwired in. You have to anticipate what you're going to need up front or suffer the consequences.
This is the case even if the script had everything you wanted and was perfect. This script doesn't "cause" the extra work. It makes the extra work more usable.Also, for head turns it seems you'd need to create a rather vast library of mouth phenomes and eye positions, eyebrow expressions, etc. in every pose -Lots of work!
if you create multiple views of a character, that is going to require multiple sets of phonemes. That is the same amount of work. this script is NOT going to change the fact that each "pose" requires a set of phonemes. It never could, it never will. How could it? The phoneme issue is not relevant to this script. You can avoid that by not having phonemes in each pose for a head turn. Don't allow the character to talk WHILE turning. Just use phoneme layers for when the character reaches the final position. that is what I did with switch layer head turns.
I think the phoneme issue could be handled in other ways if needed. Groupings of pose bones for easier selection... just brain storming. Keep in mind this is a brand new idea. No one has really figured out how to set up those bones for something like lip sync.
Try to use what's there now before jumping on the things that aren't perfect. This is an amazing script with lots of potential just as it is right now. If it doesn't work for you right now for everything, scale back what it's used for. Don't use it for body twisting, just use it for simple things.
-vern