"MAXScript Script Controller Exception"
! -- Runtime error: Illegal self - reference in controller script
and other dialog after that with button Evaluete and Close:
dependsOn $'char_handLCTRL' $'char_elbowLCTRL';
-- Wrap this in a cA.get to make sure we have CA's now.
-- Otherwise on a load or merge, 3dsMAX might try to execute
-- this before the CA's get loaded in! This way it waits until
-- everything is fully loaded before -really- calculating.
myD = custAttributes.get $'char_handLCTRL'.Attribute_Holder 1;
if (myD != undefined) then
-- This script takes two helpers on the wrist to get a
-- local hand "Y" vector, and then unrotates it
-- by the rotation on the lower arm.
-- This way the hand vector is now aligned to the
-- coordinate space of the lower arm.
-- At that point I can get what would be the rotation around
-- the lowerArms X axis using the Y axis as reference
-- (using Y means Y is still correct even if it rotates
-- up/down on the Y axis causing the Z to move)
-- Because we've rotated the hand's world space rotation
-- back by the lower arm readers rotation, this all
-- works in the coordinates of the lower arm, thereby
-- giving us proper values, even though the hand
-- is not in the hierarchy.
-- Using simple trig (SOH CAH TOA) we can get the angle
-- of the twist.
-- Get rotation in world of lower arm
rotStart = $'char_lowArmReaderLINT'.rotation as eulerangles;
-- where is our wrist axis at?
posEnd = $'char_wristReaderLINT'.position;
-- Get our Y axis for the wrist in world
endY = $'char_wristReaderYLINT'.position - posEnd;
-- Normalize our wrist axis
endY = normalize endY;
-- Everything is now normalized for the wrist, so
-- all we have to do now is unrotate by the upperArm angles
-- Make rotation matrices
rotMatX = rotateXmatrix rotStart.x;
rotMatY = rotateYmatrix rotStart.y;
rotMatZ = rotateZmatrix rotStart.z;
rotMat = rotMatX * rotMatY * rotMatZ;
-- Now rotate our Y axis Vector by each x y z of the lowerArm we got
endY = endY * rotMat;
--format "--DEBUG: x=% y=% z=%\n" endX endY endZ;
-- Max atan always in degrees...yay
-- X is axis down bone, Z is up, but will probably move a lot, so look at one back/sideways = Y
autoTwistX = 0.0;
-- First make sure we don't have a divide by 0 error...
if (endY.z != 0) then
autoTwistX = atan (endY.y / endY.z) +90;
-- Then if we have crossed above the Y=0 line, we will have a 180 flip, so handle that...
if (endY.z > 0) then
autoTwistX -= 180;
autoTwistX = -1*autoTwistX; -- Do this just so things rotate the right way
-- Now add in any manual override the user did using the handCTRL attribute.
autoTwistX *= $'char_handLCTRL'.Attribute_Holder.autoTwistPct / 100.0;
autoTwistX += $'char_handLCTRL'.Attribute_Holder.extraTwist;
-- End of autoTwist script