I’m working on a rigging system where one skeleton will be driven by another skeleton using orient constraints.
I’m used to Maya where it would be as simple as
orientConstraint <master> <slave>
I’m wrapping my brain around the Max script way , where (apparently) every type of controller has to first be explicitly instantiated before it can be assigned to anything.
I came up with this script to loop over the master bones and constrain the matching slave bones:
/*
given 2 skeletons:
'master' bones , systematically named and prefixed "master_*"
matching 'slave' bones, identincally named , but prefixed "Slave_*"
finds each "master_*" bone,
creates orient constraint
ads master as target
assigns orient control to paired slave bone.
*/
masterBones=$master_*
for master in masterbones do
(
slaveName= substituteString master.name "master_" "slave_"
slave= getNodeByName slaveName
orientCtrl =orientation_constraint()
orientCtrl.appendTarget master 100.0
slave.rotation.controller=orientCtrl
)
it seems to work on a simple test rig.
I’m posting just for an ‘idiot check’, being new to the max script way of doing things I want to be sure I’m not making any obvious errors.
My one concern is how I would access these controls in a script after creation?
<rant>
Another thing I got used to in Maya was each command definition being followed by clear examples.
The hilighted 3 lines, where the actual constraining happens, were adapted from a CGtalk post,
because i just couldn’t make usable code based on the max script help pages, nor could I find an example of constraints in the tutorials.
I’m a very example-driven learner and there seems to be a lack of “here’s what using this code actually looks like” examples in MaxScript help
If I am missing the secret gold mine of practical max script examples , - or at least a very high level overview of scripting controllers - please clue me in
</rant>
And yes, Maxscript documentation is somewhat lacking. I feel your pain, I also learn by examples instead of reading babbling descriptions. In the end you have to do a lot of trial and error sometimes. show (same as showproperties), showmethods and showinterfaces are very helpful for finding stuff. A couple of times there are things that are not even mentioned in the Maxscript documentation (it’s a very few, but there are some).
Here’s another way of adding a constraint, if you want to add more targets:
fn addOrientationConstraint boneToOrient targetList =
(
boneToOrient.rotation.controller = orientation_constraint()
boneToOrient.rotation.controller.relative = True
boneToOrient.rotation.controller.appendTarget targetList[1] 100.0
if targetList.count >= 2 then
(
for i=2 to targetList.count do
(
boneToOrient.rotation.controller.appendTarget targetList[i] 0.0
)
)
)
This is useful if you want to have an IK/FK rig driving a base skeleton. You add both IK and FK bones to the target list of the base bone and wire the constraint weight to a controller somewhere. (And wiring with Maxscript can be painful…)
-- Assign a position constraint to an object's position controller
pos_controller = obj.position.controller = Position_Constraint()
Now that you have a constraints controller assigned to an object you have to access the constraints interface.
I usually assign this to another variable because you may need to make multiple calls to it.
-- Assign the controller constraints interface to a variable
pos_constraints = pos_controller.constraints
-- Specify whether the constraint maintains its relative offset ( doesnt snap to the position of the calculated constraint )
pos_constraints.relative = True
Once you have the constraints assigned you can begin accessing or modifying the objects and values.
-- Add objects and an absolute value to constrain
pos_constraints.appendTarget targetA_obj 70.0
pos_constraints.appendTarget targetB_obj 30.0
-- Query number of target nodes
pos_constraints.getNumTargets( )
> 2
-- Query the node of target index 2
pos_constraints.getNode 2
> $targetB_obj
-- Query weight value on node index 2
pos_constraints.getWeight 2
> 30.0
-- Set weight value on node index 1
pos_constraints.setWeight 1 80.0
-- Remove target node index 1
pos_constraints.deleteTarget 1