1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #define OSG_COMPILEMANIPULATORSLIB
48 #include "OSGConfig.h"
50 #include "OSGRenderAction.h"
51 #include "OSGIntersectAction.h"
52 #include "OSGSimpleMaterial.h"
53 #include "OSGNameAttachment.h"
54 #include "OSGGeoBuilder.h"
55 #include "OSGLineChunk.h"
56 #include "OSGCamera.h"
58 #include "OSGPlaneMoveManipulator.h"
62 /***************************************************************************\
64 \***************************************************************************/
66 /*! \class OSG::PlaneMoveManipulator
67 * The MoveHandle is used for moving objects. It consist of three axis which
68 * can be picked and translated and one center box to translate freely in 3D.
71 /***************************************************************************\
73 \***************************************************************************/
75 /***************************************************************************\
77 \***************************************************************************/
79 void PlaneMoveManipulator::initMethod(InitPhase ePhase
)
81 Inherited::initMethod(ePhase
);
83 if(ePhase
== TypeObject::SystemPost
)
85 IntersectAction::registerEnterDefault(
87 reinterpret_cast<Action::Callback
>(
88 &PlaneMoveManipulator::intersectEnter
));
90 IntersectAction::registerLeaveDefault(
92 reinterpret_cast<Action::Callback
>(
93 &PlaneMoveManipulator::intersectLeave
));
95 RenderAction::registerEnterDefault(
97 reinterpret_cast<Action::Callback
>(
98 &PlaneMoveManipulator::renderEnter
));
100 RenderAction::registerLeaveDefault(
102 reinterpret_cast<Action::Callback
>(
103 &PlaneMoveManipulator::renderLeave
));
108 /***************************************************************************\
110 \***************************************************************************/
112 /*-------------------------------------------------------------------------*\
114 \*-------------------------------------------------------------------------*/
116 /*----------------------- constructors & destructors ----------------------*/
118 PlaneMoveManipulator::PlaneMoveManipulator(void) :
123 PlaneMoveManipulator::PlaneMoveManipulator(const PlaneMoveManipulator
&source
) :
128 PlaneMoveManipulator::~PlaneMoveManipulator(void)
132 void PlaneMoveManipulator::onCreate()
136 void PlaneMoveManipulator::onCreate(const PlaneMoveManipulator
* source
)
138 // Skip direct parent, don't want the default geometry creation
139 Transform::onCreate(source
);
141 SimpleMaterialUnrecPtr pMat
= SimpleMaterial::create();
142 pMat
->setDiffuse(Color3f(.5, .5, .5));
143 pMat
->setLit (false );
146 pMat
= SimpleMaterial::create();
147 pMat
->setDiffuse(Color3f(0, 1, 0));
148 pMat
->setLit (false );
149 LineChunkUnrecPtr lc
= LineChunk::create();
154 pMat
= SimpleMaterial::create();
155 pMat
->setDiffuse(Color3f(0., 0., 1.));
156 pMat
->setLit (true );
159 // SimpleMaterial *simpleMat;
162 setExternalUpdateHandler(NULL
);
164 // add a name attachment
165 NameUnrecPtr nameN
= Name::create();
166 nameN
->editFieldPtr()->setValue("XYManipulator");
167 addAttachment(nameN
);
169 // make the axis line. Not really a handle, but easier to manage this way.
173 b
.vertex(Pnt3f(0,0,0));
174 b
.vertex(Pnt3f(0,getLength()[1],0));
178 GeometryUnrecPtr g
= b
.getGeometry();
180 g
->setMaterial(getMaterialY());
182 NodeUnrecPtr pNode
= makeNodeFor(g
);
183 setTransYNode(pNode
);
185 // make the plane handle
187 pNode
= Node::create();
188 setTransXNode(pNode
);
190 g
= makePlaneGeo(getLength()[0] / 2.f
, getLength()[2] / 2.f
, 1, 1);
191 g
->setMaterial(getMaterialX());
192 pNode
= makeNodeFor(g
);
194 OSG::ComponentTransformUnrecPtr transHandleXC
= ComponentTransform::create();
196 setHandleXNode(pNode
);
198 getTransXNode()->setCore (transHandleXC
);
199 getTransXNode()->addChild(getHandleXNode());
201 transHandleXC
->setTranslation(Vec3f(0, getLength()[1], 0));
202 transHandleXC
->setRotation (Quaternion(Vec3f(1, 0, 0), osgDegree2Rad(90)));
205 // make the rotate handle
207 pNode
= Node::create();
208 setTransZNode(pNode
);
210 g
= makeCylinderGeo(0.05f
, 0.1f
, 16, true, true, true);
211 g
->setMaterial(getMaterialZ());
212 pNode
= makeNodeFor(g
);
214 OSG::ComponentTransformUnrecPtr transHandleZC
= ComponentTransform::create();
216 setHandleZNode(pNode
);
218 getTransZNode()->setCore (transHandleZC
);
219 getTransZNode()->addChild(getHandleZNode());
221 transHandleZC
->setTranslation(Vec3f(0, getLength()[1], 0));
226 /*----------------------------- class specific ----------------------------*/
228 void PlaneMoveManipulator::changed(ConstFieldMaskArg whichField
,
232 Inherited::changed(whichField
, origin
, details
);
235 void PlaneMoveManipulator::dump( UInt32 uiIndent
,
236 const BitVector bvFlags
) const
238 Inherited::dump(uiIndent
, bvFlags
);
241 NodeTransitPtr
PlaneMoveManipulator::makeHandleGeo()
243 return Node::create();
246 /*! The mouseMove is called by the viewer when the mouse is moved in the
247 viewer and this handle is the active one.
249 \param x the x-pos of the mouse (pixel)
250 \param y the y-pos of the mouse (pixel)
252 void PlaneMoveManipulator::mouseMove(const Int16 x
,
255 SLOG
<< "==============================" << endLog
;
256 SLOG
<< "PlaneMoveManipulator::mouseMove() enter x=" << x
<< " y=" << y
<< endLog
;
258 // get the beacon's core (must be ComponentTransform) and it's center
259 if( getTarget() == NULL
)
261 SWARNING
<< "Handle has no target.\n";
265 // get transformation of beacon
266 Transform
*t
= dynamic_cast<Transform
*>(getTarget()->getCore());
270 SWARNING
<< "handled object has no parent transform!\n";
274 Vec3f translation
; // for matrix decomposition
277 Quaternion scaleOrientation
;
279 t
->getMatrix().getTransform(translation
, rotation
, scaleFactor
,
283 getViewport()->getCamera()->calcViewRay(viewray
, x
, y
, *getViewport());
285 SLOG
<< "Manipulator::mouseMove(): viewray: " << viewray
<< endLog
;
287 // Get manipulator axes into world space
288 OSG::Matrix tm
= getTarget()->getToWorld();
291 tm
.multFull(Vec3f(0,1,0), rot_axis
);
293 Plane
pl(rot_axis
, getClickPoint());
297 if (pl
.intersect(viewray
, plpoint
) == true) // Ignore moving out of the plane...
299 SLOG
<< "Manipulator::mouseMove(): plpoint: " << plpoint
<< endLog
;
301 Vec3f trans
= getBaseTranslation();
302 Quaternion rot
= getBaseRotation();
304 // Get manipulator axes into world space
307 tm
.multFull(Vec3f(1,0,0), xp
);
308 tm
.multFull(Vec3f(0,0,1), zp
);
310 if (getActiveSubHandle() == getHandleXNode())
312 Line
xaxis(getClickPoint(), xp
);
313 Line
zaxis(getClickPoint(), zp
);
315 Real32 fx
= xaxis
.getClosestPointT(plpoint
);
316 Real32 fz
= zaxis
.getClosestPointT(plpoint
);
318 SLOG
<< "Manipulator::mouseMove(): xaxis: " << xaxis
<< " zaxis: " << zaxis
<<endLog
;
319 SLOG
<< "Manipulator::mouseMove(): fx: " << fx
<< " fz: " << fz
<<endLog
;
321 // Alternative: transform hitpoint into manip space
322 OSG::Matrix m
= getTarget()->getToWorld();
326 m
.mult(plpoint
, mpoint
);
328 SLOG
<< "Manipulator::mouseMove(): mpoint:" << mpoint
<< endLog
;
330 trans
= trans
+ xp
* fx
+ zp
* fz
;
332 else if (getActiveSubHandle() == getHandleZNode())
336 tm
.multFull(Pnt3f(0,getLength()[1],0), wcenter
);
338 Vec3f vclick
, vcurrent
;
340 vclick
= getClickPoint() - wcenter
;
341 vcurrent
= plpoint
- wcenter
;
344 vcurrent
.normalize();
346 Real32 a
= vclick
.enclosedAngle(vcurrent
);
348 SLOG
<< "Manipulator::mouseMove(): wcenter:" << wcenter
<< "" <<endLog
;
349 SLOG
<< "Manipulator::mouseMove(): vclick:" << vclick
<< " vcurrent:" << vcurrent
<<endLog
;
350 SLOG
<< "Manipulator::mouseMove(): angle:" << a
<< " deg: " << osgRad2Degree(a
) << endLog
;
355 m
.setTransform(trans
, rot
, scaleFactor
, scaleOrientation
);
361 setLastMousePos(Pnt2f(Real32(x
), Real32(y
)));
362 updateHandleTransform();
364 //SLOG << "Manipulator::mouseMove() leave\n" << std::flush;
367 /*! The mouseButtonPress is called by the viewer when the mouse is
368 pressed in the viewer above a subhandle of this handle.
370 \param button the button pressed
371 \param x the x-pos of the mouse (pixel)
372 \param y the y-pos of the mouse (pixel)
375 void PlaneMoveManipulator::mouseButtonPress(const UInt16 button
,
379 Transform
*t
= dynamic_cast<Transform
*>(getTarget()->getCore());
383 SWARNING
<< "PlaneMoveManipulator::mouseButtonPress() target is not a Transform!" << endLog
;
387 SLOG
<< "PlaneMoveManipulator::mouseButtonPress() button=" << button
<< " x=" << x
<< " y=" << y
<< std::endl
<< endLog
;
390 getViewport()->getCamera()->calcViewRay(viewray
, x
, y
, *getViewport());
392 OSG::Node
*scene
= getTarget();
393 while (scene
->getParent() != 0)
395 scene
= scene
->getParent();
398 OSG::IntersectActionRefPtr act
= OSG::IntersectAction::create();
399 act
->setLine( viewray
);
402 SLOG
<< "PlaneMoveManipulator::mouseButtonPress() viewray=" << viewray
<< " scene=" << scene
<< endLog
;
406 SLOG
<< "PlaneMoveManipulator::mouseButtonPress() hit! at " << act
->getHitPoint() << endLog
;
408 // Get manipulator plane into world space
409 OSG::Matrix m
= getTarget()->getToWorld();
411 Vec3f translation
; // for matrix decomposition
414 Quaternion scaleOrientation
;
416 t
->getMatrix().getTransform(translation
, rotation
, scaleFactor
,
420 rotation
.multVec(Vec3f(0,1,0), rot_axis
);
422 Plane
pl(rot_axis
, act
->getHitPoint());
424 SLOG
<< "PlaneMoveManipulator::mouseButtonPress() world plane: " << pl
<< endLog
;
426 setClickPoint(act
->getHitPoint());
428 setBaseTranslation(translation
);
429 setBaseRotation(rotation
);
437 void PlaneMoveManipulator::mouseButtonRelease(const UInt16 button
,
441 //SLOG << "Manipulator::mouseButtonRelease() button=" << button << " x=" << x << " y=" << y << std::endl << endLog;