Can ASP control a switch, based on its bone angle?
Moderators: Víctor Paredes, Belgarath, slowtiger
These are switch layers. You would need to bind the switch to a bone so you can rotate the whole switch. Genete mentioned in his last post that he would be working on that. Most likely it will need a special name for the bone and switch layer to "match" them up.ruibjr wrote:Vern, any ideas on why the shape won't rotate, and is there a way to make it work with any control bone?
-vern
Last edited by heyvern on Tue Apr 21, 2009 6:37 pm, edited 1 time in total.
What a useful script!, thanks you guys.
For the control bone, couldn't you use one called nameofswitchlayer.control? If one doesn't exist, automatically create one in the topmost bone layer.
Too bad you can't create note-layers by lua, would be nice to have one close to the control-bone with the name of the current switch-layer.
For the control bone, couldn't you use one called nameofswitchlayer.control? If one doesn't exist, automatically create one in the topmost bone layer.
Too bad you can't create note-layers by lua, would be nice to have one close to the control-bone with the name of the current switch-layer.
Nah! not much code there!. Just a bit of maths.heyvern wrote:Thanks Gente!!!!!! It works GREAT now! Woooohooooo! This is great! I always wanted this script for switching hands and other things.
-vern
I left you or others to try to use other bones than the bone 0 to control the switch layer.
One proposal for that:
The control bone's name must be the same than the switch layer name that want to control. Using bone 0 every switch layer would turn with it, what is not useful.
Also I think that it would be interesting to have the control bone and the script in the switch layer. It would allow to have other script in the bone layer (that's very important in some circumstances)
Maybe I can do something on those proposals.
-G
1) Save as Switcher.lua
2) Embed it in a switch layer
3) The bone number 0 in the switch layer controls the switch value.
4) Keyframes on the switch layer seems to be updated after press play.
5) It doesn't work for negative turns. I've tried to enable it but failed.
6) You can embed a script in each switch layers what gives control independence.
7) Move the bone keys and the switch keys will follow.
Based on first script from heyvern.
I hope you like it.
-G
2) Embed it in a switch layer
3) The bone number 0 in the switch layer controls the switch value.
4) Keyframes on the switch layer seems to be updated after press play.
5) It doesn't work for negative turns. I've tried to enable it but failed.
6) You can embed a script in each switch layers what gives control independence.
7) Move the bone keys and the switch keys will follow.
Based on first script from heyvern.
I hope you like it.
-G
Code: Select all
function LayerScript(moho)
local layer = moho.layer
if (not layer:IsBoneType()) then
return
end
local group = moho:LayerAsGroup(layer)
local layerCount = group:CountLayers()
if ( layerCount == 0 ) then
return
end
local skel = moho:Skeleton()
local boneCount = skel:CountBones()
if ( boneCount == 0) then
return
end
local SwitchLayer = moho:LayerAsSwitch(layer)
if(SwitchLayer==nil) then
return
end
local crtlBone = skel:Bone(0)
local keySwitch = nil
local Oneturn = math.rad(360)
local TurnsPerLayer = Oneturn /layerCount
if ( moho.frame > 0 ) then
if ( crtlBone.fAnimAngle:HasKey(moho.frame) ) then
keySwitch = math.mod(crtlBone.fAngle,Oneturn)
end
for b = 0, layerCount-1 do
local swLayer = group:Layer(b)
local swName = swLayer:Name()
if ( keySwitch ~= nil ) then
local Bottom = b * TurnsPerLayer
local Top = TurnsPerLayer + Bottom
if (keySwitch <= Top and keySwitch >= Bottom) then
SwitchLayer:SwitchValues():AddKey(moho.frame)
SwitchLayer:SwitchValues():SetValue(moho.frame, swName)
end
elseif ( keySwitch == nil) then
SwitchLayer:SwitchValues():DeleteKey(moho.frame)
end
end
end
end
I am so glad I found this forum.
Thank you so much.
This is amazing.
And you guys are so proactive. This is trully amazing.
On the better inteface for switching, I think besides having that, we still can use this script.
The way I plan to use it is to implement it in every problematic connection, such as the knees and the elbows.
This script allows me to hand-draw the specific drawing for each problematic angle range.
This way, I can simply rotate the lower arm bone and have the script select the perfect drawing for a perfect macth.
So, we can build characters that look perfect every tme, without having to worry about bone bending, loops and collapsing.
Thanks Vern, Thanks Genete, thank you so much.
SO cool. And useful.
Thans, guys.
Thank you so much.
This is amazing.
And you guys are so proactive. This is trully amazing.
On the better inteface for switching, I think besides having that, we still can use this script.
The way I plan to use it is to implement it in every problematic connection, such as the knees and the elbows.
This script allows me to hand-draw the specific drawing for each problematic angle range.
This way, I can simply rotate the lower arm bone and have the script select the perfect drawing for a perfect macth.
So, we can build characters that look perfect every tme, without having to worry about bone bending, loops and collapsing.
Thanks Vern, Thanks Genete, thank you so much.
SO cool. And useful.
Thans, guys.
That's a fantastic idea ruibjr!!!!
The angle of the limb itself controls the switch.
This should be done with a modified script though. Instead of evenly spaced rotations selecting a random number of layers in the switch you would want to put in SPECIFIC rotation values that only change the switch layer when that angle is reached.
COOOL idea. With smooth interpolation of switches this would be a great way to adjust joints on limbs as bones turn.
-vern
The angle of the limb itself controls the switch.
This should be done with a modified script though. Instead of evenly spaced rotations selecting a random number of layers in the switch you would want to put in SPECIFIC rotation values that only change the switch layer when that angle is reached.
COOOL idea. With smooth interpolation of switches this would be a great way to adjust joints on limbs as bones turn.
-vern
That would be perfect, I mean, being able to specify the actual angles.
But the script is most useful already, the way it is.
What I am going to do, is I am going to use 10 options for each limb; every time.
Then, I can simply replicate the "default" shape for the lower arm (for example) 10 times.
This will result in one different image for each 36 degrees "slice", which I believe will be pretty good.
Then, I can go and edit the ones that are looking bad.
I will try this technique and will let you know what kind of results I get.
Cheers.
edit
==============
As a matter of fact, most limbs will rotate about 120 to 140 degrees, so the accuracy would be of about 12 to 14 degrees - pretty good, actualy.
==============
/edit
But the script is most useful already, the way it is.
What I am going to do, is I am going to use 10 options for each limb; every time.
Then, I can simply replicate the "default" shape for the lower arm (for example) 10 times.
This will result in one different image for each 36 degrees "slice", which I believe will be pretty good.
Then, I can go and edit the ones that are looking bad.
I will try this technique and will let you know what kind of results I get.
Cheers.
edit
==============
As a matter of fact, most limbs will rotate about 120 to 140 degrees, so the accuracy would be of about 12 to 14 degrees - pretty good, actualy.
==============
/edit
Guys,
Do you think it is possible to retrieve the control bone's angle constraints?
Like, for instance, if one limits the rotation to -10 to +120 degrees.
This would allow the script to divide that actual range (130 dgrees) by the (say) 10 options in the switch layer, instead of dividing the full 360 degrees.
This would be incredibly useful.
Do you think it is possible to retrieve the control bone's angle constraints?
Like, for instance, if one limits the rotation to -10 to +120 degrees.
This would allow the script to divide that actual range (130 dgrees) by the (say) 10 options in the switch layer, instead of dividing the full 360 degrees.
This would be incredibly useful.
It doesn't work for negative values but why don't you do it externally? the control bone can be also controlled by other bone that can be angle limited, and angle scaled to the control bone.ruibjr wrote:Guys,
Do you think it is possible to retrieve the control bone's angle constraints?
Like, for instance, if one limits the rotation to -10 to +120 degrees.
This would allow the script to divide that actual range (130 dgrees) by the (say) 10 options in the switch layer, instead of dividing the full 360 degrees.
This would be incredibly useful.
For example:
b= bone that control the script
c= bone that you effectively would animate
limit c.angle to [0,130]
b.angle=360/130*c.angle
Then to offset the bone c just make it child of a bone that actually is rotated -10 deg. And voila! your control bone is in the range of -10,120 and controls all the sublayers of the switch layer!

