#include <Iguana/GLBrowsers/interface/Ig3DUnitVec3fControl.h>
Public Slots | |
virtual void | setDirty (bool dirty) |
virtual void | setValues (const float *values, unsigned int size) |
Public Member Functions | |
Ig3DUnitVec3fControl (IgControlCategory *pane, QString label, Style style=DirectionStyle) | |
Private Member Functions | |
void | normalize (float delta, float &v, float &a1, float &a2, float precision=0.001) |
Private Attributes | |
bool | m_internalUpdate |
Definition at line 15 of file Ig3DUnitVec3fControl.h.
Ig3DUnitVec3fControl::Ig3DUnitVec3fControl | ( | IgControlCategory * | pane, | |
QString | label, | |||
Style | style = DirectionStyle | |||
) |
Definition at line 23 of file Ig3DUnitVec3fControl.cc.
References Ig3DVectorControl::control(), m_internalUpdate, IgQtRangeControlCommon::rangeEditable(), IgQtRangeControlFloat::setLongStep(), IgQtRangeControlFloat::setRange(), IgQtRangeControlFloat::setSmallStep(), Ig3DVectorControl::setValue(), Ig3DVectorControl::xControl(), Ig3DVectorControl::yControl(), and Ig3DVectorControl::zControl().
00026 : Ig3DVec3fControl (pane, label, style), 00027 m_internalUpdate (false) 00028 { 00029 control ()->setSmallStep (.01); 00030 control ()->setLongStep (.1); 00031 control ()->setRange (-1.,1.); 00032 00033 xControl ()->rangeEditable (false); 00034 yControl ()->rangeEditable (false); 00035 zControl ()->rangeEditable (false); 00036 00037 m_internalUpdate = true; 00038 setValue(1., 0., 0.); 00039 m_internalUpdate = false; 00040 }
void Ig3DUnitVec3fControl::normalize | ( | float | delta, | |
float & | v, | |||
float & | a1, | |||
float & | a2, | |||
float | precision = 0.001 | |||
) | [private] |
Definition at line 123 of file Ig3DUnitVec3fControl.cc.
References ASSERT, diff, and funct::sqrt().
Referenced by setDirty().
00125 { 00126 // If the other two components are zero, give v everything; 00127 // determine the sign from v's previous value, or if zero, from 00128 // the direction we are going to (increase -> 1, decrease -> -1). 00129 00130 if (fabs(a1) <= precision && fabs(a2) <= precision) 00131 { 00132 a1 = a2 = 0.; 00133 v = copysign (1, v ? v : delta); 00134 } 00135 // Otherwise, if v is nearly one, make it one. 00136 else if ((fabs (v) + precision) >= 1.0) 00137 { 00138 v = copysign (1, v); 00139 a1 = a2 = 0.; 00140 } 00141 00142 // Otherwise, normalise by fixing v and giving the rest of the 00143 // magnitude to one or two other components. 00144 else 00145 { 00146 float newMag = v * v; 00147 float oldMag = (v-delta) * (v-delta); 00148 float diff = newMag - oldMag; 00149 00150 ASSERT (newMag <= 1); 00151 // If no difference, nothing to do 00152 if (diff == 0.) 00153 ; 00154 00155 // If one component is zero, give the rest of magnitude to the other 00156 else if (fabs(a1) <= precision) 00157 { 00158 a1 = 0.; 00159 a2 = copysign (sqrt (1-newMag), a2); 00160 } 00161 else if (fabs(a2) <= precision) 00162 { 00163 a2 = 0.; 00164 a1 = copysign (sqrt (1-newMag), a1); 00165 } 00166 00167 // Otherwise, distribute the magnitude growth to the other two 00168 // proportional to their current magnitudes. 00169 else 00170 { 00171 float a11 = a1*a1; 00172 float a22 = a2*a2; 00173 a11 = fabs (a11 * (1. - diff / (a11 + a22))); 00174 a22 = fabs (a22 * (1. - diff / (a11 + a22))); 00175 a1 = copysign (sqrt (a11), a1); 00176 a2 = copysign (sqrt (a22), a2); 00177 } 00178 } 00179 }
Reimplemented from Ig3DVectorBaseControl.
Definition at line 79 of file Ig3DUnitVec3fControl.cc.
References IgControlItem::isDirty(), m_internalUpdate, normalize(), IgControlItem::setDirty(), Ig3DVectorControl::setValue(), Ig3DVectorControl::value(), Ig3DVectorControl::xChange(), Ig3DVectorControl::xControl(), Ig3DVectorControl::yChange(), Ig3DVectorControl::yControl(), Ig3DVectorControl::zChange(), and Ig3DVectorControl::zControl().
00080 { 00081 // Normalise the vector if the value is not being forced on us 00082 // from outside and we are not recursing (from setValue() below). 00083 // 00084 // If the change occurs due to GUI changes and there is just one 00085 // changed component, fix the changed one and normalise the other 00086 // two components relative to it. This makes the user interface 00087 // more intuitive and avoids numerical errors when one of the 00088 // values is stepped to boundaries. 00089 if (m_internalUpdate || ! dirty) 00090 Ig3DVectorControl::setDirty (dirty); 00091 00092 else 00093 { 00094 SbVec3f vec (value ()); 00095 bool xdirty = xControl ()->isDirty (); 00096 bool ydirty = yControl ()->isDirty (); 00097 bool zdirty = zControl ()->isDirty (); 00098 00099 if (xdirty && !ydirty && !zdirty) 00100 // Fix X and normalise the others. 00101 normalize (xChange (), vec[0], vec[1], vec[2], 00102 0.00001); 00103 else if (!xdirty && ydirty && !zdirty) 00104 // Fix Y and normalise the others. 00105 normalize (yChange (), vec[1], vec[0], vec[2], 00106 0.00001); 00107 else if (!xdirty && !ydirty && zdirty) 00108 // Fix Z and normalise the others. 00109 normalize (zChange (), vec[2], vec[0], vec[1], 00110 0.00001); 00111 else 00112 // Normalise all. 00113 vec.normalize (); 00114 00115 // Prevent recursive normalisation and set it. 00116 m_internalUpdate = true; 00117 setValue (vec); 00118 m_internalUpdate = false; 00119 } 00120 }
Reimplemented from Ig3DVectorBaseControl.
Definition at line 43 of file Ig3DUnitVec3fControl.cc.
References ASSERT, Ig3DVectorControl::control(), i, int, IgQtRangeControlCommon::isEmitSettingsChanged(), m_internalUpdate, IgQtRangeValuePrecision::precision(), IgControlItem::setClean(), IgQtRangeControlCommon::setEmitSettingsChanged(), IgQtRangeControlFloat::setPrecision(), and Ig3DVectorBaseControl::setValues().
00044 { 00045 ASSERT (size == 3); 00046 SbVec3f vec (values[0], values[1], values[2]); 00047 // If this is coming from inside, don't touch it 00048 if (! m_internalUpdate) 00049 vec.normalize (); 00050 00051 // Save current precision setting across the update. Increase the 00052 // precision while setting the value to avoid jittered values. 00053 float savedPrecision = control (0)->precision (); 00054 bool oldSetting = control (0)->isEmitSettingsChanged (); 00055 control (0)->setEmitSettingsChanged (false); 00056 for(unsigned int i = 0; i < 3; i++) 00057 control (i)->setPrecision (.00001); 00058 00059 // Set the value. Prevent further internal normalisation. Then 00060 // mark all the controls clean. 00061 bool savedInternal = m_internalUpdate; 00062 m_internalUpdate = true; 00063 Ig3DVectorBaseControl::setValues (vec.getValue (), (unsigned int)(3)); 00064 00065 for(unsigned int i = 0; i < 3; i++) 00066 control (i)->setClean (); 00067 00068 m_internalUpdate = savedInternal; 00069 00070 // Restore the precision back to whatever it was. 00071 00072 for(unsigned int i = 0; i < 3; i++) 00073 control (i)->setPrecision (savedPrecision); 00074 00075 control (0)->setEmitSettingsChanged (oldSetting); 00076 }
bool Ig3DUnitVec3fControl::m_internalUpdate [private] |
Definition at line 37 of file Ig3DUnitVec3fControl.h.
Referenced by Ig3DUnitVec3fControl(), setDirty(), and setValues().