i have a script request! (Poses)

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

Moderators: Víctor Paredes, Belgarath, slowtiger

User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Doesn't the script do that already? It gets the point values of the poses on those other frames.

There are two things to look at in the script reference:

fPos and fAnimPos. Each one is a bit different. fPos I think is what you are trying to get unfortunately I am pretty sure it only works on the current frame. You can't access it from another frame.

fAnimPos can be accessed on another frame because you can access that value using a frame number reference. I think you should try fAnimPos to see if that gives you the value you need.

It would help to see what you've been trying to do to get that value.

-vern
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

pi is the point variable from the loop. "frame" is the frame number you want the value from. You can put any number or variable you want in there. if "frame" is the current frame you could put "frame -1) to get the previous frame etc etc.

Code: Select all

pi.fAnimPos:GetValue(frame)
I am almost certain fAnimPos is the only way to get a value on another frame. Unless you get the value and store it as the time line moves past that frame... that would be a nightmare to manage though and the constant updating would probably slow things down.

-vern
User avatar
madrobot
Posts: 667
Joined: Mon Apr 07, 2008 3:07 pm

Post by madrobot »

Reading this without having had my morning coffee does not seem to be working out.

http://www.youtube.com/watch?v=HY-03vYYAjA
PocketGoat
Posts: 45
Joined: Mon Jun 11, 2007 9:02 am

Post by PocketGoat »

Yeah, I tried fAnimPos, but it doesn't appear to take into account bone effects.
The idea was to make the pose frames deformed by the skeleton in the same way the current frame is, that way the morphs would still be accurate. Getting the skeleton on the pose frames to change to whatever the current frame is was fine, but there's no way to access the updated point positions from the current frame as far as I can find.
I've tried using fAnimPos, and I tried changing to the pose frames mid-script to grab the fPos, which was massively slow and didn't work.

I'm tentatively concluding it's not possible, since I'm guessing anime studio only calculates the absolute point position as affected by bones and everything when it changes to that frame, so it's not actually stored.

I probably could get the changing to the pose frames idea to work with some clever loops, but changing frames 5+ times every time the script is run is not a good solution.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

I think there is a way to get the bone/points matrix (I mentioned this in passing before). However I have never been brave enough to try it. The point matrix of the bone is the points influenced by bones and I assume this includes the motion and influence based on the strength of the bone. I suppose you could try to figure out the bone motion influence on the points using that but... <sigh> I don't want to go there myself. The thought of it makes me very sleepy. ;)

-vern
PocketGoat
Posts: 45
Joined: Mon Jun 11, 2007 9:02 am

Post by PocketGoat »

Heh. The word "matrix" scares me off a bit. This is the first script I've played around with and I'm kinda sick of looking at it. I can work around the limitation by having every freely rotating part on a different layer, which is good enough for me for now.

If someone else was to pick it up, either re-writing it to use seperate "pose layers" as a reference instead of frames, or incorporating the bone/point matrix calculations that would be great.

I think it'll be some time before I feel adventurous enough to try myself.
chucky
Posts: 4650
Joined: Sun Jan 28, 2007 4:24 am

the matrix issue

Post by chucky »

I figured a way to sort out this "matrix"issue..
It firstly involves sticking a shiny metal spike into the back of my head.
I'm gonna' try it out later tonight.... wish me luck. :wink:
Either that or take one of these pills here...now was it the blue one or the red one? hmmmmm. :?:
Hopefully the finished script will be handed to you in person by a pale dude in a black suit and sunglasses. :roll:
Last edited by chucky on Tue May 19, 2009 10:27 am, edited 1 time in total.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

"Matrix math" is pretty... complicated. I've only used it in one of my custom scripts for bone colorizing/grouping. I have no idea how or why it does what it does but it works.

For example a layer has a "transformation matrix" that can be accessed and used to change other things. You can use a "matrix" to change the locations of points, or bones. I am NOT an expert with matrices but the general idea in my own head is that they are a 3 x 3 grid of numbers that represent a transformation. When you multiply or add or whatever a matrix to a value like x y coordinates it uses all the numbers in the "grid" to create a new value or whatever, that matches the matrix.

This is... beyond me right now. About a year or so ago I actually understood some of it. I think maybe I used it in Genete's "3D" script to create 3D perspective distortion. I created some sort of 3D matrix and applied it to the bone locations to change the focal length of the "view". I've since forgotten everything I learned about that topic. ;)

p.s. As I recall I plugged in the numbers and matrix stuff... and it worked. I didn't bother to research beyond the point of "Holy cow it works!". ;)

-vern
Genete
Posts: 3483
Joined: Tue Oct 17, 2006 3:27 pm
Location: España / Spain

Post by Genete »

Trying to push the script a little more.
Excuse me because I've forked this version based on my 2.1 version because your latest modifications seems not to be stable or at last I don't understand them. Feel free to refork them again :)

http://www.mediafire.com/?l4xnpcymtxe
The poses 2.2 version and the modeltest as usual, just open it and press play. Everything is written on it. Enjoy!

To do:
- Extend the functionality so each vector layer can have its own wrapper.

