CMS 3D CMS Logo

Ig3DRotationControl Class Reference

#include <Iguana/GLBrowsers/interface/Ig3DRotationControl.h>

Inheritance diagram for Ig3DRotationControl:

Ig3DVectorControl Ig3DVectorBaseControl Ig3DFieldControl IgControlBase IgControlItem Ig3DCameraRotControl

List of all members.

Public Member Functions

SoSFRotation * field (void) const
 Get the field this control is attached to, or null if the control is currently not attached to a rotation field.
SbRotation fieldValue (void) const
 Return the current value of the field this control is attached to.
 Ig3DRotationControl (IgControlCategory *pane, QString label)
 Create a new rotation controller.
void setField (SoSFRotation *field)
 Attach this control to field.
void yOver90 (bool value)
 Indicate whether current rotation around Y is over 90 degrees.
void zForY90 (float degrees)
 Set Z rotation angle to degrees for the situation when it cannot be determined from the rotation matrix (rotation around Y axis is 90 degrees).

Static Public Member Functions

static float deg2rad (float value)
 Convert value from degrees to radians.
static SbVec3f eulerXYZAngles (const SbRotation &from, bool yOver90=false, float zForY90=0, float epsilon=.0001)
 Calculate Euler rotation angles in degrees from rotation matrix rot into a sequence of rotations around X, Y, and Z axes, in that order.
static float rad2deg (float value)
 Convert value from radians to degrees.
static SbRotation rotate (const SbRotation &rot, const SbVec3f &angles)
 Rotate rot by angles (where angles is in degrees).

Protected Member Functions

virtual void applyValue (void)
 Apply the control's current value to the field.
virtual void updateValue (void)
 Update the control's current value from the field.

Private Member Functions

void setup (IgQtRangeControlFloat *c, QPixmap rev, QPixmap fwd)

Private Attributes

bool m_yOver90
float m_zForY90


Detailed Description

Definition at line 18 of file Ig3DRotationControl.h.


Constructor & Destructor Documentation

Ig3DRotationControl::Ig3DRotationControl ( IgControlCategory pane,
QString  label 
)

Create a new rotation controller.

Definition at line 129 of file Ig3DRotationControl.cc.

References IgQtRangeControlCommon::resetChangedValue(), Ig3DVectorControl::xControl(), Ig3DVectorControl::yControl(), and Ig3DVectorControl::zControl().

00131     : Ig3DVectorControl (pane, label, RotationStyle),
00132       m_yOver90 (false),
00133       m_zForY90 (0)
00134 {
00135     xControl ()->resetChangedValue (true);
00136     yControl ()->resetChangedValue (true);
00137     zControl ()->resetChangedValue (true);
00138 
00139     disconnect(pane,            SIGNAL (tracking (bool)),
00140                xControl (),     SLOT   (resetChangedValue (bool)));  
00141     disconnect(pane,            SIGNAL (tracking (bool)),
00142                yControl (),     SLOT   (resetChangedValue (bool)));  
00143     disconnect(pane,            SIGNAL (tracking (bool)),
00144                zControl (),     SLOT   (resetChangedValue (bool)));  
00145 }


Member Function Documentation

void Ig3DRotationControl::applyValue ( void   )  [protected, virtual]

Apply the control's current value to the field.

The control must currently be attached to a field; this is normally assured by base class apply() before invoking this method. Currently the control tracks only the changes made to the rotation matrix, not the actual angle values it has.

Reimplemented from Ig3DVectorBaseControl.

Reimplemented in Ig3DCameraRotControl.

Definition at line 217 of file Ig3DRotationControl.cc.

References Ig3DVectorControl::change(), field(), fieldValue(), Ig3DVectorBaseControl::isChanged(), and rotate().

Referenced by Ig3DCameraRotControl::applyValue().

00218 {    
00219     if (isChanged ())
00220         // We currently work only on changed (= delta) values, not the
00221         // absolute angles.  To switch to using actual angle values use:
00222         //   field ()->setValue (rotate (SbRotation (), value ()));
00223         field ()->setValue (rotate (fieldValue (), change ()));
00224 }

float Ig3DRotationControl::deg2rad ( float  value  )  [static]

Convert value from degrees to radians.

Definition at line 21 of file Ig3DRotationControl.cc.

