Page 2 of 3

Posted: Tue Apr 21, 2009 4:16 pm
by ruibjr
That's awesome.

Thanks, Genete.

Vern, any ideas on why the shape won't rotate, and is there a way to make it work with any control bone?

Posted: Tue Apr 21, 2009 6:27 pm
by heyvern
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?
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.

-vern

Posted: Tue Apr 21, 2009 6:36 pm
by heyvern
Thanks Gente!!!!!! It works GREAT now! Woooohooooo! This is great! I always wanted this script for switching hands and other things.

-vern

Posted: Tue Apr 21, 2009 9:34 pm
by rylleman
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.

Posted: Tue Apr 21, 2009 9:40 pm
by Genete
heyvern wrote:Thanks Gente!!!!!! It works GREAT now! Woooohooooo! This is great! I always wanted this script for switching hands and other things.

-vern
Nah! not much code there!. Just a bit of maths.

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

Posted: Tue Apr 21, 2009 11:11 pm
by Genete
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

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

Posted: Tue Apr 21, 2009 11:14 pm
by Genete
Btw, all those scripts are just a workaround for a better interface that allows easy visual selection of the switch layer. It should be added as main feature in the next version but with the proper interface and not need to sacrifice to use a script in the switch layer to achieve the feature.

-G

Posted: Tue Apr 21, 2009 11:43 pm
by ruibjr
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.

Posted: Wed Apr 22, 2009 3:43 pm
by heyvern
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

Posted: Wed Apr 22, 2009 6:44 pm
by ruibjr
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

Posted: Wed Apr 22, 2009 7:20 pm
by ruibjr
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.

Posted: Wed Apr 22, 2009 8:40 pm
by Genete
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.
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.

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!
:D
-G

Posted: Wed Apr 22, 2009 8:59 pm
by ruibjr
That is a very clever solution, Genete.

Thanks for sharing the idea.

Posted: Thu Apr 23, 2009 1:47 am
by ruibjr
Hi guys.

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 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]

Posted: Sat Jan 23, 2010 11:30 pm
by VĂ­ctor Paredes
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!