00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #define OSG_COMPILEMANIPULATORSLIB
00047
00048 #include "OSGConfig.h"
00049 #include "OSGBaseFunctions.h"
00050 #include "OSGSimpleMaterial.h"
00051 #include "OSGTransform.h"
00052 #include "OSGGeometry.h"
00053 #include "OSGSimpleGeometry.h"
00054 #include "OSGWindow.h"
00055 #include "OSGNameAttachment.h"
00056 #include "OSGCamera.h"
00057
00058 #include "OSGManipulator.h"
00059 #include "OSGSimpleGeometryExt.h"
00060
00061 OSG_USING_NAMESPACE
00062
00063
00064
00065
00066
00071
00072
00073
00074
00075
00076
00077
00078
00080
00081 void Manipulator::initMethod(InitPhase)
00082 {
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 Manipulator::Manipulator(void) :
00096 Inherited(),
00097 _activeParent( NULL ),
00098 _externalUpdateHandler( NULL )
00099 {
00100 }
00101
00102 Manipulator::Manipulator(const Manipulator &source) :
00103 Inherited(source)
00104 {
00105
00106 }
00107
00108 Manipulator::~Manipulator(void)
00109 {
00110 }
00111
00112
00113
00114 void Manipulator::setExternalUpdateHandler(ExternalUpdateHandler* h)
00115 {
00116 _externalUpdateHandler = h;
00117 }
00118
00119 void Manipulator::callExternalUpdateHandler()
00120 {
00121 if ( NULL != _externalUpdateHandler )
00122 {
00123 _externalUpdateHandler->update(this->getTarget());
00124 }
00125 }
00126
00128
00129 void Manipulator::changed(ConstFieldMaskArg whichField,
00130 UInt32 origin,
00131 BitVector details )
00132 {
00133 Inherited::changed(whichField, origin, details);
00134
00135 if ( (whichField & TargetFieldMask) == TargetFieldMask )
00136 {
00137 reverseTransform();
00138 }
00139 else if ( (whichField & ParentsFieldMask) == ParentsFieldMask )
00140 {
00141 Node *parent;
00142
00143 if ( !getParents().empty() )
00144 {
00145
00146 parent = dynamic_cast<Node *>(getParents()[0]);
00147 }
00148 else
00149 {
00150 parent = NULL;
00151 }
00152
00153
00154
00155
00156 if ( parent != _activeParent )
00157 {
00158 if ( NULL != parent )
00159 {
00160
00161 while(parent->getNChildren() > 0)
00162 {
00163 parent->subChild(parent->getChild(0));
00164 }
00165 addHandleGeo(parent);
00166 }
00167
00168 if ( _activeParent != NULL )
00169 {
00170 subHandleGeo(_activeParent);
00171 }
00172
00173 _activeParent = parent;
00174 }
00175 }
00176 }
00177
00178 void Manipulator::addHandleGeo(Node *n)
00179 {
00180 n->addChild(getTransXNode());
00181 n->addChild(getTransYNode());
00182 n->addChild(getTransZNode());
00183 n->addChild(getAxisLinesN());
00184 }
00185
00186 void Manipulator::subHandleGeo(Node *n)
00187 {
00188 n->subChild(getTransXNode());
00189 n->subChild(getTransYNode());
00190 n->subChild(getTransZNode());
00191 n->subChild(getAxisLinesN());
00192 }
00193
00194 void Manipulator::reverseTransform()
00195 {
00196 if ( getTarget() != NULL )
00197 {
00198 Transform *t = dynamic_cast<Transform *>(getTarget()->getCore());
00199 Matrix m,n,o;
00200
00201 Vec3f translation;
00202 Quaternion rotation;
00203 Vec3f scaleFactor;
00204 Quaternion scaleOrientation;
00205
00206 m = t->getMatrix();
00207 m.getTransform(translation, rotation, scaleFactor, scaleOrientation);
00208
00209 if( false == o.invertFrom(m) )
00210 {
00211 SWARNING << "Matrix is SINGULAR!!!\n";
00212 }
00213 else
00214 {
00215 n.setIdentity ( );
00216 n.setTransform(translation);
00217 n.setRotate (rotation );
00218 n.multLeft (o );
00219
00220 setMatrix(n);
00221 }
00222 }
00223 }
00224
00226
00227 void Manipulator::dump( UInt32 ,
00228 const BitVector ) const
00229 {
00230 SLOG << "Dump Manipulator NI" << std::endl;
00231 }
00232
00233 void Manipulator::onCreate()
00234 {
00235 }
00236
00237 void Manipulator::onCreate(const Manipulator* source)
00238 {
00239 Inherited::onCreate(source);
00240
00241 SimpleMaterialUnrecPtr pMat = SimpleMaterial::create();
00242
00243 setMaterialX(pMat);
00244
00245 pMat = SimpleMaterial::create();
00246
00247 setMaterialY(pMat);
00248
00249 pMat = SimpleMaterial::create();
00250
00251 setMaterialZ(pMat);
00252
00253 SimpleMaterial *simpleMat;
00254 Geometry *geo;
00255
00256 setExternalUpdateHandler(NULL);
00257
00258
00259 NameUnrecPtr nameN = Name::create();
00260 nameN->editFieldPtr()->setValue("XManipulator");
00261 addAttachment(nameN);
00262
00263
00264 NodeUnrecPtr pNode = makeCoordAxis(getLength()[0], 2.0, false);
00265 setAxisLinesN(pNode);
00266
00267
00268
00269 pNode = Node::create();
00270 setTransXNode(pNode);
00271 _transHandleXC = ComponentTransform::create();
00272
00273 pNode = makeHandleGeo();
00274 setHandleXNode(pNode);
00275 pMat = SimpleMaterial::create();
00276 setMaterialX (pMat );
00277
00278 getTransXNode()->setCore (_transHandleXC );
00279 getTransXNode()->addChild(getHandleXNode());
00280
00281 _transHandleXC->setTranslation(Vec3f(getLength()[0], 0, 0) );
00282 _transHandleXC->setRotation (Quaternion(Vec3f(0, 0, 1), osgDegree2Rad(-90)));
00283
00284 simpleMat = dynamic_cast<SimpleMaterial *>(getMaterialX());
00285
00286 simpleMat->setDiffuse(Color3f(1, 0, 0));
00287 simpleMat->setLit (true );
00288
00289 geo = dynamic_cast<Geometry *>(getHandleXNode()->getCore());
00290 geo->setMaterial(simpleMat);
00291
00292
00293
00294
00295 pNode = Node::create();
00296 setTransYNode(pNode);
00297 _transHandleYC = ComponentTransform::create();
00298 pNode = makeHandleGeo();
00299 setHandleYNode(pNode);
00300 pMat = SimpleMaterial::create();
00301 setMaterialY(pMat);
00302
00303 getTransYNode()->setCore (_transHandleYC );
00304 getTransYNode()->addChild(getHandleYNode());
00305
00306 _transHandleYC->setTranslation(Vec3f(0, getLength()[1], 0) );
00307
00308
00309 simpleMat = dynamic_cast<SimpleMaterial *>(getMaterialY());
00310 simpleMat->setDiffuse(Color3f(0, 1, 0));
00311 simpleMat->setLit (true );
00312
00313 geo = dynamic_cast<Geometry *>(getHandleYNode()->getCore());
00314 geo->setMaterial(simpleMat);
00315
00316
00317
00318
00319 pNode = Node::create();
00320 setTransZNode(pNode);
00321 _transHandleZC = ComponentTransform::create();
00322 pNode = makeHandleGeo();
00323 setHandleZNode(pNode);
00324 pMat = SimpleMaterial::create();
00325 setMaterialZ (pMat);
00326
00327 getTransZNode()->setCore (_transHandleZC);
00328 getTransZNode()->addChild(getHandleZNode());
00329
00330 _transHandleZC->setTranslation(Vec3f(0, 0, getLength()[2]) );
00331 _transHandleZC->setRotation (Quaternion(Vec3f(1, 0, 0), osgDegree2Rad(90)));
00332
00333 simpleMat = dynamic_cast<SimpleMaterial *>(getMaterialZ());
00334 simpleMat->setDiffuse(Color3f(0, 0, 1));
00335 simpleMat->setLit (true );
00336
00337 geo = dynamic_cast<Geometry *>(getHandleZNode()->getCore());
00338 geo->setMaterial(simpleMat);
00339
00340 commitChanges();
00341 }
00342
00343 void Manipulator::onDestroy()
00344 {
00345 }
00346
00347 void Manipulator::resolveLinks(void)
00348 {
00349 Inherited::resolveLinks();
00350
00351 _activeParent = NULL;
00352
00353 _transHandleXC = NULL;
00354 _transHandleYC = NULL;
00355 _transHandleZC = NULL;
00356 }
00357
00358 Pnt2f Manipulator::calcScreenProjection(const Pnt3f & p,
00359 Viewport * const port)
00360 {
00361 Camera *cam;
00362 Matrix proj, projtrans, view;
00363 Pnt3f pnt;
00364
00365 if( port != NULL )
00366 {
00367 cam = port->getCamera();
00368
00369 cam->getProjection(proj, port->getPixelWidth(),
00370 port->getPixelHeight());
00371 cam->getProjectionTranslation(projtrans, port->getPixelWidth(),
00372 port->getPixelHeight());
00373 cam->getViewing(view, port->getPixelWidth(), port->getPixelHeight());
00374
00375 Matrix wctocc = proj;
00376 wctocc.mult(projtrans);
00377 wctocc.mult(view);
00378
00379 wctocc.multFull(p, pnt);
00380
00381 Real32 rx = (pnt[0] + 1.0) /2 * port->getPixelWidth();
00382 Real32 ry = (pnt[1] + 1.0) /2 * port->getPixelHeight();
00383
00384 return Pnt2f(rx, ry);
00385 }
00386 else
00387 {
00388 SWARNING << "calcScreenProjection(const Pnt3f&, "
00389 "Viewport * const port="
00390 << port << ")\n";
00391 return Pnt2f(0.0f, 0.0f);
00392 }
00393 }
00394
00401 void Manipulator::mouseMove(const Int16 x,
00402 const Int16 y)
00403 {
00404
00405
00406
00407 if( getTarget() != NULL )
00408 {
00409
00410 Transform *t = dynamic_cast<Transform *>(getTarget()->getCore());
00411
00412 if( t != NULL )
00413 {
00414 UInt16 coord(0);
00415
00416 Int16 xDiff;
00417 Int16 yDiff;
00418
00419 Vec3f centerV;
00420 Vec3f handleCenterV;
00421 Vec2f mouseScreenV;
00422 Vec2f handleScreenV;
00423 Real32 handleScreenVLen;
00424
00425 Vec3f translation;
00426 Quaternion rotation;
00427 Vec3f scaleFactor;
00428 Quaternion scaleOrientation;
00429
00430
00431 static const Vec3f coordVector[3] = {
00432 Vec3f(1.0f, 0.0f, 0.0f),
00433 Vec3f(0.0f, 1.0f, 0.0f),
00434 Vec3f(0.0f, 0.0f, 1.0f)
00435 };
00436
00437
00438 if( getActiveSubHandle() == getHandleXNode())
00439 {
00440 coord = 0;
00441 }
00442 else if(getActiveSubHandle() == getHandleYNode())
00443 {
00444 coord = 1;
00445 }
00446 else if(getActiveSubHandle() == getHandleZNode())
00447 {
00448 coord = 2;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458 xDiff = x - Int16(getLastMousePos()[0]);
00459 yDiff = y - Int16(getLastMousePos()[1]);
00460
00461
00462 mouseScreenV.setValues(xDiff, -yDiff);
00463
00464 t->getMatrix().getTransform(translation, rotation, scaleFactor,
00465 scaleOrientation);
00466
00467
00468
00469 centerV = translation;
00470 Pnt2f centerPixPos = calcScreenProjection(centerV.addToZero(),
00471 getViewport());
00472
00473
00474
00475 handleCenterV = centerV + coordVector[coord]*getLength()[coord];
00476 Pnt2f handleCenterPixPos = calcScreenProjection(handleCenterV.addToZero(),
00477 getViewport());
00478
00479 handleScreenV = handleCenterPixPos - centerPixPos;
00480 handleScreenVLen = handleScreenV.length();
00481
00482 Real32 s = handleScreenV.dot(mouseScreenV) / handleScreenVLen;
00483
00484 doMovement(t, coord, s * getLength()[coord] * 0.01, translation,
00485 rotation, scaleFactor, scaleOrientation);
00486 }
00487 else
00488 {
00489 SWARNING << "handled object has no parent transform!\n";
00490 }
00491 callExternalUpdateHandler();
00492 }
00493 else
00494 {
00495 SWARNING << "Handle has no target.\n";
00496 }
00497
00498 setLastMousePos(Pnt2f(Real32(x), Real32(y)));
00499 reverseTransform();
00500
00501
00502 }
00503
00512 void Manipulator::mouseButtonPress(const UInt16 button,
00513 const Int16 x,
00514 const Int16 y )
00515 {
00516 setLastMousePos(Pnt2f(Real32(x), Real32(y)));
00517 setActive(true);
00518 }
00519
00520 void Manipulator::mouseButtonRelease(const UInt16 button,
00521 const Int16 x,
00522 const Int16 y )
00523 {
00524 setActive(false);
00525 }