Keeping the control object in place

a problem which seems to come up frequently when I rig a control object to a bone or IK handle
is keeping the control object in place relative to the bone, while avoiding any dependency loop.

for FK it’s usually not a problem: the control object is positioned at exactly the bone pivot and does not need to move.

but for ik controls, aim / lookat constraints, or other cases where the control object translates and the bone responds,
keeping the control object in a sensible position can be a challenge. its position must relate to the bone it drives,
but it cannot be driven directly by the bone, or we have a dependency loop.

this has to be a pretty common phenomenon. I am wondering if there are equally common solutions.

here’s a quick example of what I’m talking about


I’m not seeking a specific solution to the above, but a more general approach to constraining the position of a CTRL
in relation to the bone it drives , yet without dependency loops or loss of the ability to translate Altogether.

You’d need to be able to interrupt the processing of the scene graph to reliably do what you want; the dependency loop is the expression of a basic logical problem: if X tells Y where to go, Y can’t also tell X at the same time. At some level you’d need to know if X or Y were in charge at a given moment, and then evaluate accordingly.

This is not trivial to do with common rigging tools, even though it’s easy to see how the structure would work in theory:


   if (user_is_driving):
       X.rotation = get_ik(Y)
  else:
       Y.position = [1,0,0] * X.local_matrix

but neither max nor maya gives you a basic tool to accomplish this. It’s also complicated by animation controls in general: would you want your control to snap to end of the bone if the animation curve wanted it to be somewhere else?

Some folks like to snap their IK or other controls to the target bones right after the user moves the control; that ensures that the controls are on the right place visually but doesn’t change the logical structure. I often find when animating that I want to hyperextend or otherwise exceed the reach of the bones, however – the position of the IK target is information I actually want a lot of the time.

Other common bandaids:

  • Add a visual connection from the bone chain to the control - for example, drawing a line from the end of the bone to the control so you don’t get confused by floating controls that have no obvious connection to the model
  • You can add a selection proxy object that is just parented to the end of the chain you’re controlling, with a callback that just automatically selects the real IK control when you try to select the proxy. That helps with ergonomics, although again it doesn’t change the logical issues.

Hello,

I’m not entirely sure if I understand your problem, particularly in the FK case (why would you want to translate your controls?), but for the LookAt and IK cases, you can use a simple script hack to do achieve what I think you’re looking for. For the LookAt case, create a new point and assign a Scale Script controller and assign the script:


if distance bone point != boneLen then
(
   point.pos = (normalize (point.pos - bone.pos))*boneLen + bone.pos
)

[1, 1, 1]

For the IK case it’s no different from the LookAt case other than the if-statement is “if distance bone point > boneLen then”

I’ve uploaded the file to HotFile: https://hotfile.com/dl/256131318/b92a893/How_Scene2013.zip.html

Thanks,
-Harry

hazmondo, that’s sneaky.

So the “dummy” point scale script actually does nothing to the dummy point itself,
but in the process of executing it manipulates the values of the actual ctrl object.

It never occurred to me that a Max script controller can be used that way.
That opens some doors for me for sure.

big thanks!

It’s a classic trick ;), I first saw it being used to change the colour of bones based on whether they were squashed or stretched. You probably already know but you need the last line to make sure that the last thing that is evaluated is the point3 value which is passed to the scale value.

But you’re right, this hack open a lot of doors and can be used to get round any dependency loop, but I also I use it to do name independent IK-FK snapping.

-Harry

[edit] a late thread bump.
after some monkeying and advice form my CGTalk thread


	fn _radiusCtrlLimit theCtrl theBone=(
		/*
			theCtrl = object you wish to constrain to a radius
			theBone = a bone with w/ rotation lookat constrained to theCtrl, whose length will determine the radius
				--Dennis T's solution from cgtalk
				--http://forums.cgsociety.org/newreply.php?do=newreply&noquote=1&p=7749357
		*/

		p = theCtrl.pos.controller = position_list()
		p.weight[1] = 0
		sc = p.available.controller = position_script()
		sc.addConstant "radius" theBone.length	
		sc.addobject "pos" p[1]--pass  theCtrl.pos.controller[1] (a position_XYZ controller) to the script
		sc.setexpression "(normalize pos.value)*radius"
	),

Instead of using a scale script on a third object, you can utilize the controller list on the ctrl object to pass that objects XYZ pos to itself.