CMS 3D CMS Logo

IgSoAnimator.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
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 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00011 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00012 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00013 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00014 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00015 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00016 
00017 SO_NODE_SOURCE (IgSoAnimator);
00018 
00019 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00020 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00021 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
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));        // short int ==> mrad / M_PI
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));           // output signal
00047     SO_NODE_ADD_FIELD (complete, (FALSE));      // output signal
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)                 // Rotate about Y
00072         axis.setValue (0, 1, 0);
00073     else if (state.getValue () == 2)            // Rotate about Z
00074         axis.setValue (0, 0, 1);
00075     else                                        // Rotate about X
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     // Create a calculator to turn the timer into output angle
00132     m_calc->ref();
00133     m_calc->a.connectFrom (&m_counter->output);
00134     m_calc->expression.set1Value (0, "oa = M_PI * a / 1000"); // mrad => rad
00135 
00136     // Connect the rotation angle into the rotation
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     // Use the state counter to cycle over axes.  The states are: 0=X, 1=Y, 2=Z
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     // Connect the timer cycle to the state, then connect the state output
00151     // to the callback sensor.  Thus when the state changes we get called
00152     // so that we can change the axis.
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 }

Generated on Tue Jun 9 17:38:45 2009 for CMSSW by  doxygen 1.5.4