00001
00002
00003 #include "Iguana/Inventor/interface/IgSoPlaneManip.h"
00004 #include <Inventor/draggers/SoJackDragger.h>
00005
00006
00007
00008
00009
00010
00011
00012
00013 SO_NODE_SOURCE (IgSoPlaneManip);
00014
00015
00016
00017
00018
00019 void
00020 IgSoPlaneManip::initClass (void)
00021 {
00022 SO_NODE_INIT_CLASS (IgSoPlaneManip, SoNode, "Node");
00023 }
00024
00025 IgSoPlaneManip::IgSoPlaneManip (void)
00026 : m_manip (new SoJackDragger),
00027 m_manipSensor (0),
00028 m_planeSensor (0)
00029 {
00030 SO_NODE_CONSTRUCTOR (IgSoPlaneManip);
00031 SO_NODE_ADD_FIELD (plane, (SbPlane (SbVec3f (0.0f, 1.0f, 0.0f), 0.0f)));
00032 SO_NODE_ADD_FIELD (manip, (FALSE));
00033
00034 m_manip->ref();
00035 m_manip->addValueChangedCallback(jackChanged, this);
00036
00037 m_manipSensor = new SoFieldSensor (&manipChanged, this);
00038 m_manipSensor->attach (&manip);
00039
00040 m_planeSensor = new SoFieldSensor (&planeChanged, this);
00041 }
00042
00043 IgSoPlaneManip::~IgSoPlaneManip (void)
00044 {
00045 m_manip->unref();
00046 delete m_manipSensor;
00047 delete m_planeSensor;
00048 }
00049
00050 SoDragger *
00051 IgSoPlaneManip::getDragger(void)
00052 { return m_manip; }
00053
00054 void
00055 IgSoPlaneManip::getMotionMatrix (SbMatrix &matrix, bool scaling )
00056 {
00057 matrix = m_manip->getMotionMatrix();
00058
00059 SbVec3f normal = plane.getValue().getNormal();
00060 SbVec3f t, s;
00061 SbRotation r, so;
00062 matrix.getTransform(t, r, s, so);
00063 r.setValue(SbVec3f(0.0f, 1.0f, 0.0f), normal);
00064 t = normal * plane.getValue().getDistanceFromOrigin ();
00065 if (scaling)
00066 s.setValue (1.0f, 1.0f, 1.0f);
00067 matrix.setTransform(t, r, s, so);
00068 }
00069
00070 void
00071 IgSoPlaneManip::jackChanged(void *me, SoDragger *dragger)
00072 {
00073 IgSoPlaneManip * self = static_cast<IgSoPlaneManip*>(me);
00074 SbMatrix matrix = dragger->getMotionMatrix();
00075
00076 SbPlane plane(SbVec3f(0.0f, 1.0f, 0.0f), 0.0f);
00077 plane.transform(matrix);
00078
00079 if ((plane.getNormal().equals (self->plane.getValue().getNormal(), 0.01f)) &&
00080 (fabs(plane.getDistanceFromOrigin() -
00081 self->plane.getValue().getDistanceFromOrigin()) < 0.0001))
00082 return;
00083
00084 if (self->manip.getValue ())
00085 {
00086 self->m_planeSensor->detach();
00087 self->plane = plane;
00088 self->m_planeSensor->attach(&self->plane);
00089 }
00090 else
00091 self->plane = plane;
00092 }
00093
00094 void
00095 IgSoPlaneManip::planeChanged(void *me, SoSensor *)
00096 {
00097 IgSoPlaneManip * self = static_cast<IgSoPlaneManip*>(me);
00098
00099 SbMatrix matrix;
00100 self->getMotionMatrix (matrix, false);
00101
00102 self->m_manip->enableValueChangedCallbacks(false);
00103 self->m_manip->setMotionMatrix(matrix);
00104 self->m_manip->enableValueChangedCallbacks(true);
00105 }
00106
00107 void
00108 IgSoPlaneManip::manipChanged (void *me, SoSensor *)
00109 {
00110 IgSoPlaneManip * self = static_cast<IgSoPlaneManip*>(me);
00111 if (self->manip.getValue ())
00112 {
00113 if (!self->hasDragger ())
00114 {
00115 self->insertChild (self->m_manip, 0);
00116 self->m_planeSensor->attach (&self->plane);
00117 self->m_planeSensor->trigger ();
00118 }
00119 }
00120 else if(self->hasDragger ())
00121 {
00122 self->m_planeSensor->detach ();
00123 self->m_manip->enableValueChangedCallbacks(false);
00124 self->removeChild (self->m_manip);
00125 }
00126 }
00127
00128 bool
00129 IgSoPlaneManip::hasDragger (void)
00130 {
00131 return (getNumChildren () > 0) &&
00132 dynamic_cast<SoJackDragger*>(getChild(0));
00133 }
00134
00135 void
00136 IgSoPlaneManip::write (SoWriteAction *action)
00137 { SoNode::write (action); }