Inside Sabertooth
Learn how Sabertooth uses 3ds Max to create 3D interactive projects, including HBO Go’s Game of Thrones interactive experience
  • 1/3
You are here: Forum Home / Autodesk 3ds® Max® / MaxScript / Custom Attributes
  RSS 2.0 ATOM  

Custom Attributes
Rate this thread
 
25738
 
Permlink of this thread  
avatar
  • CBruce
  • Posted: 17 April 2009 08:21 PM
  • Location: San Jose, California
  • Total Posts: 82
  • Joined: 18 April 2009 03:10 AM

I’m working on our player model rigs and I’ve been using Paul Neale’s to add custom attribute definitions onto Attribute Holders on various bones and controllers in our scene.  One of these is a simple IK/FK bone snap utility.  Right now, I have a copy of the functions to do this in each unique custom attribute, but I’d like to put these into the master control object instead, and just have the individual custom attributes reference it for the function.

Based on Paul’s tutorial about accessing custom attributes through a script controller, this seems like it should be possible, but I can’t get it to work.

Here’s the basic gist of what I’m doing:

Adding a custom attribute script to “MasterControlObject” (Editable Spline)

attributes CustomAttributes_Globals
            
(           
            function 
SnapIKToFK_ArmL = -- Snap Left Arm IK bones to FK Bones
            
(
                        
with animate on
                        
(
                                    
$CTRL_Hand_Left.rotation $FK_HandL.rotation
                                    $CTRL_Hand_Left
.position $FK_HandL.position
                        
)
            )           
)

Then on another object, I’m trying to call this function through a button in the rollout of a custom attribute script (instanced between the other FK arm bones).

Custom attribute on FK_UpperArmL (Editable Mesh)

...
                        
button SnapIKFKArmL "Arm L" pos:[16,176] width:60 height:24
                        on SnapIKFKArmL pressed 
do
                        (
                                    
$MasterControlObject.CustomAttributes_Globals.SnapIKToFK_ArmL()
                        )
...

Which spits back a “—Type error: Call needs function or class, got:undefined” error message.  I feel like I’m missing something simple here, but don’t know what.

I’m also having a similiar problem with attempting the set the value of a custom attribute in a particular object from a value in an Expose Transform helper (basically trying to set the elbow swivel angle slider to the local rotation angle between the hand and lower arm bone of the FK rig).  I’m pretty sure this is a similiar issue...I’m just not calling the custom attribute correctly in the function.



Christopher L. Bruce - Senior Animation - Cryptic Studios
3DSMax 2009 (SP1) 32-bit/64-bit - Windows 7 Enterprise 64-bit
Intel Core(TM)2 Quad CPU Q9550 @2.83GHz - 8.00GB RAM - GeForce 9800 GT (1GB)

Replies: 0
avatar
  • Ripley
  • Posted: 21 April 2009 04:28 AM

maybe it’s good to check that it can see the function, try to list all attributes sources assigned to objs. Here’s a simple fn to do that

fn listCaSources = ( -- list custom attributes sources
        sel 
selection as array
        for 
o in sel do (
            
caCount custAttributes.count o
            
if caCount == do continue
            
format "\nObj name: %\n----------------------------------\n" o.name
            
for 1 to caCount do print (custAttributes.getDef o i).source
        
)
    )

Good luck!  :-)



Replies: 0
avatar
  • CBruce
  • Posted: 22 April 2009 08:24 PM

I’m really not sure what to do with that script you gave me.  To me, it looks like it’s just defining a function.  I can copy that into a script editor, save it, run it, and presumably it’s setting up the function listCaSources to look for custom attributes defined on selected objects...but then what?

I’ve tried running entering listCaSources () into the listner window and it just comes back with “OK”.  I’ve tried selecting various objects, same thing.  Not sure where the output is supposed to go or what to look for.

Sorry for being so clueless about this stuff, it’s all new to me.



Christopher L. Bruce - Senior Animation - Cryptic Studios
3DSMax 2009 (SP1) 32-bit/64-bit - Windows 7 Enterprise 64-bit
Intel Core(TM)2 Quad CPU Q9550 @2.83GHz - 8.00GB RAM - GeForce 9800 GT (1GB)

Replies: 0
avatar
  • Ripley
  • Posted: 23 April 2009 09:18 AM

Sorry, the script was only looking for attributes at base level, and didn’t find any, that’s why it prompted ‘ok’.

I give a new version, it goes through all subanims and prints it out at mx listener. Just select objects and run it from mx editor

