i have a script request! (Poses)
Moderators: Víctor Paredes, Belgarath, slowtiger
-
- Posts: 45
- Joined: Mon Jun 11, 2007 9:02 am
Every time the script runs in each frame it starts from scratch, right? So all the stored variables are lost. How do I go about storing values between runs of the script? I see there's the ScriptPrefs class, which could do it, but it wouldn't be efficient to convert the point positions into integers to be stored by ScriptPrefs and then converted back again every run of the script.
Is there another way?
Is there another way?
I think I see the problem. I separated out the spot that might be the issue. This is a snippet from the code where the points get moved:
"fPos" is the absolute position of the point on the frame. If you set the point to be the "fPos" and change the "fPos" you are incrementing it exponentially each time around.
The "normal" script is only working on "Static" values of the poses. The current frame position values are never considered. They aren't part of the calculation. Once you add in that constantly changing value of the current point position on each frame you run into the issue of what is the "actual" value. How can you determine what the point position is really suppose to be? You would have to have a key on every frame before adding the script to the layer. Then the "fPos" value would "over ride" the key frame value but that value would be stored.
I hate to say it but I think this is impossible to accomplish. I just don't see any way to separate the position value of the key frame from the position value that the script is adding in.
I would be very happy to be proven wrong.
-vern
Code: Select all
---------------------------------------------POINT MOTION
local fc3=mesh:CountPoints()-1 -- added to speed up loops
for i=0, fc3 do --- move the points.
---------------------------------------------
pimoved:Set(mesh:Point(i).fPos)
---------------------------------------------
....
The "normal" script is only working on "Static" values of the poses. The current frame position values are never considered. They aren't part of the calculation. Once you add in that constantly changing value of the current point position on each frame you run into the issue of what is the "actual" value. How can you determine what the point position is really suppose to be? You would have to have a key on every frame before adding the script to the layer. Then the "fPos" value would "over ride" the key frame value but that value would be stored.
I hate to say it but I think this is impossible to accomplish. I just don't see any way to separate the position value of the key frame from the position value that the script is adding in.
I would be very happy to be proven wrong.
-vern
HAHAHAHA!!!! I FIXED IT I FIXED IT!
I've decided to leave my last post up for the humorous aspect. Of course it's impossible until 30 seconds later I find the solution.
I will post the code shortly I need to test it a bit more. Very simple. Two lines one word.... ha hah hahaha! I'm in code mode again!
-vern
I've decided to leave my last post up for the humorous aspect. Of course it's impossible until 30 seconds later I find the solution.
I will post the code shortly I need to test it a bit more. Very simple. Two lines one word.... ha hah hahaha! I'm in code mode again!