Referenced by Ig3DRotationFControl::angle(), Ig3DAngleControl::applyValue(), and rotate().

00022 { return value * M_PI / 180; }

SbVec3f Ig3DRotationControl::eulerXYZAngles ( const SbRotation &  rot,
bool  yOver90 = false,
float  zForY90 = 0,
float  epsilon = .0001 
) [static]

Calculate Euler rotation angles in degrees from rotation matrix rot into a sequence of rotations around X, Y, and Z axes, in that order.

The resulting angles are in the range [-180, 180].

If yOver90 is set, rotation around Y is known to be within [-180,90) or (90,180] and the resulting angles will reflect that. Otherwise (= by default) it is assumed that Y is within [-90,90]. The range of Y cannot be determined automatically so passing this flag is useful when smooth results are needed and for example incremental rotations are applied.

If the rotation around the Y axis is exactly 90 degrees such that X maps to Z or vice versa, only the sum or difference of rotations around X and Z can be determined, but not each individually. If the client knows a good initial guess for Z rotation, for example when small incremental rotations are applied, it can pass it in the zForY90 argument to disambiguate the sum and to guarantee smooth results; by default Z is set to zero and X is given the complete rotation.

Pass epsilon to indicate how close values to 90-degree rotation around Y should be considered as 90 degrees. If you pass zero, only rotations of exactly 90 degrees will match. The default is a small but noticable error -- zero error makes it difficult to lock on a unit vector due to numerical errors. (FIXME: Test this with the new code.)

Definition at line 66 of file Ig3DRotationControl.cc.

References funct::cos(), m, rad2deg(), x, y, and z.

00070 {
00071     float       x;
00072     float       y;
00073     float       z;
00074     SbMatrix    m;
00075 
00076     rot.getValue (m);
00077 
00078     // In the notation below ca == cos(a), sa == sin(a)
00079     //
00080     //          0            1                   2
00081     //   m =  cy*cz   cz*sx*sy + cx*sz   -cx*cz*sy + sx*sz    0
00082     //       -cy*sz   cx*cz - sx*sy*sz    cz*sz + cx*sy*sz    1
00083     //         sy         -cy*sx               cx*cy          2
00084     //
00085     // If sin(y) is +-1 (y is +- 90 deg) the solution is ambiguous and
00086     // we can only determine z+x (+90) or z-x (-90).  Allow client to
00087     // lock on to +- 90 when we get close to avoid numerical errors.
00088     if (m [2][0] < 1-epsilon)
00089     {
00090         if (m [2][0] > -1+epsilon)
00091         {
00092             float yrad = asin (m [2][0]);
00093             if (yOver90) yrad = yrad > 0 ? M_PI - yrad : -M_PI - yrad;
00094             float cy = cos (yrad);
00095             y = rad2deg (yrad);
00096             z = rad2deg (atan2 (-m[1][0]/cy, m[0][0]/cy));
00097             x = rad2deg (atan2 (-m[2][1]/cy, m[2][2]/cy));
00098         }
00099         else
00100         {
00101             // sin(y) =~ -1, i.e. -90 degrees
00102             // m[0][1] == -cz*sx + cx*sz == sin(z-x)
00103             // m[1][1] ==  cx*cz + sx*sz == cos(z-x)
00104             //  ==> z-x = atan2(sin(z-x),cos(z-x))
00105             y = -90;
00106             z = zForY90;
00107             x = z - rad2deg (atan2 (m[0][1], m[1][1]));
00108         }
00109     }
00110     else
00111     {
00112         // sin(y) =~ 1, i.e. 90 degrees
00113         // m[0][1] == cz*sx + cx*sz == sin(z+x)
00114         // m[1][1] == cx*cz - sx*sz == cos(z+x)
00115         //  ==> z+x = atan2(sin(z+x),cos(z+x))
00116         y = 90;
00117         z = zForY90;
00118         x = rad2deg (atan2(m[0][1], m[1][1])) - z;
00119     }
00120 
00121     // FIXME? return SbVec3f (x ? -x : 0, y ? -y : 0, z ? -z : 0);
00122     return SbVec3f (x, y, z);
00123 }

SoSFRotation * Ig3DRotationControl::field ( void   )  const

Get the field this control is attached to, or null if the control is currently not attached to a rotation field.

See also:
setField(), fieldValue().

Reimplemented from Ig3DFieldControl.

