00001
00002
00003 #include "Iguana/GLBrowsers/interface/Ig3DUnitVec3fControl.h"
00004 #include "Iguana/GLBrowsers/interface/IgControlCategory.h"
00005 #include "Iguana/GLBrowsers/interface/IgQtRangeControlFloat.h"
00006 #include <classlib/utils/DebugAids.h>
00007
00008 #ifdef WIN32
00009 #include <float.h>
00010 #define copysign _copysign
00011 #endif // WIN32
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 Ig3DUnitVec3fControl::Ig3DUnitVec3fControl (IgControlCategory *pane,
00024 QString label,
00025 Style style )
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 }
00041
00042 void
00043 Ig3DUnitVec3fControl::setValues (const float *values, unsigned int size)
00044 {
00045 ASSERT (size == 3);
00046 SbVec3f vec (values[0], values[1], values[2]);
00047
00048 if (! m_internalUpdate)
00049 vec.normalize ();
00050
00051
00052
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
00060
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
00071
00072 for(unsigned int i = 0; i < 3; i++)
00073 control (i)->setPrecision (savedPrecision);
00074
00075 control (0)->setEmitSettingsChanged (oldSetting);
00076 }
00077
00078 void
00079 Ig3DUnitVec3fControl::setDirty (bool dirty)
00080 {
00081
00082
00083
00084
00085
00086
00087
00088
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
00101 normalize (xChange (), vec[0], vec[1], vec[2],
00102 0.00001);
00103 else if (!xdirty && ydirty && !zdirty)
00104
00105 normalize (yChange (), vec[1], vec[0], vec[2],
00106 0.00001);
00107 else if (!xdirty && !ydirty && zdirty)
00108
00109 normalize (zChange (), vec[2], vec[0], vec[1],
00110 0.00001);
00111 else
00112
00113 vec.normalize ();
00114
00115
00116 m_internalUpdate = true;
00117 setValue (vec);
00118 m_internalUpdate = false;
00119 }
00120 }
00121
00122 void
00123 Ig3DUnitVec3fControl::normalize (float delta, float &v, float &a1, float &a2,
00124 float precision )
00125 {
00126
00127
00128
00129
00130 if (fabs(a1) <= precision && fabs(a2) <= precision)
00131 {
00132 a1 = a2 = 0.;
00133 v = copysign (1, v ? v : delta);
00134 }
00135
00136 else if ((fabs (v) + precision) >= 1.0)
00137 {
00138 v = copysign (1, v);
00139 a1 = a2 = 0.;
00140 }
00141
00142
00143
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
00152 if (diff == 0.)
00153 ;
00154
00155
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
00168
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 }