A DAG node that can contain a list of DAG nodes.
#include <AlGroupNode.h>
class AlGroupNode : public AlDagNode
AlGroupNode();
virtual ~AlGroupNode();
virtual AlObject* copyWrapper() const;
statusCode create();
virtual AlObjectType type() const;
AlDagNode* childNode() const;
AlDagNode* childNode(AlTM&) const;
AlGroupNode* nextInstance() const;
AlGroupNode* prevInstance() const;
statusCode nextInstanceD();
statusCode prevInstanceD();
boolean isInstanceable();
boolean isInstanceNode();
boolean isAncestorAnInstance();
statusCode addChildNode( AlDagNode* );
statusCode applyIteratorToChildren( AlIterator*, int& );
This class encapsulates the functionality for creating, manipulating and deleting a group node. A group node is a DAG node that refers to a list of child DAG nodes. It is this type of DAG node that allows the hierarchical grouping of DAG nodes.
The transformations that can be defined for a group node are inherited by each child DAG node. This means that a group node’s transformations are combined with a child node’s transformations to define a global transformation for the object that the child node refers to.
A group node’s list of child DAG nodes can be shared by more than one group node. If a group node’s list of child nodes is shared by another group node, both group nodes are considered "instanced". This can be achieved by using the AlDagNode::copyObject() method to create an instanced group node from another group node. The instanced group node is created as a sibling of the group node. There are methods for finding the next and previous instanced group node among its siblings and for determining whether a group node is an instanced node.
To create a group node, the user must call the constructor and then the create method for an AlGroupNode object. If a group node is not an instanced group node, deleting it will cause the deletion of all the child DAG nodes and the deletion of any objects the child DAG nodes refer to. Deleting an instanced group node will not cause all of its child nodes to be deleted since the list of child nodes is shared by another instanced group node.
Note on AlGroupNode::deleteObject()
If a group node is an instanced group node, then only the group node is removed from its list of siblings and is deleted. The list of child DAG nodes an instanced DAG node refers to is not deleted. If this group node is not an instanced group node (that is, none of its siblings share its list of child DAG nodes), then the group node is removed from the list of siblings it belongs to and the group node and every child node of the group node is deleted.
statusCode AlGroupNode::addChildNode( AlDagNode *child )
Adds an AlDagNode to the end of the list of child AlDagNodes. If the AlDagNode is already a child of this object, then nothing is done. Otherwise, the AlDagNode is removed from the list of siblings it belongs to and added to the end of this object’s list of children. If the AlDagNode is an AlGroupNode and it has siblings that are instanced AlGroupNodes, those instanced siblings are also made children of this object. It is illegal for the AlDagNode argument to be NULL or for it to not have had its create() method called.
statusCode AlGroupNode::applyIteratorToChildren( AlIterator* iter, int& rc )
Interface to Inverse Kinematics Handles.
#include <AlIKHandle.h>
class AlIKHandle : public AlObject , public AlAnimatable
AlIKHandle( void );
virtual ~AlIKHandle();
virtual statusCode deleteObject();
virtual AlObject* copyWrapper() const;
virtual AlObjectType type() const;
statusCode createSingle( AlJoint*, AlJoint* );
statusCode createMulti( AlJoint*, AlJoint*,
AlIKHandleGoalType );
statusCode createSpline (AlJoint*, AlJoint*, AlCurveNode*, AlIKHandle*);
statusCode createSpline (AlJoint*, AlJoint*, AlCurveNode*);
boolean on( void ) const;
AlIKHandleSolverType solverType( void ) const;
AlIKHandleGoalType goalType( void ) const;
double weight( void ) const;
AlIKHandleRotationOrder rotationOrder( void ) const;
boolean worldOrientation( void ) const;
statusCode restRotation( double[3] ) const;
AlJoint* root( void ) const;
AlJoint* endEffector( void ) const;
AlDagNode* rootNode( void ) const;
AlDagNode* endEffectorNode( void ) const;
AlIKHandlePositionType positionType( void ) const;
AlIKHandleTwistType twistType( void ) const;
AlCurveNode* curveNode( void ) const;
boolean oneJointHandle( void ) const;
boolean touchRootHandle( void ) const;
AlIKHandlePositionType splineChainPosition( double* ) const;
AlIKHandleTwistType splineChainTwist( double* ) const;
double splineChainRoll( void ) const;
statusCode setOn( boolean );
statusCode setGoalType( AlIKHandleGoalType );
statusCode setWeight( double );
statusCode setRotationOrder( AlIKHandleRotationOrder );
statusCode setWorldOrientation( boolean );
statusCode setRestRotation( const double[3] );
statusCode assumeRestRotation( void );
statusCode setPositionType( AlIKHandlePositionType );
statusCode setTwistType ( AlIKHandleTwistType );
AlIKHandleNode* handleNode( void ) const;
A skeleton is a collection of joint DAG nodes that have no particularly special behavior until IK handles are applied to them. In order to use inverse kinematics in Alias, you must create IK handles that define paths along skeletons to be constrained by IK.
An IK handle is defined by two joints. The end effector is the point on the skeleton that is free to move, and the root is the anchor point on the skeleton. When the end effector is moved, the rotations on all joints leading up to the root are constrained to provide an IK solution.
The IK handle also specifies the solver that will be used. There are two kinds of IK solvers in Alias:
Single-chain IK handles are always position handles - the rotations of the joints above the end-effector, and below or at the root, are transformed to meet the position of the end-effector.
Multi-solver IK handles can be position or orientation goals or both. An orientation goal will try to match the orientation of the bone immediately above the end-effector to the orientation of the IK handle.
Multi-solver IK handles also have weights. When several multi-solver IK handles overlap, the weights on these handles are used to determine the relative effect each solution has on the overall rotation of the joints in the affected skeleton.
statusCode AlIKHandle::createSingle( AlJoint* root, AlJoint* end )
statusCode AlIKHandle::createMulti(AlJoint* root, AlJoint* end, AlIKHandleGoalType goal )
Builds a new multi-IK handle, given the root and end effector nodes and the goal type of the handle. Returns statusCode, indicating whether the IK handle was successfully constructed.
statusCode AlIKHandle::createSpline(AlJoint* root, AlJoint* end, AlCurveNode* curve, AlIKHandle*& rHandle)
Builds a pair of new spline IK handles: master spline handle and its root spline handle. You must specify the root, end joints and the curve to be matched with. The rHandle must be a NULL AlIKHandle pointer which is to be set with an associated one-joint spline handle for 'this' handle.
A root spline handle EQUALS a one-joint handle. It can only be created when a master spline handle is created. (That is, it cannot be created separately.)
A one-joint spline handle can be set to different position types with AlIKHandlePositionType.
A master spline handle can be set to different twist types with AlIKHandleTwistType.
This function creates spline handles in default position type (kParameter) and twist type (kTwist_Linear). They can be changed later by setPositionType() and setTwistType().
<root - the root joint of the handle
<end - the end joint of the handle
<curve - the target of the handle
<rHandle - a reference for an empty AlIKHandle pointer
statusCode AlIKHandle::createSpline( AlJoint* root, AlJoint* end, AlCurveNode* curve)
Builds a master spline handle without root spline handle. Requires the root and end joints, also the curve to be matched with.
This function creates a spline handle in default position type (kParameter) and twist type (kTwist_Linear). They can be changed later by setPositionType() and setTwistType().