00001
00002
00003 #include "Iguana/Inventor/interface/IgSoAnimator.h"
00004 #include <Inventor/engines/SoCompose.h>
00005 #include <Inventor/engines/SoTimeCounter.h>
00006 #include <Inventor/engines/SoCalculator.h>
00007 #include <Inventor/engines/SoCounter.h>
00008 #include <Inventor/sensors/SoFieldSensor.h>
00009
00010
00011
00012
00013
00014
00015
00016
00017 SO_NODE_SOURCE (IgSoAnimator);
00018
00019
00020
00021
00022
00023 void
00024 IgSoAnimator::initClass (void)
00025 {
00026 SO_NODE_INIT_CLASS (IgSoAnimator, SoRotation, "Node");
00027 }
00028
00029 IgSoAnimator::IgSoAnimator (void)
00030 : m_crot (0),
00031 m_calc (0),
00032 m_counter (0),
00033 m_stateCounter (0),
00034 m_onSensor (0),
00035 m_resetSensor (0),
00036 m_stateSensor (0)
00037 {
00038 SO_NODE_CONSTRUCTOR (IgSoAnimator);
00039 SO_NODE_ADD_FIELD (timeMax, (2000));
00040 SO_NODE_ADD_FIELD (timeStep, (10));
00041 SO_NODE_ADD_FIELD (timeFreq, (.05));
00042 SO_NODE_ADD_FIELD (axis, (SbVec3f (1, 0, 0)));
00043 SO_NODE_ADD_FIELD (on, (FALSE));
00044 SO_NODE_ADD_FIELD (reset, (FALSE));
00045 SO_NODE_ADD_FIELD (state, (0));
00046 SO_NODE_ADD_FIELD (newAxis, (0));
00047 SO_NODE_ADD_FIELD (complete, (FALSE));
00048
00049 m_stateSensor = new SoFieldSensor (&invokeUpdateAxis, this);
00050 m_stateSensor->setPriority (SoFieldSensor::getDefaultPriority () - 2);
00051 m_onSensor = new SoFieldSensor (&onSensorCB, this);
00052 m_resetSensor = new SoFieldSensor (&resetSensorCB, this);
00053
00054 initAnim ();
00055 }
00056
00057 IgSoAnimator::~IgSoAnimator()
00058 {
00059 m_crot->unref ();
00060 m_counter->unref ();
00061 m_calc->unref();
00062 m_stateCounter->unref();
00063 delete m_onSensor;
00064 delete m_resetSensor;
00065 delete m_stateSensor;
00066 }
00067
00068 void
00069 IgSoAnimator::updateAxis (void)
00070 {
00071 if (state.getValue () == 1)
00072 axis.setValue (0, 1, 0);
00073 else if (state.getValue () == 2)
00074 axis.setValue (0, 0, 1);
00075 else
00076 axis.setValue (1, 0, 0);
00077
00078 newAxis = state.getValue ();
00079 if (state.getValue () == 0)
00080 complete = true;
00081 }
00082
00083 void
00084 IgSoAnimator::invokeUpdateAxis (void *data, SoSensor *)
00085 { static_cast<IgSoAnimator *> (data)->updateAxis (); }
00086
00087 void
00088 IgSoAnimator::resetSensorCB (void *me, SoSensor *)
00089 {
00090 IgSoAnimator *self = static_cast<IgSoAnimator *> (me);
00091 if (self->reset.getValue ())
00092 {
00093 self->m_stateSensor->detach ();
00094 self->m_onSensor->detach ();
00095 self->m_resetSensor->detach ();
00096 if (self->m_counter->getRefCount())
00097 {
00098 self->m_stateCounter->unref();
00099 self->m_crot->unref ();
00100 self->m_calc->unref();
00101 self->m_counter->unref ();
00102 }
00103
00104 short max = self->timeMax.getValue();
00105 short step = self->timeStep.getValue();
00106 float freq = self->timeFreq.getValue();
00107 self->setToDefaults ();
00108 self->reset = true;
00109 self->timeMax = max;
00110 self->timeStep = step;
00111 self->timeFreq = freq;
00112 self->initAnim ();
00113 }
00114 }
00115
00116 void
00117 IgSoAnimator::initAnim (void)
00118 {
00119 m_crot = new SoComposeRotation;
00120 m_counter = new SoTimeCounter;
00121 m_calc = new SoCalculator;
00122 m_stateCounter = new SoCounter;
00123
00124 m_counter->ref ();
00125 m_counter->min = 0;
00126 m_counter->max.connectFrom (&timeMax);
00127 m_counter->step.connectFrom (&timeStep);
00128 m_counter->frequency.connectFrom (&timeFreq);
00129 m_counter->on.connectFrom (&on);
00130
00131
00132 m_calc->ref();
00133 m_calc->a.connectFrom (&m_counter->output);
00134 m_calc->expression.set1Value (0, "oa = M_PI * a / 1000");
00135
00136
00137 m_crot->ref ();
00138 m_crot->axis.connectFrom (&axis);
00139 m_crot->angle.connectFrom (&m_calc->oa);
00140 rotation.connectFrom (&m_crot->rotation);
00141
00142
00143 m_stateCounter->ref ();
00144 m_stateCounter->min = 0;
00145 m_stateCounter->max = 2;
00146 m_stateCounter->step = 1;
00147 m_stateCounter->trigger.connectFrom (&m_counter->syncOut);
00148 m_stateCounter->reset.setValue (0);
00149
00150
00151
00152
00153 state.connectFrom (&m_stateCounter->output);
00154 m_stateSensor->attach (&state);
00155 m_onSensor->attach (&on);
00156 m_resetSensor->attach (&reset);
00157 }
00158
00159 void
00160 IgSoAnimator::onSensorCB (void *me, SoSensor *)
00161 {
00162 IgSoAnimator *self = static_cast<IgSoAnimator *> (me);
00163 if (self->on.getValue ())
00164 self->reset.setValue (false);
00165 }
00166
00167 void
00168 IgSoAnimator::write (SoWriteAction *action)
00169 {
00170 rotation.disconnect ();
00171 state.disconnect ();
00172 SoNode::write (action);
00173 rotation.connectFrom (&m_crot->rotation);
00174 state.connectFrom (&m_stateCounter->output);
00175 }