I previously posted about my custom maya node that does some 'pose' based calculations, for use in driving deformations and what not.
I recently found myself wishing I had it to use in 3ds Max. So, I wrote one.
I recently found myself wishing I had it to use in 3ds Max. So, I wrote one.
Below I'm just driving three point and orient constraint weights via the output of the node.
This is generally a bit simpler than my Maya version. It just defines two radius' and remaps the angle, between two matrix axis vectors, from 0-1 (or reverse). The Maya node allowed a definition of an ellipse shape for both min and max 'areas', so I could elongate the shape over one axis more than another. However I'm getting good results from just the circular shapes, so I'm happy for now.
To achieve this I wrote a Scripted Manipulator Plugin to draw the shapes, and to store the needed parameters for node associations, to control the shape and store the output. Then, inside the Scripted plugin, I'm adding a Scripted Controller, on creation, to the Output parameter. The scripted controller is actually pretty simple:
To achieve this I wrote a Scripted Manipulator Plugin to draw the shapes, and to store the needed parameters for node associations, to control the shape and store the output. Then, inside the Scripted plugin, I'm adding a Scripted Controller, on creation, to the Output parameter. The scripted controller is actually pretty simple:
/* Float Scripted Controller code that handles 'pose space' calculations. It is assigned to the output of our custom node The Float Script controller has two node variables assigned to it: srcObj : this is essentially 'this' object... the object this controller is assigned to targObj : The Target node that we are comparing axese to */ -- the return value... init with invalid value local theOutput = -1.0; -- make sure the source node is valid if srcObj != undefined then ( -- make sure the target node is valid if targObj != undefined then ( -- this is the angle variable that will be converted to a valid 0-1 output local theAngle = 0.0; -- Grab this nodes z axis... we always use the z axis for the source (this) node local srcAxis = srcObj.transform.row3 -- Here we are getting some 'settings' from properties on the target node... -- ..here we grab the target axis of the target node based on the drop down ui/property user specification local targAxis = [0,0,0] if srcObj.TargetAxis == 1 then targAxis = targObj.transform.row1; if srcObj.TargetAxis == 2 then targAxis = targObj.transform.row2; if srcObj.TargetAxis == 3 then targAxis = targObj.transform.row3; -- calculate the angle between the two axes.. theAngle = (acos (dot targAxis srcAxis )); -- again grab more settings from the source node. Here we grab the min and max -- angle settings local minimum = srcObj.innerRadius; local maximum = srcObj.outerRadius; -- Here we are calculating the output based on another node property setting. if srcObj.ReverseOutput == false then( -- default calculates output as a 0-1 value.. 'inside' the specified cone if theAngle < minimum then theOutput = 1.0; else if theAngle > maximum then theOutput = 0.0; else theOutput = 1 + -((theAngle - minimum) / (maximum - minimum)) ; )else( -- Reverse output is a 0-1... outside the cone.. if theAngle < minimum then theOutput = 0.0; else if theAngle > maximum then theOutput = 1.0; else theOutput = ((theAngle - minimum) / (maximum - minimum)) ; ) ) ) -- return / set the controller value theOutput ;
It all seems pretty fast, so that's a plus. I was dubious of the speed needs for something like this using Maxscript and Scripted Controllers, but it seems decent.