[MaxScript] assigning constraints between matching skeletons

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 :frowning:
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 :slight_smile:
</rant>

Your code is right, nothing to change there.

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…)

There are multiple constraint controller types but they only have examples in a few cases it seems. Also, not very in depth.
http://docs.autodesk.com/3DSMAX/14/ENU/MAXScript%20Help%202012//index.html?url=files/GUID-4F0CBB0A-28B1-4182-8164-2BB730C86D0-1485.htm,topicNumber=d28e539273

Assigning a controller.


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

Most of these methods are common between the constraint controllers however each one does have their own specific methods.
Constraint Types
http://docs.autodesk.com/3DSMAX/14/ENU/MAXScript%20Help%202012//files/GUID-D4188472-38CD-4E7C-9D69-155A97A0E15-1480.htm