-vern
Here's the scoop...
fPos is the ABSOLUTE value. This value includes ALL motion applied to the point location.
fAnimePos is just the "animated" position defined by AS. It doesn't include "scripted" motion. Cool beans. Easy fix.
-vern
fPos is the ABSOLUTE value. This value includes ALL motion applied to the point location.
fAnimePos is just the "animated" position defined by AS. It doesn't include "scripted" motion. Cool beans. Easy fix.
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.)
-- (curvature done!)
-- 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
--Genete 2008 july, 27th
---I've added some testing to speed up the positioning on the poses. You can edit the poses freely staying at its own frame but
---if you modify a pose then you have to go to frame 0 to store the modifications on the pose array. Frame 0 is slow!!!
---Now the pose bone legth has influence on the final weight of the poses. So you can control the interpolated pose with the poses lengths.
---Added the Curvature channel. Now the curvature is stored and is interpolated between poses. It produces automatically a keyframe on each frame
---There is NO WAY to solve this because the curvature channel has not a fCurvature variable to set like the one for the points.
---Added the functionality of an external variable: GE_ToggleKeyframePoses.Status
---You have to run the ge_toggle_keyframe_poses.lua script by the menu or button script to modify the variable Status form false (default value)
---to True and viceversa. When this variable is set to true the inrterpolated point motion is stored in a keyframe. This is useful to
---store all the animation in its own keyframes and be able to remove the embedde scripts. Also useful when used on single frames to key all the
---point motions for all layers where the script is embedded.
---Added the ability to avoid interpolate or set again an existing keyframe. This allows the user to insert a keyframe in any moment of the
---interpolation and manually modify the interpolated values. This solves the situation where the interpolated poses produces a bad value
---difficult to solve by modifying the poses thenselves.
---Added interpolation for style shape fill and line color. I've tried Line Widht but it seems not to work.
--PocketGoat 2009, 15th May.
--Added ability to use other types of animation in conjunction with poses.
--Heyvern 2009, 14th May? (Hey PocketGoat... how are you a day ahead of me?
--Small teeny tiny miniscule edit to fix PocketGoat's revision. Lines 177-179
poses = {}
maxposes = 4
bone = {}
boneselector = nil
function LayerScript(moho)
local w = {}
local distance
local posk
local pos_selector
local r
local length
local k,i,l
local layer = moho.layer
local frame = moho.frame
local pimoved =LM.Vector2:new_local()
local pi
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 and frame > 0) then return end
if (frame <= maxposes or boneselector == nil) then
-----------------------------------look for the bones
for k=2, 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
---------------------------------
--------------------------------- creates a new array for the layer
poses[layer]={}
poses[layer]["points"]={} -- this is the array for the point motion
for k=1, maxposes do
poses[layer]["points"][k]={}
local fc2 = mesh:CountPoints()-1 -- added to speed up loops
if k == 1 then
for i=0, fc2 do
poses[layer]["points"][k][i]=mesh:Point(i).fAnimPos:GetValue(k) --store all the points/pose/positions for neutral layer 1
end
else
for i=0, fc2 do
poses[layer]["points"][k][i]=mesh:Point(i).fAnimPos:GetValue(k) - poses[layer]["points"][1][i] --store point differences for other layers
end
end
collectgarbage(fc2)
end
poses[layer]["curvature"]={} -- this is the array for the curvatures
for k=2, maxposes do
poses[layer]["curvature"][k]={}
local fc3 = mesh:CountCurves()-1
for i=0, fc3 do
poses[layer]["curvature"][k][i]={}
local curvei = mesh:Curve(i)
local fc4 = curvei:CountPoints()-1
for l=0, fc4 do
poses[layer]["curvature"][k][i][l]=curvei:GetCurvature(l,k)--store all the point of curves/pose /curvature
end
collectgarbage(fc4)
end
collectgarbage(fc3)
end
poses[layer]["fillcolor"]={}
poses[layer]["linecolor"]={}
poses[layer]["linewidth"]={}
for k=2, maxposes do
poses[layer]["fillcolor"][k]={}
poses[layer]["linecolor"][k]={}
poses[layer]["linewidth"][k]={}
local fc5=mesh:CountShapes()-1
for i=0, fc5 do
local shapei=mesh:Shape(i)
poses[layer]["fillcolor"][k][i]=shapei.fMyStyle.fFillCol:GetValue(k)
poses[layer]["linecolor"][k][i]=shapei.fMyStyle.fLineCol:GetValue(k)
poses[layer]["linewidth"][k][i]=shapei.fMyStyle.fLineWidth
end
end
return
end -- end of frame < maxposes or boneselector == nil
pos_selector = boneselector.fPos --position of the selector bone.
-- length = boneselector.fLength*boneselector.fAnimScale:GetValue(moho.frame) --current length of the boneselector
length = boneselector.fLength*boneselector.fScale --current length of the boneselector
-- Calculate the distance form the boneselector to all the pose bones and calculate its "weight" influence
for k=2, maxposes do
w[k]=0
posk = bone[k].fPos
distance = posk - pos_selector
r = distance:Mag()
w[k]=weight(r, length)*bone[k].fScale --***THE SCALE OF THE POSE BONE CREATE INFLUENCE ON THE POSE!***
end
local wtot=0.0 --total weight initially = 0.0
for k=2, maxposes do
wtot =wtot +w[k]
end
if (wtot == 0.0) then return end
for k=2, maxposes do
w[k]=w[k]/wtot -- normalize the weights.
end
---------------------------------------------POINT MOTION
local fc3=mesh:CountPoints()-1 -- added to speed up loops
for i=0, fc3 do --- move the points.
-- pimoved:Set(mesh:Point(i).fPos) -- heyvern edit- I removed this. Wrong thing (fPos) and in the wrong spot
pi= mesh:Point(i)
--- heyvern edit - I changed this to fAnimPos. This is ANIMATED position... not the "real" position defined by fPos
pimoved=pi.fAnimPos:GetValue(frame)
---if (pi.fAnimPos:HasKey(frame)) then break end -- if there is a keyframe then don't overrride it. Not needed anymore.
for k=2, maxposes do
pimoved = pimoved + (poses[layer]["points"][k][i]*w[k])/2
end
if(GE_ToggleKeyframePoses.Status==false) then
mesh:Point(i).fPos:Set(pimoved) --move the point
else
pi.fAnimPos.value=pimoved -- move the point
pi.fAnimPos:StoreValue()--this produces a keyframe and stores its valule
moho.document:SetDirty()
end
end
---------------------------------------------END POINT MOTION
---------------------------------------------CURVATURE
fc3 = mesh:CountCurves()-1
for i=0, fc3 do
local curvei = mesh:Curve(i)
local fc4 = curvei:CountPoints()-1
for l=0, fc4 do
local currentcurvature = 0.0
for k=2, maxposes do
currentcurvature=currentcurvature + poses[layer]["curvature"][k][i][l]*w[k]
curvei:SetCurvature(l,currentcurvature,frame)
end
end
end
---------------------------------------------END CURVATURE
---------------------------------------------STYLE
fc3 = mesh:CountShapes()-1
for i=0, fc3 do
local shapei = mesh:Shape(i)
local currentfillcol = LM.ColorVector:new_local()
local currentlinecol = LM.ColorVector:new_local()
local currentlinewidth = 0.0
currentfillcol:Set(0.0,0.0,0.0)
currentlinecol:Set(0.0,0.0,0.0)
for k=2, maxposes do
currentfillcol=currentfillcol+poses[layer]["fillcolor"][k][i]*w[k]
currentlinecol=currentlinecol+poses[layer]["linecolor"][k][i]*w[k]
currentlinewidth=currentlinewidth+poses[layer]["linewidth"][k][i]*w[k]
--if(shapei.fMyStyle.fDefineFillCol) then
shapei.fMyStyle.fFillCol:SetValue(frame,currentfillcol) --end
--if(shapei.fMyStyle.fDefineLinecol) then
shapei.fMyStyle.fLineCol:SetValue(frame,currentlinecol) --end
--if(shapei.fMyStyle.fDefineLineWidth) then
shapei.fMyStyle.fLineWidth=currentlinewidth --end
end
end
--------------------------------------------- END STYLE
collectgarbage (fc3)
end ---FUNCTION END
function weight (r, l)
if (r <= l) then
local w =1-r/l
return w
else
return 0.0
end
end
- Víctor Paredes
- Site Admin
- Posts: 5815
- Joined: Wed Jan 26, 2005 12:18 am
- Location: Barcelona/Chile
- Contact:
-
- Posts: 45
- Joined: Mon Jun 11, 2007 9:02 am
-
- Posts: 45
- Joined: Mon Jun 11, 2007 9:02 am
- Víctor Paredes
- Site Admin
- Posts: 5815
- Joined: Wed Jan 26, 2005 12:18 am
- Location: Barcelona/Chile
- Contact:
Hah! Another break through.
The reason it doesn't work correctly using "fAnimPos".... is... because... think about it... wait for it... you see the problem?
Hah! It's using the LAST POSE! When you add keys it's based on the last pose.... D'oh! I need to change the code to get the point positions from FRAME 0 not the current frame.
-vern
The reason it doesn't work correctly using "fAnimPos".... is... because... think about it... wait for it... you see the problem?
Hah! It's using the LAST POSE! When you add keys it's based on the last pose.... D'oh! I need to change the code to get the point positions from FRAME 0 not the current frame.
-vern
There's another problem... the keys for the poses.
This is why the points won't move correctly. No matter what you do those keys for the poses have an adverse effect. Keying points keys relative the last key frame which is always the last pose.
I'm going to try making the last pose an "extra" pose that is identical to frame 0.
-vern
This is why the points won't move correctly. No matter what you do those keys for the poses have an adverse effect. Keying points keys relative the last key frame which is always the last pose.
I'm going to try making the last pose an "extra" pose that is identical to frame 0.
-vern
-
- Posts: 45
- Joined: Mon Jun 11, 2007 9:02 am
Just so you know there was a change you made in Genete's latest version.
You changed the max pose variable loop in some spots from:
to:
All I did was to add the other minor changes you made in the "move points" section in the original script and it works "better". Keying points on the vector layer worked almost as expected. Those changes you made to the loop seemed to be for something else you planned to do? Anyway it messed things up.
It still isn't right though. The point motion is still "expanded" on the frame. Apparently there is a "double" hit on the motion of the fAnimPos. I think I need to subtract one of those values.
-vern
You changed the max pose variable loop in some spots from:
Code: Select all
for k=1, maxposes do
Code: Select all
for k=2, maxposes do
It still isn't right though. The point motion is still "expanded" on the frame. Apparently there is a "double" hit on the motion of the fAnimPos. I think I need to subtract one of those values.
-vern
-
- Posts: 45
- Joined: Mon Jun 11, 2007 9:02 am
I did that to ignore frame one except as a comparison as the neutral pose. If you wanted to include it as a normal pose you'd need to make another variable and store the neutral pose in there instead of with all the others. It was more work than just cutting it out.
Heh, if it's doing something else clearly I'm confused as to how the loops were working.
Heh, if it's doing something else clearly I'm confused as to how the loops were working.
This is the only change I made to Genete's original script. If you replace this in Genete's original script it works pretty well. However there is still that bizarre weird shifting of the points when you move them on a frame. It's difficult to do precise edits. I don't know exactly what is causing this.
Code: Select all
---------------------------------------------POINT MOTION
local fc3=mesh:CountPoints()-1 -- added to speed up loops
for i=0, fc3 do --- move the points.
pimoved:Set(0,0)
pi= mesh:Point(i)
---------------- Begin HV Change
pimoved=pi.fAnimPos:GetValue(frame)
pimoved=pimoved-pi.fAnimPos:GetValue(0)
--if (pi.fAnimPos:HasKey(frame)) then break end -- if there is a keyframe then don't overrride it.
---------------- End HV Change
for k=1, maxposes do
pimoved = pimoved + poses[layer]["points"][k][i]*w[k]
end
if(GE_ToggleKeyframePoses.Status==false) then
mesh:Point(i).fPos:Set(pimoved) --move the point
else
pi.fAnimPos.value=pimoved -- move the point
pi.fAnimPos:StoreValue()--this produces a keyframe and stores its valule
moho.document:SetDirty()
end
end
---------------------------------------------END POINT MOTION