(
    -- 
travels through all subanims and prints out attribute sources
    fn printAttrSrc obj 
= (
        for 
i in 1 to obj.numSubs do (
            --
format "subAni : %\n" obj[i]
            caCount 
custAttributes.count obj[i]
            
if caCount do (
                for 
1 to caCount do print (custAttributes.getDef obj[i] j).source
            
)
            if 
obj[i].numSubs do printAttrSrc (obj[i])
        )
    )

    
sel selection as array
    for 
o in sel do (
        
format "\nObj name: %\n----------------------------------\n" o.name
        printAttrSrc o
    
)
)


Replies: 0
avatar
  • CBruce
  • Posted: 23 April 2009 01:24 PM

Here’s the result from the root controller object (the object that everything in the rig eventually gets parented to)

Obj nameMovement_ctrl
----------------------------------
"attributes CustomAttributes_Globals
(
    function SnapFKtoIK_ArmL = -- Snap Left Arm FK bones to IK Bones
    (
        with animate on
        (
            
$FK_UarmL.rotation = $Align_IKUArmL.rotation
            
$FK_UarmL.position = $Align_IKUArmL.position
            
$FK_LarmL.rotation = $Align_IKLArmL.rotation
            
$FK_LarmL.position = $Align_IKLArmL.position
            
$FK_HandL.rotation = $Align_IKHandL.rotation
            
$FK_HandL.position = $Align_IKHandL.position
        )
    )

    function SnapFKtoIK_ArmR = -- Snap Right Arm FK bones to IK Bones
    (
        with animate on
        (
            
$FK_UArmR.rotation = $Align_IKUArmR.rotation
            
$FK_UArmR.position = $Align_IKUArmR.position
            
$FK_LArmR.rotation = $Align_IKLArmR.rotation
            
$FK_LArmR.position = $Align_IKLArmR.position
            
$FK_HandR.rotation = $Align_IKHandR.rotation
            
$FK_HandR.position = $Align_IKHandR.position
        )
    )    
    
    function SnapIKToFK_ArmL = -- Snap Left Arm IK bones to FK Bones
    (
        with animate on
        (
            
$CTRL_Hand_Left.rotation = $FK_HandL.rotation
            
$CTRL_Hand_Left.position = $FK_HandL.position
        )
    )    
    
    function SnapIKToFK_ArmR = -- Snap Right Arm IK bones to FK Bones
    (
        with animate on
        (
            
$CTRL_Hand_Right.rotation = $FK_HandR.rotation
            
$CTRL_Hand_Right.position = $FK_HandR.position
        )
    )    
    
    function SnapFKtoIK_LegL = -- Snap Left Leg FK bones to IK Bones
    (
        with animate on
        (
            
$FK_UlegL.rotation = $Align_IKULegL.rotation
            
$FK_UlegL.position = $Align_IKULegL.position
            
$FK_LlegL.rotation = $Align_IKLLegL.rotation
            
$FK_LlegL.position = $Align_IKLLegL.position
            
$FK_FootL.rotation = $Align_IKFootL.rotation
            
$FK_FootL.position = $Align_IKFootL.position
        )
    )
    
    function SnapFKtoIK_LegR = -- Snap Right Leg FK bones to IK Bones
    (
        with animate on
        (
            
$FK_UlegR.rotation = $Align_IKULegR.rotation
            
$FK_UlegR.position = $Align_IKULegR.position
            
$FK_LlegR.rotation = $Align_IKLLegR.rotation
            
$FK_LlegR.position = $Align_IKLLegR.position
            
$FK_FootR.rotation = $Align_IKFootR.rotation
            
$FK_FootR.position = $Align_IKFootR.position
        )
    )
    
    function SnapIKToFK_LegL = -- Snap Left Leg IK bones to FK Bones
    (
        with animate on
        (
            
$CTRL_Foot_Left.rotation = $FK_FootL.rotation
            
$CTRL_Foot_Left.position = $FK_FootL.position
        )
    )    
    
    function SnapIKToFK_LegR = -- Snap Right Leg IK bones to FK Bones
    (
        with animate on
        (
            
$CTRL_Foot_Right.rotation = $FK_FootR.rotation
            
$CTRL_Foot_Right.position = $FK_FootR.position
        )
    )    
)
"
OK


Christopher L. Bruce - Senior Animation - Cryptic Studios
3DSMax 2009 (SP1) 32-bit/64-bit - Windows 7 Enterprise 64-bit
Intel Core(TM)2 Quad CPU Q9550 @2.83GHz - 8.00GB RAM - GeForce 9800 GT (1GB)