Definition at line 167 of file Ig3DRotationControl.cc.

References Ig3DFieldControl::field().

Referenced by applyValue(), and fieldValue().

00168 { return static_cast<SoSFRotation *> (Ig3DFieldControl::field ()); }

SbRotation Ig3DRotationControl::fieldValue ( void   )  const

Return the current value of the field this control is attached to.

The control must currently by attached to a non-null field. Note that this is not necessarily the same as the current value that the control holds.

See also:
field(), setField(), value().

Definition at line 186 of file Ig3DRotationControl.cc.

References ASSERT, and field().

Referenced by applyValue().

00187 { ASSERT (field ()); return field ()->getValue (); }

float Ig3DRotationControl::rad2deg ( float  value  )  [static]

Convert value from radians to degrees.

Definition at line 26 of file Ig3DRotationControl.cc.

Referenced by eulerXYZAngles(), Ig3DRotationFControl::setValue(), and Ig3DAngleControl::updateValue().

00027 { return value * 180 / M_PI; }

SbRotation Ig3DRotationControl::rotate ( const SbRotation &  rot,
const SbVec3f &  angles 
) [static]

Rotate rot by angles (where angles is in degrees).

Definition at line 31 of file Ig3DRotationControl.cc.

References deg2rad().

Referenced by applyValue().

00032 {
00033     return SbRotation (SbVec3f (-1.F,0.F,0.F), deg2rad (angles [0]))
00034         * SbRotation (SbVec3f (0.F,-1.F,0.F), deg2rad (angles [1]))
00035         * SbRotation (SbVec3f (0.F,0.F,-1.F), deg2rad (angles [2]))
00036         * rot;
00037 }

void Ig3DRotationControl::setField ( SoSFRotation *  field  ) 

Attach this control to field.

Detaches the control from the field it was previously attached to if there is one, and attaches it to field if field is non-null.

See also:
field(), fieldValue().

Definition at line 176 of file Ig3DRotationControl.cc.

References Ig3DFieldControl::setField().

Referenced by Ig3DViewpointsCategory::attach(), and Ig3DViewpointsCategory::detach().

void Ig3DRotationControl::setup ( IgQtRangeControlFloat c,
QPixmap  rev,
QPixmap  fwd 
) [private]

void Ig3DRotationControl::updateValue ( void   )  [protected, virtual]

Update the control's current value from the field.

The control must currently be attached to a field; this is normally assured by base class update() before invoking this method. Currently the control tracks only the changes made to the rotation matrix, not the actual angle values it has, so this does nothing.

Reimplemented from Ig3DVectorBaseControl.

Definition at line 198 of file Ig3DRotationControl.cc.

00199 {
00200     // Since we never show the actual angle, there is nothing to do
00201     // here; when we get marked clean, the controls will also be made
00202     // clean, and will lose their change.  (FIXME: Get the current
00203     // angle values and display them.)
00204 
00205     //   // Use old values as best guess?
00206     //   setValue (eulerXYZAngles (fieldValue (),
00207     //                             fabs (yValue ()) > 90),
00208     //                             -zValue ()));
00209 }

void Ig3DRotationControl::yOver90 ( bool  value  ) 

Indicate whether current rotation around Y is over 90 degrees.

Use this to avoid jumps when the differences are known to be minor and current Y rotation is known.

Definition at line 158 of file Ig3DRotationControl.cc.

References m_yOver90.

00159 { m_yOver90 = value; }

void Ig3DRotationControl::zForY90 ( float  degrees  ) 

Set Z rotation angle to degrees for the situation when it cannot be determined from the rotation matrix (rotation around Y axis is 90 degrees).

The default value is zero.

Definition at line 151 of file Ig3DRotationControl.cc.

References ASSERT, and m_zForY90.

00152 { ASSERT (degrees >= -90 && degrees <= 90); m_zForY90 = degrees; }


Member Data Documentation

bool Ig3DRotationControl::m_yOver90 [private]

Definition at line 53 of file Ig3DRotationControl.h.

Referenced by yOver90().

float Ig3DRotationControl::m_zForY90 [private]

Definition at line 54 of file Ig3DRotationControl.h.

Referenced by zForY90().


The documentation for this class was generated from the following files:
Generated on Tue Jun 9 18:24:59 2009 for CMSSW by  doxygen 1.5.4