In the expression, first we need to find the local rotation values of the helper, that's because the controllers need values in local mode (local values in max are respect to the parents). We can do that using the transform values of this helper and its parent.
The way that a 3d software inherits the transform values from an object to its children is to multiply the parent's transform matrix by its children local transform matrix. Having in mind this, we may find the child's local TM by doing the inverse process. In math the inverse process of multiply two matrices isn't divide them, it's a special process called "Inverse", max has a maxScript function for this.
So, the expression goes as follows: helper's transform * inverse parent's transform
From this resulting transform we need to extract the rotation value: (helper's transform * inverse parent's transform).rotation
Then we need to convert this rotation from Quaternion values to Euler angles values in order to be able to get its Z rotation value. To don't make the code line too long, i assign this rotation to a variable and continue in the next line.
So, it goes as follows:
rot=(helper's transform * inverse parent's transform).rotation
(rot as eulerangles).z
For the helper we're going to create a variable called helper_lookAt assign the Helper_lookAt_Turret as node. We can get the parent node as an object's property. The expression finally goes as below.
rot=(helper_lookAt.transform * inverse helper_lookAt.parent.transform).rotation
degtorad (rot as eulerangles).z
degtorad is a need because the controller handles rotation values in radians.
The Cannon_base will need all the rotation values from its helper_lookAt. We cannot assign the lookAt constraint directly to the cannon, because we won’t be able to make manual adjustment to it. We could assign an extra Euler XYZ controller in the rotation list for manual adjustments, but it will have unexpected behaviours when we rotate it (this problem happens in rotation controllers only, in position controllers it doesn't happen, and in the turret case, it doesn't happen either because we're using only one axis there).
But there's a way to make it possible, we're going to link the cannon to the helper. Select the cannon_base and the Control_cannon_base objects and link them to the Helper_lookAt_cannon, then select the cannon_base, align it to the Helper_lookAt_cannon (orientation), now it has a wrong orientation, so rotate it 90 degrees over its local y-axis.
Doing this the cannon will inherit the helper's orientation, and also we'll be able to make manual adjustments.
You can move the Control_Target to check this out!
|