-G
Hi guys.
I was able to make it work exactly the way I needed.
Here is the script:
It was built on top of HeyVern's original script.
It also includes the changes made by Genete.
Here's how it works:
Just give all limb control bones names that start with "cb.", which stands for "control bone".
Then, create the switch layer that you want to control, as usual, and give it the exact same name you have assigned to the bone.
You can have as many limbs, controlling their corresponding switch layers as you wish.
The script takes care of computing the angle constraints, to give you the best angle-to-switch ratio (a typical 120 degrees limb with 6 optional drawings will result in a 20 degrees accuray - pretty good).
You can use as many optional drawing as you want - it just works.
The onlye three things you have to pay attention to are:
1. You must attach this script to the bone layer
2. You must name the control bones starting with cb.
3. The switch layers must have the same name as the control bones
Thank you so much, guys.
Cheers.
[/code]
I was able to make it work exactly the way I needed.
Here is the script:
Code: Select all
function LayerScript(moho)
------------------------------------------------------------------------------------------
local layer = moho.layer
if ( not layer:IsBoneType() ) then
return
end
------------------------------------------------------------------------------------------
local group = moho:LayerAsGroup(layer)
local layerCount = group:CountLayers()
if ( layerCount == 0 ) then
return
end
------------------------------------------------------------------------------------------
local skel = moho:Skeleton()
local boneCount = skel:CountBones()
if ( boneCount == 0) then
return
end
------------------------------------------------------------------------------------------
local ctrlLayer = nil
local ctrlBone = nil
local keySwitch = nil
local Lcount = nil
local SWunits = nil
local keySwitch = nil
local nextBone = nil
local theBoneName = nil
local tUnit = nil
------------------------------------------------------------------------------------------
for nextBone = 0, boneCount - 1 do
ctrlBone = skel:Bone(nextBone)
theBoneName = ctrlBone:Name()
if (string.sub(theBoneName, 1, 3) == "cb.") then
tUnit = ctrlBone.fMaxConstraint - ctrlBone.fMinConstraint
if (moho.frame > 0) then
local subSwitch = nil
if (ctrlBone.fAnimAngle:HasKey(moho.frame)) then
keySwitch = ctrlBone.fAngle
keySwitch = keySwitch - ctrlBone.fAnimAngle:GetValue(0) - ctrlBone.fMinConstraint
end
Lcount = -1
for i = 0, layerCount - 1 do
local testlayer = group:Layer(i)
if (testlayer:LayerType() == MOHO.LT_SWITCH) then
if (testlayer:Name() == theBoneName) then
group2 = moho:LayerAsGroup(testlayer)
subSwitch = moho:LayerAsSwitch(testlayer)
Lcount = group2:CountLayers()
SWunits = tUnit / (Lcount)
break
end
end
end
if (Lcount > 0) then
for b = 0, Lcount - 1 do
local swLayers = group2:Layer(b)
local SWname = swLayers:Name()
local swUnit = (b * SWunits)
local swUnitB = swUnit + SWunits
if ( keySwitch ~= nil) then
if (keySwitch <= swUnitB and keySwitch >= swUnit) then
subSwitch:SwitchValues():SetValue(moho.frame, SWname)
end
elseif ( keySwitch == nil) then
subSwitch:SwitchValues():DeleteKey(moho.frame)
end
end
end
end
end
end
------------------------------------------------------------------------------------------
end
It also includes the changes made by Genete.
Here's how it works:
Just give all limb control bones names that start with "cb.", which stands for "control bone".
Then, create the switch layer that you want to control, as usual, and give it the exact same name you have assigned to the bone.
You can have as many limbs, controlling their corresponding switch layers as you wish.
The script takes care of computing the angle constraints, to give you the best angle-to-switch ratio (a typical 120 degrees limb with 6 optional drawings will result in a 20 degrees accuray - pretty good).
You can use as many optional drawing as you want - it just works.
The onlye three things you have to pay attention to are:
1. You must attach this script to the bone layer
2. You must name the control bones starting with cb.
3. The switch layers must have the same name as the control bones
Thank you so much, guys.
Cheers.
[/code]
- Víctor Paredes
- Site Admin
- Posts: 5818
- Joined: Wed Jan 26, 2005 12:18 am
- Location: Barcelona/Chile
- Contact:
Hey, I didn't know the existence of this script (I just found it via animatorsforums).
It's fantastic, I really don't like to be going over and over to the layer window (I don't like much the menu use of secundary click neither), so it's just perfect.
Thanks!
It's fantastic, I really don't like to be going over and over to the layer window (I don't like much the menu use of secundary click neither), so it's just perfect.
Thanks!






Moho co-owner
Previously Rigged animation supervisor: My father's dragon, Wolfwalkers & Star Wars Visions "Screecher's Reach"
My personal Youtube Channel