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

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

Post by Genete »

heyvern wrote:Once I get beyond a certain number of points it becomes virtually impossible to use
place all the points/shapes into a single vector layer helps?
Remember that only shapes that are going to change its Z depth are needed to be put in different layers.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Use the strength is for that task useless because you cannot change it over time. You can change length using scale variable value. Also the strength is not shown during bone displacement and you should figure out if the bone strength is touching the pose bone or not.
Excellent points! I should have thought of that! Also the possibility of "step" movement. It never occurred to me. You're right you could end up with a situation where the points might "snap" to a new position if the influence changed.
place all the points/shapes into a single vector layer helps?
Not much really. I only have 3 layers and 3 poses for this test. One of those is a mask. Putting all on one layer isn't an option.

I did try it with one layer. It's still too slow to be useful for me. The layer is just a set of teeth and gums. There are a few points, 6 per tooth, 20 teeth, but it could get that high pretty easily (especially me! ;) ).

I still keep thinking there should be a way to increase efficiency. The lua scripting is AMAZINGLY fast at calculations. Just look at your 3D bone code! All those bones and that thing just flies like the wind! ;) Some of my scripts and files can handle over 300 bones in a lua table with no trouble.

I just can't figure out why doing a similar thing with points is so much slower. I am going to fiddle around with putting the pose frame point positions in a table on frame 0. Poses are "fixed" and unchanging and you have to "deactivate" the script to change poses anyway. My thought is one table "field" for each point with values for each pose. You could fly through a table like that very quickly.

I am hoping that traversing a lua table is faster than traversing the point list. Lua tables are wicked fast.

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

Post by Genete »

Hey Darth! here is your model test without interpolation problems.

http://www.darthfurby.com/genete/Script ... linear.zip

There you'll find a new version of the script:

posesarray-linweight.lua

And your model test file.
I've added a new bone and a dummy circle. This circle tells you whether the poses are having influence or not in the final rendered image.
You can move the pose bones or move the boneselector or the scale of the bone selector. The script will wrap only the bone poses that are inside the circle. The weight of each bone pose is linear to the distance.

I've tested with other kind of functions: cosine works well also but makes some strange ease-in out effects. You can change the weight function at the end of the script.

Here is the result:

http://www.darthfurby.com/genete/Script ... st-lin.swf

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 deveopment...

function LayerScript(moho)
-------------------------------
	local maxposes = 4
-------------------------------
	if (moho.frame <=maxposes) then 
		return -- it works only for other frames beyond frame 0
	end
	local skel = moho:ParentSkeleton()
	if (skel == nil) then
		print ("No parent skeleton found in layer:".. moho.layer:Name())
		return
	end
	local mesh = moho:Mesh()
	if (mesh==nil) then
		print ("No mesh found in layer:".. moho.layer:Name())
		return
	end	
	local bone= {}
	local w = {}
	local distance 
	local boneselector = nil
	local posk
	local pos_selector
	local r
	local length
	for k=1, maxposes do
		bone[k] = nil
		for i=0, skel:CountBones() -1 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
	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
	for i=0, mesh:CountPoints()-1 do --- move the points.
		local pi=mesh:Point(i)
		local pimoved =LM.Vector2:new_local()
		pimoved:Set(0,0)
		for k=1, maxposes do
		local pospik=pi.fAnimPos:GetValue(k)
			pimoved = pimoved + pospik*w[k]/wtot
		end
		pi.fPos:Set(pimoved)
	end
end


function weight (r, l)
	if (r <= l) then 
	local w =r/l-1
		return w
	else
		return 0.0
	end
end
Genete
Posts: 3483
Joined: Tue Oct 17, 2006 3:27 pm
Location: España / Spain

Post by Genete »

I still keep thinking there should be a way to increase efficiency
For sure!. Please modify the code as much as you can to make it faster!. But I would wait to the final version. AS you can see at the previous post there is a new version with limited weights.