Replies: 0
avatar
  • CBruce
  • Posted: 23 April 2009 01:28 PM

Then on another object in the scene (FK Lower Leg bone), there’s this:

Obj nameFK_LlegL
----------------------------------
"attributes CustomAttributes_CTRL_LegL
(
    Parameters main rollout:params
    (
        IKToFKBlend_LegL Type:#float UI:'IKToFKBlend_LegL'
    )

    rollout ParagonStudiosHeader "
Paragon Studios" width:160 height:224
    (
        bitmap bmp1 "
Paragon Logo" pos:[0,0] width:160 height:160 enabled:true fileName:"ParagonLogo.bmp"
        label lbl1 "
ver3.0 2009" pos:[40,200] width:72 height:16
        label lbl2 "
Paragon Studios" pos:[36,168] width:80 height:16
        label lbl3 "
Character Animation Tools" pos:[16,184] width:128 height:16
    )

    rollout params "
FK Controls Left Leg" width:160 height:144
    (
        -- IK Controls
        GroupBox Group_IKControls "
IK Controls" pos:[8,8] width:144 height:72
        slider IKToFKBlend_LegL "
FK/IK:" pos:[16,24] width:128 height:44 range:[0,100,0] type:#float orient:#horizontal ticks:2
    )
)
"
"attributes CustomAttributes_FKIKSnaps
(
    function SnapFKtoIK_ArmL = -- Snap Left Arm FK bones to IK Bones
    (
        with animate on
        (
            
$FK_UarmL.rotation = $Align_IKUArmL.rotation
            
$FK_UarmL.position = $Align_IKUArmL.position
            
$FK_LarmL.rotation = $Align_IKLArmL.rotation
            
$FK_LarmL.position = $Align_IKLArmL.position
            
$FK_HandL.rotation = $Align_IKHandL.rotation
            
$FK_HandL.position = $Align_IKHandL.position
        )
    )

    function SnapFKtoIK_ArmR = -- Snap Right Arm FK bones to IK Bones
    (
        with animate on
        (
            
$FK_UArmR.rotation = $Align_IKUArmR.rotation
            
$FK_UArmR.position = $Align_IKUArmR.position
            
$FK_LArmR.rotation = $Align_IKLArmR.rotation
            
$FK_LArmR.position = $Align_IKLArmR.position
            
$FK_HandR.rotation = $Align_IKHandR.rotation
            
$FK_HandR.position = $Align_IKHandR.position
        )
    )    
    
    function SnapIKToFK_ArmL = -- Snap Left Arm IK bones to FK Bones
    (
        with animate on
        (
            
$CTRL_Hand_Left.rotation = $FK_HandL.rotation
            
$CTRL_Hand_Left.position = $FK_HandL.position
        )
    )    
    
    function SnapIKToFK_ArmR = -- Snap Right Arm IK bones to FK Bones
    (
        with animate on
        (
            
$CTRL_Hand_Right.rotation = $FK_HandR.rotation
            
$CTRL_Hand_Right.position = $FK_HandR.position
        )
    )    
    
    function SnapFKtoIK_LegL = -- Snap Left Leg FK bones to IK Bones
    (
        with animate on
        (
            
$FK_UlegL.rotation = $Align_IKULegL.rotation
            
$FK_UlegL.position = $Align_IKULegL.position
            
$FK_LlegL.rotation = $Align_IKLLegL.rotation
            
$FK_LlegL.position = $Align_IKLLegL.position
            
$FK_FootL.rotation = $Align_IKFootL.rotation
            
$FK_FootL.position = $Align_IKFootL.position
        )
    )
    
    function SnapFKtoIK_LegR = -- Snap Right Leg FK bones to IK Bones
    (
        with animate on
        (
            
$FK_UlegR.rotation = $Align_IKULegR.rotation
            
$FK_UlegR.position = $Align_IKULegR.position
            
$FK_LlegR.rotation = $Align_IKLLegR.rotation
            
$FK_LlegR.position = $Align_IKLLegR.position
            
$FK_FootR.rotation = $Align_IKFootR.rotation
            
$FK_FootR.position = $Align_IKFootR.position
        )
    )
    
    function SnapIKToFK_LegL = -- Snap Left Leg IK bones to FK Bones
    (
        with animate on
        (
            
$CTRL_Foot_Left.rotation = $FK_FootL.rotation
            
$CTRL_Foot_Left.position = $FK_FootL.position
        )
    )    
    
    function SnapIKToFK_LegR = -- Snap Right Leg IK bones to FK Bones
    (
        with animate on
        (
            
$CTRL_Foot_Right.rotation = $FK_FootR.rotation
            
$CTRL_Foot_Right.position = $FK_FootR.position
        )
    )    

    rollout FKIKSnaps "
FK/IK Snaps" width:160 height:400
    (
        -- FK to IK Snap
        groupBox grp1 "
FK --> IK Snap" pos:[8,8] width:144 height:144
        button SnapFKIKArmL "
Arm L" pos:[16,24] width:60 height:24
        button SnapFKIKArmR "
Arm R" pos:[16,56] width:60 height:24
        button SnapFKIKLegL "
Leg L" pos:[84,24] width:60 height:24
        button SnapFKIKLegR "
Leg R" pos:[84,56] width:60 height:24
        button SnapFKIKArmsBoth "
Both" pos:[16,88] width:60 height:24
        button SnapFKIKLegsBoth "
Both" pos:[84,88] width:60 height:24
        button SnapFKIKALL "
ALL" pos:[16,120] width:128 height:24
        on SnapFKIKArmL pressed do
        (
            SnapFKtoIK_ArmL()
        )
        on SnapFKIKArmR pressed do
        (
            SnapFKtoIK_ArmR()
        )
        on SnapFKIKLegL pressed do
        (
            SnapFKtoIK_LegL()
        )
        on SnapFKIKLegR pressed do
        (
            SnapFKtoIK_LegR()
        )
        on SnapFKIKArmsBoth pressed do
        (
            SnapFKtoIK_ArmL()
            SnapFKtoIK_ArmR()
        )
        on SnapFKIKLegsBoth pressed do
        (
            SnapFKtoIK_LegL()
            SnapFKtoIK_LegR()
        )
        on SnapFKIKALL pressed do
        (
            SnapFKtoIK_ArmL()
            SnapFKtoIK_ArmR()
            SnapFKtoIK_LegL()
            SnapFKtoIK_LegR()
        )
        -- FK to IK Snap
        groupBox grp2 "
IK--> FK Snap" pos:[10,160] width:144 height:144
        button SnapIKFKArmL "
Arm L" pos:[16,176] width:60 height:24
        button SnapIKFKArmR "
Arm R" pos:[16,208] width:60 height:24
        button SnapIKFKLegL "
Leg L" pos:[84,176] width:60 height:24
        button SnapIKFKLegR "
Leg R" pos:[84,208] width:60 height:24
        button SnapIKFKArmsBoth "
Both" pos:[16,240] width:60 height:24
        button SnapIKFKLegsBoth "
Both" pos:[84,240] width:60 height:24
        button SnapIKFKALL "
ALL" pos:[16,272] width:128 height:24
        on SnapIKFKArmL pressed do
        (
            SnapIKToFK_ArmL()
        )
        on SnapIKFKArmR pressed do
        (
            SnapIKToFK_ArmR()
        )
        on SnapIKFKLegL pressed do
        (
            SnapIKToFK_LegL()
        )
        on SnapIKFKLegR pressed do
        (
            SnapIKToFK_LegR()
        )
        on SnapIKFKArmsBoth pressed do
        (
            SnapIKToFK_ArmL()
            SnapIKToFK_ArmR()
        )
        on SnapIKFKLegsBoth pressed do
        (
            SnapIKToFK_LegL()
            SnapIKToFK_LegR()
        )
        on SnapIKFKALL pressed do
        (
            SnapIKToFK_ArmL()
            SnapIKToFK_ArmR()
            SnapIKToFK_LegL()
            SnapIKToFK_LegR()
        )
    )
)
"
OK

So there’s a ‘header’, which holds an image of our company logo and some text info, then a rollout for setting/animating the FK/IK Blend value for the entire left leg, then a 3rd rollout which is a copy of the functions to snap IK Bones to FK bones and vice versa.

How do I go about just calling the function from the Movement_ctrl object rather than redefining it and calling it from a copy in each FK bone/IK controller I currently have it on?  I’ve tried this…

on SnapIKFKArmL pressed do
        (
            
Movement_ctrl.CustomAttributes_Globals.SnapIKToFK_ArmL()
        )

...but it doesn’t work.



Christopher L. Bruce - Senior Animation - Cryptic Studios
3DSMax 2009 (SP1) 32-bit/64-bit - Windows 7 Enterprise 64-bit
Intel Core(TM)2 Quad CPU Q9550 @2.83GHz - 8.00GB RAM - GeForce 9800 GT (1GB)

Replies: 0