Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions

RotationValue Class Reference

Search for all occurrences

Detailed Description

This class is only available in release 5 or later.



This class is to hold different representations of the rotation. In particular, it holds rotation value as represented by Euler angles or quaternion. Different types of rotation controllers may use different representations. To avoid losing information due to converting from one representation to another, we can use RotationValue to hold the result.

For example, the Skin pose feature reads rotation of a node from the rotation controller and stores the result in RotationValue (c.f. maxsdk/include/iSkinPose.h).

// Assuming node is a valid pointer to INode.

ISkinPose* skpose = ISkinPose::GetISkinPose(*node);

// skpose should not be null for Max version 5.0 or later.

RotationValue rv = skpose->SkinRot();

It is guaranteed that rv keeps the original representation of the controller.

Being asked of Euler angles, RotationValue will return 3 float numbers in the format of Point3. There must be an association between numbers and axes.

There are two classes of Euler angle types. In one class, the rotation axes are not repeated (non-repetitive). They are enum's from kXYZ to kZYX. In the other class, one of the rotation axes is repeated (repetitive). They are enum's from kXYX to kZXZ. For convenience, enum kReptd is used to denote the starting one: kRept == kXYX.

For non-repetitive Euler angles, there are two well-defined methods to associate three ordered angles, to three axes.

First, we can associate angles with x-, y-, and z-, axes, respectively. The first angle, for example, is always associated with the x-axis, no matter where it appears in the Euler order. Suppose

Point3 a(0.1, 0.2, 0.3)

then a.x (==0.1), a.y(==0.2), a.z (==0.3), are the angles of the x-axis, y-axis, and z-axis, respectively, no matter whether the order (type) of the Euler angles is kXYZ or kZXY.

Let's call this way of association by axis (name).

Second, we can associate them by position: the first angle, from left, is always associated with the first axis in the Euler angle order. For examples, the first angle is applied to the x-axis for kXYZ and kXZY, but to the y-axis for kYXZ and kYZX, etc. Suppose a is a Point3, a[0] (==a.x), a[1] (==a.y), a[2] (==a.z), are the angles of the z-axis, x-axis, and y-axis, respectively, for Euler type kZXY.

Let's call this way of association by order.

For repetitive Euler type, the association by axis is ambiguous because one axis may appear twice in the Euler axes. In this case, "by order" is well defined.

This class uses the association of by axis for non-repetitive types and by order for repetitive type. Suppose,

Point3 a = rv.Euler(RotationValue::kZXZ) // repetitive Euler type

Then, a[0] and a[2] are both applied to the Z axis, but a[0] corresponds to the first z-axis from left, a[2] corresponds to the second z-axis (third axis) from left, and a[1] corresponds to the x-axis.

#include <euler.h>

Inheritance diagram for RotationValue:
Inheritance graph
[legend]

List of all members.

Public Types

enum   EulerType {
  kXYZ = EULERTYPE_XYZ, kXZY, kYZX, kYXZ,
  kZXY, kZYX, kXYX, kYZY,
  kZXZ
}
enum   { kReptd = kXYX, kQuat = 100 }

Public Member Functions

void  Set (const Point3 &a, EulerType et)
void  Set (const Quat &q)
  RotationValue ()
  RotationValue (const Point3 &a, EulerType et)
  RotationValue (const Quat &q)
  RotationValue (const RotationValue &src)
Point3  Euler (EulerType et=kXYZ) const
  operator Quat () const
GEOMEXPORT  operator Matrix3 () const
GEOMEXPORT void  PreApplyTo (Matrix3 &m) const
GEOMEXPORT void  PostApplyTo (Matrix3 &m) const
GEOMEXPORT void  PostRotate (const AngAxis &aa)
int  NativeRep () const
Quat  GetNative () const

Static Public Member Functions

static bool  IsEuler (int rep)
static bool  IsRepetitive (int rep)
static bool  IsQuat (int rep)

Static Public Attributes

static const int  kAxisToOrdinal [kReptd][3]
static const int  kOrdinalToAxis [kZXZ+1][3]

Protected Member Functions

GEOMEXPORT Point3  ToEulerAngles (EulerType et) const
GEOMEXPORT Quat  ToQuat () const

Member Enumeration Documentation

enum EulerType
anonymous enum

Constructor & Destructor Documentation

