Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

Getting local position of CAT rig object ($.pos)

Getting local position of CAT rig object ($.pos)

Anonymous
Not applicable
1,506 Views
5 Replies
Message 1 of 6

Getting local position of CAT rig object ($.pos)

Anonymous
Not applicable

Hello,

 

I'm a bit new to Max and Maxscript, and am more used to Maya, so I hope I get the terminology right. I have received a rig created with the CAT system, and am trying to script some functions to help in animation. Right now, I want to create a "tween" function - to create an interpolated pose between two neighbouring (stepped-tangent) keyframes. 

 

My problem boils down, I believe, to this: with most objects (a newly created cube, for instance), calling 

 

>> $.position in coordsys parent 

gives you the local position of $. However, with CAT objects, call $.pos returns an error message:

 

>> Unknown property: "position" in $...

 

I notice, however, that I can get the world space position of CAT objects (and others) by calling

 

>> $.transform.position

 

So I can get it to work - but only in world space. My current approach is roughly like the below script, which moves an object to a position between previous and next positions. This, of course, runs into problems if the object is parented to something else - the in between position is in terms of absolute world position.  

 

 

 

previousKeyTime = trackbar.getPreviousKeyTime()
nextKeyTime = trackbar.getNextKeyTime()

previousPosition = at time previousKeyTime $.transform.position 
nextPosition = at time nextKeyTime $.transform.position

deltaPosition = (nextPosition - previousPosition ) 

move $ (deltaPosition  * 0.5)

 

 

I must admit I am royally confused my Max's animation controller system. I've gone over the helpdocs (Node Common Properties, Operators, and MethodsAnimation Controllers again and again, but still can't figure it out - CAT seems to operate by its own rules. If anyone can suggest a good resource to learn how this all works, I'd be very thankful.

 

0 Likes
1,507 Views
5 Replies
Replies (5)
Message 2 of 6

ads_royje
Alumni
Alumni

Hi @Anonymous,

 

you have hit the most "special" case in animation in Max: CAT.

 

In general in Max, you can query local (to parent) transform using either what you do :

in coordsys #parent $.pos (or $.position)

The $.position will give the end results of layers of controllers (if any)

Talking to controller directly would always give a local prs value.

either will give a local value:

$.pos.controller.value
$.transform.controller.position.controller.value

 

This will work for most objects in Max that uses the default PRS() & Position XYZ() controllers.

Unless objects have a hierarchy of animation controllers, like using Layers (List controller) for instance.

In that case, to access the local value will require the proper controller path when requiring local transform by layer.
Using the In Coordsys #parent $.position will still give a local (to parent) value.

 

Using the In Coordsys can be very useful and powerful, as Max can return transforms from any space coordinate.
#local, #parent, #world and even $<otherobject> (in CoordSys $<otherobject>).

 

Now, in CAT. By default CAT objects don't have a "value". CAT works with Layers and as long as there are no animation Layers, the transforms are not accessible.

To be able to do so, CAT must have at least an Abs layer (Absolute Layer).

 

You might be already aware, just in case, using Max's Listener (Macro Recorder: Enabled) can help a lot to get the proper maxscript commands.

In case of CAT you would get :

$.transform.controller.LayerTrans.Animation_Layer.position

 

I hope this can help! 🙂

 

 

0 Likes
Message 3 of 6

ads_royje
Alumni
Alumni

I should specify that without an Animation Layer in CAT, to access the Rigging values, using the LayerTrans

$.transform.controller.LayerTrans.position

0 Likes
Message 4 of 6

Anonymous
Not applicable

Hi Jean-Thierry,

 

Thank you for your response! However... I suppose I'm not quite sure how to navigate to the data I need within the layers. The CAT rig does have an active layer, but I don't understand how to get local position data out of that? All the variations of $.pos, $.transform.pos, etc, that I have tried have wound up with an error or world position data. 

 

 

My latest effort consisted of trying to recreate the CAT hierarchy with "normal" Point objects. The following was an attempt to figure out the transform parent CAT object by trying to filter the original object's CAT address... but it turns out that only worked in certain cases. It's very much a workaround attempt, though if I can figure out how to reliably find the parent CAT object - I realize the CATParent is usually the main control object, I'm talking about the object currently influencing the relevant object's transformations - it would work well enough for my purposes.

 

CATObjAddress = obj[3].address
CATparentObj = obj[3].CATparent
splitAddress = filterString CATObjAddress "."
lengthLocalObjAddressName = 1 + splitAddress[splitAddress.count - 1].count + 1 + splitAddress[splitAddress.count].count
parentObjAddress = substring CATObjAddress 1 (CATObjAddress.count - lengthLocalObjAddressName)
parentObj = CATparentObj.GetBoneByAddress parentObjAddress		

 

0 Likes
Message 5 of 6

ads_royje
Alumni
Alumni

Querying $.pos or = $.position or $.transform.position (for any controllers in Max) will always return in World values.

 

 

CAT is a special beast indeed and is quite hard to get the local transform consistently via CAT controllers, due to the various conditions that it may have as it is always layers:/

 

Would it work for you to use a generic math calculation ? :

obj matrix (in world) multiplied by the inverse of its parent matrix = local matrix

For instance with any CAT objects, this will work in all cases (unless child of World) :

($.transform * inverse($.parent.transform)).position = position in parent space, or local.

 

So for all CAT bones, get local Position :

if $.parent == undefined then

(

$.transform.position

)

else

(

($.transform * inverse($.parent.transform)).position 

)

 

 

Message 6 of 6

Anonymous
Not applicable

Oh, that looks very promising! I'll look into it a bit later and let you know how it goes, thank you for the tip!

0 Likes