(what's a "wrapper" hahahahahah! open the modeltest!)
-G

Code: Select all

--Poses 2.2 (last edited May 20, 2009)
--Copyright 2008,2009 Genete
--Released for free.
--Thanks to Selgin for that great idea.

--INSTRUCTIONS:

--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
--It can be extended for other animated values (curvatures, widths,
--shape fill colors, shape outline color, etc.)

--CHANGELOG:

--Genete: 2008, June 5th:
--Curvature done!
--Also weights w[k] can be overweigthed by the pose bone legth. It would
--allow some sort of variable action weights...
--Tim Fischer: (date missing)
--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 interpolated
---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.

--Genete: 2009, May 20th
--Reformatted the changelog and the instructions.
--Reformated the code. Deleted uneeded comments.
--Added influence of a single bone for the pose. I've called it "wrapper"
--I've tried to combine more than one bone to obtain the compund influence
--matrix for the points based on the bones that are not the poses or the
--selector. Multiply the influence matrixes seems not to be the way. I think
--that the "skeleton matrix" based on each bone point matrix influence,
--the strenght and the bind mode (region or flexible) is not opened to scripting...
--... and never will be? A pita!. Enjoy! at last one single bone works!
--Change the fucntionality:
--if you're at frame 0 the script doesn't run
--if you're at 0<frame<=maxposes then search and store the values only if
--the toggle pose is false, otherwise the script doesn't run. It allows
--edition easily at frames 0-masposes.
--So ehn you find a "trying to bla bla a nil value" in the middle of the
--time line you have to go to any of the poses not the frame 0 to restore
--the bones, points, curvatures, etc.

poses = {}
-----------CHANGE THIS VALUE TO SE THE AMOUNT OF POSES------------------
maxposes = 4
------------------------------------------------------------------------
bone = {}
boneselector = nil
wrapper = 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==0) then return end
--- store bones, curvature, and styles
   if ((frame <=maxposes and frame > 0) or boneselector == nil) then
      if (GE_ToggleKeyframePoses.Status==true) then return end
      for k=1, maxposes do
         bone[k] = nil
         local fc1 = skel:CountBones()-1
         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
            elseif (bonei:Name() == "wrapper") then
			   wrapper=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
      poses[layer]={}
      poses[layer]["points"]={}
      for k=1, maxposes do
         poses[layer]["points"][k]={}
         local fc2 = mesh:CountPoints()-1
         for i=0, fc2 do
            poses[layer]["points"][k][i]=mesh:Point(i).fAnimPos:GetValue(k)
         end
         collectgarbage(fc2)
      end
      poses[layer]["curvature"]={}
      for k=1, 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)
            end
            collectgarbage(fc4)
         end
         collectgarbage(fc3)
      end
      poses[layer]["fillcolor"]={}
      poses[layer]["linecolor"]={}
      poses[layer]["linewidth"]={}
      for k=1, 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
   length = boneselector.fLength*boneselector.fScale

-- Calculate the distance form the boneselector to all the pose bones and
-- calculate its "weight" influence
   for k=1, maxposes do
      w[k]=0
      posk = bone[k].fPos
      distance = posk - pos_selector
      r = distance:Mag()
      w[k]=weight(r, length)*bone[k].fScale
   end

   local wtot=0.0
   for k=1, maxposes do
      wtot =wtot +w[k]
   end
   if (wtot == 0.0) then  return  end
   for k=1, maxposes do
      w[k]=w[k]/wtot
   end

---------------------------------------------POINT MOTION
   local fc3=mesh:CountPoints()-1
   for i=0, fc3 do --- move the points.
      pimoved:Set(0,0)
      pi= mesh:Point(i)
	  -- if there is a keyframe then don't overrride it.
      if (pi.fAnimPos:HasKey(frame)) then break end
      for k=1, maxposes do
         pimoved = pimoved + poses[layer]["points"][k][i]*w[k]
      end
	  if(wrapper~=nil) then ---if wrapper bone exists
	    wrapper.fPtMatrix:Transform(pimoved) --move under its inlfuence
	  end
      if(GE_ToggleKeyframePoses.Status==false) then
         pi.fPos:Set(pimoved) --move the point
      else
         pi.fAnimPos.value=pimoved -- move the point
		 --this produces a keyframe and stores its valule
         pi.fAnimPos:StoreValue()
         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=1, 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=1, 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
User avatar
synthsin75
Posts: 9968
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Great work Genete, but it seems the performance suffered. :wink:
PocketGoat
Posts: 45
Joined: Mon Jun 11, 2007 9:02 am

Post by PocketGoat »

Probably only took you an hour to do what I've been trying to do for days :P

Thanks Genete, it's awesome.

That one wrapper thing is a bit of a pain though.
chucky
Posts: 4650
Joined: Sun Jan 28, 2007 4:24 am

Post by chucky »

This is exciting breakthrough Genete, your are....legend.
Can anyone explain though, why the poses aren't activating?
All the scripts are all linked up as they should be , I haven't moved the .anme file from the parent folder but for some reason.... nothing.

??????????????????????????????????:?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?:?????????????????????????
Genete
Posts: 3483
Joined: Tue Oct 17, 2006 3:27 pm
Location: España / Spain

Post by Genete »

chucky wrote:This is exciting breakthrough Genete, your are....legend.
Can anyone explain though, why the poses aren't activating?
All the scripts are all linked up as they should be , I haven't moved the .anme file from the parent folder but for some reason.... nothing.

??????????????????????????????????:?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?: :?:?????????????????????????
Check that you have the ge_toggle_keyframe_poses.lua installed and that it is set to 'false'.
-G
chucky
Posts: 4650
Joined: Sun Jan 28, 2007 4:24 am

Post by chucky »

cool thanks Genete , i'll get right on it.
chucky
Posts: 4650
Joined: Sun Jan 28, 2007 4:24 am

Post by chucky »

when I find that slippery sucker
Post Reply