RotationValue ( ) [inline]
Remarks:
Constructor
: mQ(), mRep(kXYZ) {}
RotationValue ( const Point3 a,
EulerType  et 
) [inline]
Remarks:
Constructor
{ Set(a, et); }
RotationValue ( const Quat q ) [inline]
Remarks:
K Prototype

Constructor.
{ Set(q); }
RotationValue ( const RotationValue src ) [inline]
Remarks:
Copy constructor.
: mQ(src.mQ), mRep(src.mRep) {}

Member Function Documentation

static bool IsEuler ( int  rep ) [inline, static]
Remarks:
Conveniency (static) method to test whether an integer corresponds to an enum of rotation representations used in RotationValue of type Euler angles

{ return (kXYZ <= rep && rep <= kZXZ); }
static bool IsRepetitive ( int  rep ) [inline, static]
Remarks:
Conveniency (static) method to test whether in cases where a call to IsEuler(int rep) is made, and the return value is of type Euler angles, this method call returns whether it has repetitive axes (such as XYX).

                                      {
        // Pre-cond: IsEuler(rep)
        return rep >= kReptd; }
static bool IsQuat ( int  rep ) [inline, static]
Remarks:
Conveniency (static) method to test whether an integer corresponds to an enum of rotation representations used in RotationValue of type Quaternion.

{ return rep == kQuat; }
void Set ( const Point3 a,
EulerType  et 
) [inline]
Remarks:
Set an object of RotationValue to an Euler angle representation. Angles are assumed in radians. To set to Euler angles of x, y, z, of order XYZ, do, for example:

RotationValue a;

a.Set(Point3(x, y, z), RotationValue::kXYZ);

                                            {
        mQ.x = a.x;
        mQ.y = a.y;
        mQ.z = a.z;
        mRep = (short)et; }
void Set ( const Quat q ) [inline]
Remarks:
Set an object of RotationValue to a quaternion representation.

                            {
        mQ = q;
        mRep = kQuat; }
Point3 Euler ( EulerType  et = kXYZ ) const [inline]
Remarks:
Used to get the rotation in specific representation. Suppose rv is a RotationValue, to get it in terms of Euler angles of order XYZ:

rv.Euler();

in order ZXY:

rv.Euler(RotationValue::kZXY);

or, to get it in quaternion:

(Quat)rv;

to get it in matrix form:

(Matrix3)rv
                                           {
        if (et == mRep) return Point3(mQ.x, mQ.y, mQ.z);
        else return ToEulerAngles(et); }
operator Quat ( ) const [inline]
Remarks:
Please see method Euler() for fuller explanation.
                          {
        if (mRep == kQuat) return mQ;
        else return ToQuat(); }
GEOMEXPORT operator Matrix3 ( ) const
Remarks:
Please see method Euler() for fuller explanation.
GEOMEXPORT void PreApplyTo ( Matrix3 m ) const
Remarks:
Given a matrix, m, we can apply the rotation, rv, of RotationValue from left side (PreApplyTo)

rv.PreApplyTo(m) == ((Matrix3)rv) * m
GEOMEXPORT void PostApplyTo ( Matrix3 m ) const
Remarks:
Given a matrix, m, we can apply the rotation, rv, of RotationValue from right side (PoseApplyTo)

rv.PoseApplyTo(m) == m * (Matrix3)rv)
GEOMEXPORT void PostRotate ( const AngAxis aa )
Remarks:
To apply a rotation, aa, as represented as AngAxis to a RotationValue, rv, from the right side,

rv.PostRotate(aa)

The internal representation of rv after applying to it will not be change. Mathematically,

(Matrix3)rv.PostRotate(aa) == ((Matrix3)rv) * MatrixOf(aa)

If rv is in Euler angles, this method will try to keep the Euler angles from jumping at the borders of (+/-)180 degrees.
int NativeRep ( ) const [inline]
Remarks:
Used to get the internal representation and returns the representation type. If it is a Euler angle type, the first three numbers of the Quat returned from GetNative() are to be interpreted as Euler angles.
{ return mRep; }
Quat GetNative ( ) const [inline]
Remarks:
Used to get the internal representation and returns the actual float numbers.
{ return mQ; }
GEOMEXPORT Point3 ToEulerAngles ( EulerType  et ) const [protected]
GEOMEXPORT Quat ToQuat ( ) const [protected]

Member Data Documentation

const int kAxisToOrdinal[kReptd][3] [static]
const int kOrdinalToAxis[kZXZ+1][3] [static]

RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue
RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue RotationValue