A node transform contains six degrees of freedom. Three are translational (sliding) and three are rotational. In the API, they have enum names, IKSys::TransX
to IKSys::TransZ
and IKSys::RotX
to IKSys::RotZ
. When the context implies rotational or translational, IKSys::DofX
to IKSys::DofZ
are used.
A degree of freedom can be active or inactive. An inactive degree of freedom is not to be used by IK. In other words, only active degrees of freedom are degrees of freedom as far as IK is concerned. The methods DofActive()
, ActiveTrans()
, ActiveRot()
, and ActiveDofs()
are provided to determine which degrees of freedom are active and inactive. The first query answers whether a specific (translational / rotational) axis is active. The following three return a set of DOFs, which is defined in the same file. The set returned by ActiveTrans()
and ActiveRot()
is to be tested by IKSys::DofX
to IKSys::DofZ
, and the set returned by ActiveDofs()
is to be tested by IKSys::TransX
to IKSys::RotZ
.
A node transformation can be conceptually viewed as consisting of two joints, sliding joint (translational degrees of freedom) and rotational joint. The enum type, IKSys::JointType
, contains two enums: IKSys::SlidingJoint
and IKSys::RotationalJoint
. An IK chain starts at the rotational joint of the Start Joint and ends at the sliding joint of the End Joint. Two IK chains covering the same joint, are considered overlapping IK chains.
Let's call a node an IK chain node if its TM controller supports interface IIKChainControl
, i.e., node
->GetTMController()->GetInterface
(I_IKChainControl) != NULL
. The following query returns a list of IK chain nodes; InodeTab
IKChains(JointType
) const
The parameter that decides whether an individual degree of freedom is (IK) active is not animatable. There is an animatable variable of IK chain that decides whether the goal defined in the IK chain actually affects the joints it covers at a specific time, this can be queried using IKBound()
.
A degree of freedom can be bound to a limited range. The lower bound and upper bound can be set separately. At each end, there are a boolean parameter, Limited, and a float number that sets the limit. The limit is effective only if the boolean parameter, Limited, is true. Following queries concern the joint limits. When a Point2
is returned, it is ordered as the lower limit followed by the upper limit. When a Point3
is returned, the order is X, Y, and Z. For example, TransLowerLimits()
returns lower limits of TransX
, TransY
, and TransZ
, respectively.
Some solver may start off the solution process with joint angles being set to special values, these are called preferred angles. PrefPosition()
and PrefRotation()
return preferred angles of the translation and rotation joints, respectively. The APIs allows them to be animatable. However, in 3ds Max 4, they are constant with regard to animation time. The methods SetPrefTrans()
, SetPrefRot()
, and SetPrefTR()
set their values at a specific time.
TransValue()
and RotValue()
will query joint angles of sliding and rotational joints, respectively, at a specific time. If the user supplies non-null pointer to a validity interval, the validity interval will be updated.
Their values can be assigned using AssignTrans()
and AssignRot()
. The methods AssignActiveTrans()
and AssignActiveRot()
will skip those degrees of freedom that are not active. These same two methods allow active DOFs to be given as the first argument of type DofSet
, while having the new values supplied as float array whose size should be the same as the DofSet [DofSet::Count()
]. The order in the array is: DofZ
if the DofSet includes DofZ
, DofY
if the DofSet includes it, and followed by DofX
if it is included in the DofSet
. IK controllers are designed to be controlled by the IK goals (through the internal IK system). Therefore, their values are not to be set as independent variables are. These assignment methods just assign new values to the respective variables and that's all. They do not adjust the validity interval, this is done through the methods SetTransValid()
, SetRotValid()
and SetTRValid()
.The last method sets the validity intervals for translation and rotation values to the same interval.
The Forward Kinematics sub-controller and the pointer to the node that holds this controller as its TM controller can be obtained using Control
* FKSubController() and INode
* GetNode(). Note that the IK controller is not designed to be instanced. It is expected to have a unique node.