changed: gcc8 base update
[opensg.git] / Source / Contrib / Manipulators / OSGPlaneMoveManipulator.cpp
blob24b6693e6a2ee2c1b533e9cdbfb623466915f2c7
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <stdlib.h>
44 #include <stdio.h>
46 #define OSG_COMPILEMANIPULATORSLIB
48 #include "OSGConfig.h"
49 #include "OSGPlane.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"
60 OSG_USING_NAMESPACE
62 /***************************************************************************\
63 * Description *
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 /***************************************************************************\
72 * Class variables *
73 \***************************************************************************/
75 /***************************************************************************\
76 * Class methods *
77 \***************************************************************************/
79 void PlaneMoveManipulator::initMethod(InitPhase ePhase)
81 Inherited::initMethod(ePhase);
83 if(ePhase == TypeObject::SystemPost)
85 IntersectAction::registerEnterDefault(
86 getClassType(),
87 reinterpret_cast<Action::Callback>(
88 &PlaneMoveManipulator::intersectEnter));
90 IntersectAction::registerLeaveDefault(
91 getClassType(),
92 reinterpret_cast<Action::Callback>(
93 &PlaneMoveManipulator::intersectLeave));
95 RenderAction::registerEnterDefault(
96 getClassType(),
97 reinterpret_cast<Action::Callback>(
98 &PlaneMoveManipulator::renderEnter));
100 RenderAction::registerLeaveDefault(
101 getClassType(),
102 reinterpret_cast<Action::Callback>(
103 &PlaneMoveManipulator::renderLeave));
108 /***************************************************************************\
109 * Instance methods *
110 \***************************************************************************/
112 /*-------------------------------------------------------------------------*\
113 - private -
114 \*-------------------------------------------------------------------------*/
116 /*----------------------- constructors & destructors ----------------------*/
118 PlaneMoveManipulator::PlaneMoveManipulator(void) :
119 Inherited()
123 PlaneMoveManipulator::PlaneMoveManipulator(const PlaneMoveManipulator &source) :
124 Inherited(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 );
144 setMaterialX(pMat);
146 pMat = SimpleMaterial::create();
147 pMat->setDiffuse(Color3f(0, 1, 0));
148 pMat->setLit (false );
149 LineChunkUnrecPtr lc = LineChunk::create();
150 lc->setWidth(3);
151 pMat->addChunk(lc);
152 setMaterialY(pMat);
154 pMat = SimpleMaterial::create();
155 pMat->setDiffuse(Color3f(0., 0., 1.));
156 pMat->setLit (true );
157 setMaterialZ(pMat);
159 // SimpleMaterial *simpleMat;
160 // Geometry *geo;
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.
171 GeoBuilder b;
173 b.vertex(Pnt3f(0,0,0));
174 b.vertex(Pnt3f(0,getLength()[1],0));
176 b.line(0, 1);
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));
223 commitChanges();
226 /*----------------------------- class specific ----------------------------*/
228 void PlaneMoveManipulator::changed(ConstFieldMaskArg whichField,
229 UInt32 origin,
230 BitVector details)
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,
253 const Int16 y)
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";
262 return;
265 // get transformation of beacon
266 Transform *t = dynamic_cast<Transform *>(getTarget()->getCore());
268 if( t == NULL )
270 SWARNING << "handled object has no parent transform!\n";
271 return;
274 Vec3f translation; // for matrix decomposition
275 Quaternion rotation;
276 Vec3f scaleFactor;
277 Quaternion scaleOrientation;
279 t->getMatrix().getTransform(translation, rotation, scaleFactor,
280 scaleOrientation);
282 OSG::Line viewray;
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();
290 Vec3f rot_axis;
291 tm.multFull(Vec3f(0,1,0), rot_axis);
293 Plane pl(rot_axis, getClickPoint());
295 Pnt3f plpoint;
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
305 Vec3f xp,zp;
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();
323 m.invert();
325 Pnt3f mpoint;
326 m.mult(plpoint, mpoint);
328 SLOG << "Manipulator::mouseMove(): mpoint:" << mpoint << endLog;
330 trans = trans + xp * fx + zp * fz;
332 else if (getActiveSubHandle() == getHandleZNode())
334 Pnt3f wcenter;
336 tm.multFull(Pnt3f(0,getLength()[1],0), wcenter);
338 Vec3f vclick, vcurrent;
340 vclick = getClickPoint() - wcenter;
341 vcurrent = plpoint - wcenter;
343 vclick.normalize();
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;
353 Matrix m;
355 m.setTransform(trans, rot, scaleFactor, scaleOrientation);
357 t->setMatrix(m);
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,
376 const Int16 x,
377 const Int16 y )
379 Transform *t = dynamic_cast<Transform *>(getTarget()->getCore());
381 if (t == NULL)
383 SWARNING << "PlaneMoveManipulator::mouseButtonPress() target is not a Transform!" << endLog;
384 return;
387 SLOG << "PlaneMoveManipulator::mouseButtonPress() button=" << button << " x=" << x << " y=" << y << std::endl << endLog;
389 OSG::Line viewray;
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 );
400 act->apply( scene );
402 SLOG << "PlaneMoveManipulator::mouseButtonPress() viewray=" << viewray << " scene=" << scene << endLog;
404 if ( act->didHit() )
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
412 Quaternion rotation;
413 Vec3f scaleFactor;
414 Quaternion scaleOrientation;
416 t->getMatrix().getTransform(translation, rotation, scaleFactor,
417 scaleOrientation);
419 Vec3f rot_axis;
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);
431 setActive(true);
434 act = NULL;
437 void PlaneMoveManipulator::mouseButtonRelease(const UInt16 button,
438 const Int16 x,
439 const Int16 y )
441 //SLOG << "Manipulator::mouseButtonRelease() button=" << button << " x=" << x << " y=" << y << std::endl << endLog;
442 setActive(false);