Also I wonder if it is useful to include shapes and all the rest of variable values of the vector layer (except point width that hasn't any script interface).

What do you think guys?
-G
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Also I wonder if it is useful to include shapes and all the rest of variable values of the vector layer.
This would be kind of cool actually. Imagine shifting color values of a shape using poses. Switch layers can't "blend" colors... but key frames can. Would this be possible? Sounds like a lot of MATH to me. ;)
Please modify the code as much as you can to make it faster!. But I would wait to the final version.
Way ahead of you. The stuff I would be adding could easily be adapted to any changes. It would just be a separate function in the main code. Instead of reading the point list it would build the point list on frame 0 with any appropriate values added to it and then the stuff that happens later would just read the table instead of the mesh points. It would be like a "copy" of all the points and their values.

I will test this on something simple first to see if it even makes a difference. I think it will... but I've been wrong before. ;)
(except point width that hasn't any script interface)
You can get point width only on the each frame using:

Code: Select all

fWidth
fWidth has no "fAnimWidth" like fAnimPos etc. This is just silly. ;)

However using my idea of storing the point values in a table it would be a bit tricky but I suppose you could "jump" to each pose frame and grab the values to store in the table. Once those values are in the table they don't need to be accessed again (if the table isn't empty then the value doesn't need to be checked).

It would depend on how badly you want point width included. This could be a very useful feature but I'm not sure how "weird" it would be to do it. Would the script "jump" to those frames when first loaded? Or would it just update the first time through the time line?

-vern
DarthFurby
Posts: 510
Joined: Sat Jul 29, 2006 1:34 pm
Location: New York City
Contact:

Post by DarthFurby »

Genete - I've played around with the new script, but still can't seem to get the interpolation to behave properly the way you have it set up in the revised modeltest file(most likely I'm doing something wrong here).

http://darthfurby.com/as/simplemodel.zip

I only have the first five poses turned on using a very simple model.


Vern - It's not just you but the script gets REALLY laggy when I have too many vector points in the model. For now I'm experimenting with a simple model for betatest purposes.

Anyway, I'll keep playing with this when I get back from work.
User avatar
funksmaname
Posts: 3174
Joined: Tue May 29, 2007 11:31 am
Location: New Zealand

Post by funksmaname »

WOW! this is so exciting!
why was it not made a sticky right away!? i didnt know it existed till just now...

i wonder if rather than referencing keyframes (1/2/3/4 etc) you could reference actions?? if they were named properlu (pose1 etc) that would not clutter the main timeline with 'poses' (at the point were there are phenomes, and other poses etc it might get confusing with lots of frames in the main timeline... no biggy though....

also, as a future thought, could there be a way to name bones so they are grouped - i.e. pose1-4 control pose, eye1-4 control 4 eye movements, etc (named by the user rather than fixed) so then you can have a whole bunch of controls for specific parts of the rig rather than a centralised one?? just a thought.

Well done genete - this is amazing!
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

funksmaname wrote:WOW! this is so exciting!
why was it not made a sticky right away!? i didnt know it existed till just now...
Probably best to wait till it gets closer to a final version. As long as the topic is "hot" it stays at the top of the list.
funksmaname wrote:i wonder if rather than referencing keyframes (1/2/3/4 etc) you could reference actions??...
I don't think that would work. You would have to be on the time line of the action to get the key values. Actions are like "tiny" AS documents inside an AS document. You can do all the same stuff but you have to "activate" the action. The only way to get those keys into the MAIN time line from an action is to insert it as a key frame.

Maybe... just maybe... you could store the action point motion in a lua table on frame 0 (see my previous posts here on that idea). It would look kind of funky though as AS bounces around to all the actions to store the data. Probably it would be best to store ALL the poses in ONE action to minimize this (I'm making this up on the fly. ;) ) Or keys could be set from the action and then deleted after the positions are used. I don't know... it's slow now... this would just add a new level of processing. ;)
funksmaname wrote:... could there be a way to name bones so they are grouped - i.e. pose1-4 control pose, eye1-4 control 4 eye movements, etc...
I thought about that as well. I've been running it through my head trying to figure out a way to do that. It would involve either point groups (groups aren't accessed the same as points or bones. there is very limited scripting access to point groups unfortunately) or by bone binding.

Bone binding might work since bones have no effect on points directly in this script, bone point control is completely "overridden" by the script. So... you bind the points for the eyes to an "eye_bone". You can easily sort through only the points that are bound to the eye bone and those would be the only points moved for that pose when the master eye pose bone is moved. If the "eye_bone" has a PARENT bone and that one is moved then all the points controlled by children of the bone would move... follow me? You could "group" poses just like you have say, an entire arm as a child of the shoulder.

I think this might work... but you are correct that it should come "later". It would need some serious testing. Man if that could be pulled off it would jump this script to ANOTHER level of coolness! ;)

One of the big drawbacks to this script is the total lack of secondary control using bones for point movement. I haven't even tried to think of a way to overcome that... makes my head spin. Maybe Genete has a trick up his sleeve. ;)

I did think about the concept of "poses" using BONES as well as point motion. You CAN get the point motion from bone influence and convert it directly to point motion only. That motion could be ADDED to the "weight" when the point motion is calculated... (that's when my eyes glaze over, roll back into my head and I pass out. ;) )

-vern
User avatar
funksmaname
Posts: 3174
Joined: Tue May 29, 2007 11:31 am
Location: New Zealand

Post by funksmaname »

One of the big drawbacks to this script is the total lack of secondary control using bones
hmmm i hadnt noticed that... 'bugger' as we say 'round these parts. however, you can have the effected bone layer under another bone layer and control its movement on a bone... so all the facial animation is done with the script but another parent bone layer effectively does the 'neck' movements as well as the body... I dont know if secondary weighting is that necessary??

Although saying that - ive just thought of a way it might be useful to control pupils via a bone, while controling an actual facial rig with this script - extreme facial poses might look the same but the pupils and tongue will need to be independant...

what might also be useful (in a seperate script) would be to use this sort of 'bone moving' to select switch sub layers? you could animated switched hands by animating a master bone arch rather than inserting switch layer references?? just a thought :P

-------

tried this on my 'doll' character - was having so much fun till it crashed :)
I think efficiency/stability improvements are a must...
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

I really like this idea of using poses. This could provide a TON of solutions for a lot of things. The only thing is... a pose is "fixed". Sometimes you want to "tweak" the motion of points to add "variety" to a fixed set of poses.
however, you can have the effected bone layer under another bone layer and control its movement on a bone...
I haven't tried this yet but I was thinking of nested bone layers in combination with this script. This might be what you are suggesting. Imagine you have a bone layer with a set of vectors to just do "head turns". The basic head turn doesn't need to have variations or secondary control outside of the scripted solution.

Now you add a nested bone layer inside that layer that is bound to the bone for the poses in some way. The head turns and it drags the mouth along with it... this nested bone layer ALSO has vector layers with poses.

This is where additional bone distortion would be nice. The mouth bone layer has poses say, for phonemes, but you might want to make a character smile or frown while "talking" without having 50 bazillion pose frames to do that. A few bones could "tweak" the mouth into a frown or smile or exaggerated position that is ADDED to the pose motion.
what might also be useful (in a seperate script) would be to use this sort of 'bone moving' to select switch sub layers? you could animated switched hands by animating a master bone arch rather than inserting switch layer references?? just a thought.
I have a script that does that using rotation (I haven't released it yet because I haven't figured out how to "divide" the angles properly to get the switch layers to switch in a logical way). I suppose it could be modified to use translation instead... and it would eliminate the rotation problem... god I hate math. ;)

This would be really useful for doing shape sorting for turns! You could have several layers in a switch each with the same poses but the shapes ordered differently. Moving the bones would make shapes flip up and down in the order using the switch layers.

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

Post by Genete »

This is what I think:

This idea of poses is to substitute/improve the well known 1 frame action technique from Darthfurby. The script simply override any point motion done by bones or point keyframe itself. You cannot move the points with any other tool if the script is running.
As you can see from DF tutorials the model has an skeleton for global rotations of the head or what ever. That can continue being doing with layer binding.

Other aspect is the performance. As much as you want to complicate the script with more and more checkings about the bone names and so, it will go slower. And more unstable. I've seen that there is memory problems when running the script several times and a lot of points. It maybe some thing with the lua arrays.

I have an idea to improve performance. When the current frame is over one frame pose the script (last version) simply returns. I want to use that moment to store the layer parameters value into an array. I would read that array later directly instead of pick up the values from the stored frames. It would solve the point width issue. But will introduce a problem if the user doesn't pass over all the poses almost once. Also it would let the user "correct" the pose meanwhile the script is loaded. It will update the pose for all the animation in one shot.

It is also a good thing to have the arrays of vector layer values fixed. I think the arrays must be stored by other external script (menu script) into a persistent external arrays (like in the 3Drig model). I believe that lua doesn't free the arrays and gets more and more memory each time the script runs.

This script and its development is completely open and free so you can make as many forks of the original as you want. I want to continue making it as simple as possible and more stable and quick as possible.

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

Post by heyvern »

When the current frame is over one frame pose the script (last version) simply returns. I want to use that moment to store the layer parameters value into an array. I would read that array later directly instead of pick up the values from the stored frames.
I think that might be the only solution to improve performance. In all my studying of Lua the one thing I keep coming across is how fast the tables and arrays are.

I'll wait for the "final" version before I attempt any crazy additions. You're right, let's keep it simple. Interesting thought on the "memory usage" of scripts. I've never done any testing but this could explain some crashes I have after using some scripts for a long period of time.

Although another thing about Lua that comes up a lot is how efficient its garbage collection is. it depends though on how the variables are used. If you "copy" a variable the wrong way it never gets removed from memory. I got hit by that problem a few times. I also find it annoying that closing a document doesn't delete those huge table variables.

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

Post by Genete »

DarthFurby wrote:Genete - I've played around with the new script, but still can't seem to get the interpolation to behave properly the way you have it set up in the revised modeltest file(most likely I'm doing something wrong here).

http://darthfurby.com/as/simplemodel.zip

I only have the first five poses turned on using a very simple model.


Vern - It's not just you but the script gets REALLY laggy when I have too many vector points in the model. For now I'm experimenting with a simple model for betatest purposes.

Anyway, I'll keep playing with this when I get back from work.
I think you have used the wrong script. Try again with the script fromthis post. The one inside the zip file or the pasted as code section. (they are both the same).
Take account to set the boneselector current length to be exactly the same as fixed distance of the poses bones. Like in my example. Use the grid.

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

Post by Genete »

I have an idea to improve performance. When the current frame is over one frame pose the script (last version) simply returns. I want to use that moment to store the layer parameters value into an array. I would read that array later directly instead of pick up the values from the stored frames. It would solve the point width issue. But will introduce a problem if the user doesn't pass over all the poses almost once. Also it would let the user "correct" the pose meanwhile the script is loaded. It will update the pose for all the animation in one shot.
There is a secondary problem and more important even: The store array should be a multidimensional array:

Code: Select all

(maxposes) x (number of vector layers parameters) x (number of vector layers)
Max poses can be known (it is written in the script) and number of vector layers parameters also, but how to know how many layers (and which) have the script embedded? :roll:
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Max poses can be known (it is written in the script) and number of vector layers parameters also, but how to know how many layers (and which) have the script embedded?
I may be missing something. Why would you need to know how many layers? In my opinion all the layers would have the same number of poses (maxposes) they would all "transform" in the same way at the same amount.

If each of those layers has the same script there would be a unique table array for each layer and set of points.

If I have this wrong let me know.

EDIT: if this is needed it would be a simple matter of putting an extension on the name of the layers with the script.

-vern
Post Reply