changed: gcc8 base update
[opensg.git] / Source / Contrib / Manipulators / OSGManipulator.cpp
blob2945cf29d6dc4c3f80dd87fcc30218d6440f509d
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 "OSGBaseFunctions.h"
50 #include "OSGSimpleMaterial.h"
51 #include "OSGTransform.h"
52 #include "OSGGeometry.h"
53 #include "OSGSimpleGeometry.h"
54 #include "OSGWindow.h"
55 #include "OSGNameAttachment.h"
56 #include "OSGCamera.h"
57 #include "OSGViewport.h"
59 #include "OSGManipulator.h"
60 #include "OSGSimpleGeometryExt.h"
62 OSG_USING_NAMESPACE
64 /***************************************************************************\
65 * Description *
66 \***************************************************************************/
68 /*! \class OSG::Manipulator
69 Baseclass for all Manipulators
72 /***************************************************************************\
73 * Class variables *
74 \***************************************************************************/
76 /***************************************************************************\
77 * Class methods *
78 \***************************************************************************/
80 //! initialize the static features of the class, e.g. action callbacks
82 void Manipulator::initMethod(InitPhase)
86 /***************************************************************************\
87 * Instance methods *
88 \***************************************************************************/
90 /*-------------------------------------------------------------------------*\
91 - private -
92 \*-------------------------------------------------------------------------*/
94 /*----------------------- constructors & destructors ----------------------*/
96 Manipulator::Manipulator(void) :
97 Inherited ( ),
98 _activeParent (NULL),
99 _externalUpdateHandler(NULL)
103 Manipulator::Manipulator(const Manipulator &source) :
104 Inherited (source),
105 _activeParent (NULL ),
106 _externalUpdateHandler(NULL )
108 //TODO: empty copy constructor?!?!?!?
111 Manipulator::~Manipulator(void)
115 /*----------------------------- class specific ----------------------------*/
117 void Manipulator::setExternalUpdateHandler(ExternalUpdateHandler* h)
119 _externalUpdateHandler = h;
122 void Manipulator::callExternalUpdateHandler()
124 if ( NULL != _externalUpdateHandler )
126 _externalUpdateHandler->update(this->getTarget());
130 //! react to field changes
132 void Manipulator::changed(ConstFieldMaskArg whichField,
133 UInt32 origin,
134 BitVector details )
136 Inherited::changed(whichField, origin, details);
138 if ( (whichField & TargetFieldMask) == TargetFieldMask )
140 updateHandleTransform();
142 if ( (whichField & ParentsFieldMask) == ParentsFieldMask )
144 Node *parent;
146 if ( !getParents().empty() )
148 //std::cout << "parent size= " << parents.getSize() << std::endl;
149 parent = dynamic_cast<Node *>(getParents()[0]); // Dangerous! multiple parents?
151 else
153 parent = NULL;
156 //std::cout << " Parent= " << parent << std::endl;
157 //std::cout << " activeParent= " << _activeParent << std::endl;
159 if ( parent != _activeParent )
161 if ( NULL != parent )
163 // remove old childs from a loaded osb file.
164 while(parent->getNChildren() > 0)
166 parent->subChild(parent->getChild(0));
168 addHandleGeo(parent);
171 if ( _activeParent != NULL )
173 subHandleGeo(_activeParent);
176 _activeParent = parent;
179 if ( (whichField & EnablePivotFieldMask) == EnablePivotFieldMask )
181 if (getPivotNode() != 0) // Some manips don't support a pivot and don't create a node for it
183 if (!getEnablePivot())
185 getPivotNode()->setTravMask(0x0);
187 else
189 getPivotNode()->setTravMask(0xffffffff);
196 void Manipulator::addHandleGeo(Node *n)
198 n->addChild(getTransXNode());
199 n->addChild(getTransYNode());
200 n->addChild(getTransZNode());
201 n->addChild(getAxisLinesN());
202 n->addChild(getPivotNode());
205 void Manipulator::subHandleGeo(Node *n)
207 n->subChild(getTransXNode());
208 n->subChild(getTransYNode());
209 n->subChild(getTransZNode());
210 n->subChild(getAxisLinesN());
211 n->subChild(getPivotNode());
214 void Manipulator::updateHandleTransform()
216 if ( getTarget() != NULL )
218 Transform *t = dynamic_cast<Transform *>(getTarget()->getCore());
219 Matrix m,o;
221 Vec3f translation;
222 Quaternion rotation;
223 Vec3f scaleFactor;
224 Quaternion scaleOrientation;
226 m = t->getMatrix();
227 m.getTransform(translation, rotation, scaleFactor, scaleOrientation);
229 if( false == o.invertFrom(m) )
231 SWARNING << "Matrix is SINGULAR!!!\n";
233 else
235 Matrix n,ma,mb,mc,md;
237 mb.setTranslate(translation);
238 ma.setTranslate(Vec3f(getPivot()[0] * scaleFactor[0],
239 getPivot()[1] * scaleFactor[1],
240 getPivot()[2] * scaleFactor[2])
242 mc.setRotate(rotation);
244 n.multLeft(ma);
245 n.multLeft(mc);
246 n.multLeft(mb);
247 n.multLeft(o);
249 setMatrix(n);
254 //! output the instance for debug purposes
256 void Manipulator::dump( UInt32 ,
257 const BitVector ) const
259 SLOG << "Dump Manipulator NI" << std::endl;
262 void Manipulator::onCreate()
266 void Manipulator::onCreate(const Manipulator* source)
268 Inherited::onCreate(source);
270 SimpleMaterialUnrecPtr pMat;
272 // SimpleMaterial *simpleMat;
273 Geometry *geo;
275 setExternalUpdateHandler(NULL);
277 // add a name attachment
278 NameUnrecPtr nameN = Name::create();
279 nameN->editFieldPtr()->setValue("XManipulator");
280 addAttachment(nameN);
282 // make the axis lines
283 NodeUnrecPtr pNode = makeCoordAxis(getLength()[0], 2.0, false);
284 setAxisLinesN(pNode);
286 // make the red x-axis transform and handle
288 pNode = Node::create();
289 setTransXNode(pNode);
290 OSG::ComponentTransformUnrecPtr transHandleXC = ComponentTransform::create();
292 pNode = makeHandleGeo();
293 setHandleXNode(pNode);
294 pMat = SimpleMaterial::create();
295 setMaterialX (pMat );
297 getTransXNode()->setCore (transHandleXC );
298 getTransXNode()->addChild(getHandleXNode());
300 transHandleXC->setTranslation(Vec3f(getLength()[0], 0, 0) );
301 transHandleXC->setRotation (Quaternion(Vec3f(0, 0, 1), osgDegree2Rad(-90)));
303 pMat->setDiffuse(Color3f(1, 0, 0));
304 pMat->setLit (true );
306 geo = dynamic_cast<Geometry *>(getHandleXNode()->getCore());
307 geo->setMaterial(pMat);
310 // make the green y-axis transform and handle
312 pNode = Node::create();
313 setTransYNode(pNode);
314 OSG::ComponentTransformUnrecPtr transHandleYC = ComponentTransform::create();
315 pNode = makeHandleGeo();
316 setHandleYNode(pNode);
317 pMat = SimpleMaterial::create();
318 setMaterialY(pMat);
320 getTransYNode()->setCore (transHandleYC );
321 getTransYNode()->addChild(getHandleYNode());
323 transHandleYC->setTranslation(Vec3f(0, getLength()[1], 0) );
324 // transHandleYC->setRotation ( Quaternion(Vec3f(0, 0, 1), osgDegree2Rad(-90)));
326 pMat->setDiffuse(Color3f(0, 1, 0));
327 pMat->setLit (true );
329 geo = dynamic_cast<Geometry *>(getHandleYNode()->getCore());
330 geo->setMaterial(pMat);
333 // make the blue z-axis transform and handle
335 pNode = Node::create();
336 setTransZNode(pNode);
337 OSG::ComponentTransformUnrecPtr transHandleZC = ComponentTransform::create();
338 pNode = makeHandleGeo();
339 setHandleZNode(pNode);
340 pMat = SimpleMaterial::create();
341 setMaterialZ (pMat);
343 getTransZNode()->setCore (transHandleZC );
344 getTransZNode()->addChild(getHandleZNode());
346 transHandleZC->setTranslation(Vec3f(0, 0, getLength()[2]) );
347 transHandleZC->setRotation (Quaternion(Vec3f(1, 0, 0), osgDegree2Rad(90)));
349 pMat->setDiffuse(Color3f(0, 0, 1));
350 pMat->setLit (true );
352 geo = dynamic_cast<Geometry *>(getHandleZNode()->getCore());
353 geo->setMaterial(pMat);
356 // make the yellow pivot transform and handle
358 pNode = Node::create();
359 setPivotNode(pNode);
360 OSG::ComponentTransformUnrecPtr transHandlePivotC = ComponentTransform::create();
361 pNode = makeSphere(2, 0.05f);
362 setHandlePNode(pNode);
363 pMat = SimpleMaterial::create();
364 setMaterialPivot (pMat);
366 getPivotNode()->setCore (transHandlePivotC );
367 getPivotNode()->addChild(getHandlePNode());
369 transHandlePivotC->setTranslation(Vec3f(0, 0, 0));
371 pMat->setDiffuse(Color3f(1, 1, 0));
372 pMat->setLit (true );
374 geo = dynamic_cast<Geometry *>(getHandlePNode()->getCore());
375 geo->setMaterial(pMat);
377 if (!getEnablePivot())
379 getPivotNode()->setTravMask(0x0);
382 commitChanges();
385 void Manipulator::onDestroy()
389 void Manipulator::resolveLinks(void)
391 Inherited::resolveLinks();
393 _activeParent = NULL;
396 Pnt2f Manipulator::calcScreenProjection(const Pnt3f & p,
397 Viewport * const port)
399 Camera *cam;
400 Matrix proj, projtrans, view;
401 Pnt3f pnt;
403 if( port != NULL )
405 cam = port->getCamera();
407 cam->getProjection(proj,
408 port->calcPixelWidth(),
409 port->calcPixelHeight());
410 cam->getProjectionTranslation(projtrans,
411 port->calcPixelWidth(),
412 port->calcPixelHeight());
413 cam->getViewing(view,
414 port->calcPixelWidth(),
415 port->calcPixelHeight());
417 Matrix wctocc = proj;
418 wctocc.mult(projtrans);
419 wctocc.mult(view);
421 wctocc.multFull(p, pnt);
423 Real32 rx = (pnt[0] + 1.0) /2 * port->calcPixelWidth();
424 Real32 ry = (pnt[1] + 1.0) /2 * port->calcPixelHeight();
426 return Pnt2f(rx, ry);
428 else
430 SWARNING << "calcScreenProjection(const Pnt3f&, "
431 "Viewport * const port="
432 << port << ")\n";
433 return Pnt2f(0.0f, 0.0f);
437 /*! The mouseMove is called by the viewer when the mouse is moved in the
438 viewer and this handle is the active one.
440 \param x the x-pos of the mouse (pixel)
441 \param y the y-pos of the mouse (pixel)
443 void Manipulator::mouseMove(const Int16 x,
444 const Int16 y)
446 //SLOG << "Manipulator::mouseMove() enter\n" << std::flush;
448 // get the beacon's core (must be ComponentTransform) and it's center
449 if( getTarget() != NULL )
451 // get transformation of beacon
452 Transform *t = dynamic_cast<Transform *>(getTarget()->getCore());
454 if( t != NULL )
456 UInt16 coord(0); // active coordinate: X=0, Y=1, Z=2
458 Int16 xDiff; // the mousepos x delta
459 Int16 yDiff; // the mousepos y delta
461 Vec3f centerV; // center of beacon
462 Vec3f handleCenterV; // center of subhandle
463 Vec2f mouseScreenV; // mouse move vector
464 Vec2f handleScreenV; // handle vec in (cc)
465 Real32 handleScreenVLen; // len of handle vec in (cc)
467 Vec3f translation; // for matrix decomposition
468 Quaternion rotation;
469 Vec3f scaleFactor;
470 Quaternion scaleOrientation;
472 // TODO: das ist ja schon ein wenig haesslich
473 static const Vec3f coordVector[3] = {
474 Vec3f(1.0f, 0.0f, 0.0f),
475 Vec3f(0.0f, 1.0f, 0.0f),
476 Vec3f(0.0f, 0.0f, 1.0f)
479 // check for the active handle
480 if( getActiveSubHandle() == getHandleXNode())
482 coord = 0;
484 else if(getActiveSubHandle() == getHandleYNode())
486 coord = 1;
488 else if(getActiveSubHandle() == getHandleZNode())
490 coord = 2;
493 // TODO: only for debugging, -> FDEBUG
494 //SLOG << "moving " << ( coord == 0 ? "x\n" :
495 // coord == 1 ? "y\n" :
496 // "z\n" )
497 // << std::flush;
499 // calculate diffs between current and last mouse position
500 xDiff = x - Int16(getLastMousePos()[0]);
501 yDiff = y - Int16(getLastMousePos()[1]);
503 // set the vector resulting from user mouse movement and calc its length
504 mouseScreenV.setValues(xDiff, -yDiff);
506 t->getMatrix().getTransform(translation, rotation, scaleFactor,
507 scaleOrientation);
510 // calculate the camera coordinate of the center
511 centerV = translation;
512 Pnt2f centerPixPos = calcScreenProjection(centerV.addToZero(),
513 getViewport());
516 // calculate the camera coordinate of the handle center
517 handleCenterV = centerV + coordVector[coord]*getLength()[coord];
518 Pnt2f handleCenterPixPos = calcScreenProjection(handleCenterV.addToZero(),
519 getViewport());
521 handleScreenV = handleCenterPixPos - centerPixPos;
522 handleScreenVLen = handleScreenV.length();
524 Real32 s = handleScreenV.dot(mouseScreenV) / handleScreenVLen;
526 doMovement(t, coord, s * getLength()[coord] * 0.01, translation,
527 rotation, scaleFactor, scaleOrientation);
529 else
531 SWARNING << "handled object has no parent transform!\n";
533 callExternalUpdateHandler();
535 else
537 SWARNING << "Handle has no target.\n";
540 setLastMousePos(Pnt2f(Real32(x), Real32(y)));
541 updateHandleTransform();
543 //SLOG << "Manipulator::mouseMove() leave\n" << std::flush;
546 /*! The mouseButtonPress is called by the viewer when the mouse is
547 pressed in the viewer above a subhandle of this handle.
549 \param button the button pressed
550 \param x the x-pos of the mouse (pixel)
551 \param y the y-pos of the mouse (pixel)
554 void Manipulator::mouseButtonPress(const UInt16 button,
555 const Int16 x,
556 const Int16 y )
558 setLastMousePos(Pnt2f(Real32(x), Real32(y)));
559 setActive(true);
562 void Manipulator::mouseButtonRelease(const UInt16 button,
563 const Int16 x,
564 const Int16 y )
566 setActive(false);
569 void Manipulator::doMovement( Transform *t,
570 const Int32 coord,
571 const Real32 value,
572 const Vec3f &translation,
573 const Quaternion &rotation,
574 const Vec3f &scaleFactor,
575 const Quaternion &scaleOrientation)
577 SWARNING << "MoveManipulator::doMovement: called. Shouldn't happen!" << endLog;
580 const Vec3f& Manipulator::getActiveAxis(void) const
582 static const Vec3f coordVector[] = {
583 Vec3f(1.0f, 0.0f, 0.0f),
584 Vec3f(0.0f, 1.0f, 0.0f),
585 Vec3f(0.0f, 0.0f, 1.0f),
586 Vec3f(-1.0f, -1.0f, -1.0f)
589 UInt16 coord;
590 // check for the active handle
591 if( getActiveSubHandle() == getHandleXNode())
593 coord = 0;
595 else if(getActiveSubHandle() == getHandleYNode())
597 coord = 1;
599 else if(getActiveSubHandle() == getHandleZNode())
601 coord = 2;
603 else
605 coord = 3;
608 return coordVector[coord];