/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ //osgManipulator - Copyright (C) 2007 Fugro-Jason B.V. #include #include #include #include #include #include #include #include #include using namespace osgManipulator; namespace { osg::Geometry* createCircleGeometry(float radius, unsigned int numSegments) { const float angleDelta = 2.0f*osg::PI/(float)numSegments; const float r = radius; float angle = 0.0f; osg::Vec3Array* vertexArray = new osg::Vec3Array(numSegments); osg::Vec3Array* normalArray = new osg::Vec3Array(numSegments); for(unsigned int i = 0; i < numSegments; ++i,angle+=angleDelta) { float c = cosf(angle); float s = sinf(angle); (*vertexArray)[i].set(c*r,s*r,0.0f); (*normalArray)[i].set(c,s,0.0f); } osg::Geometry* geometry = new osg::Geometry(); geometry->setVertexArray(vertexArray); geometry->setNormalArray(normalArray); geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,vertexArray->size())); return geometry; } } TrackballDragger::TrackballDragger(bool useAutoTransform) { if (useAutoTransform) { float pixelSize = 50.0f; osg::MatrixTransform* scaler = new osg::MatrixTransform; scaler->setMatrix(osg::Matrix::scale(pixelSize, pixelSize, pixelSize)); osg::AutoTransform *at = new osg::AutoTransform; at->setAutoScaleToScreen(true); at->addChild(scaler); AntiSquish* as = new AntiSquish; as->addChild(at); addChild(as); _xDragger = new RotateCylinderDragger(); scaler->addChild(_xDragger.get()); addDragger(_xDragger.get()); _yDragger = new RotateCylinderDragger(); scaler->addChild(_yDragger.get()); addDragger(_yDragger.get()); _zDragger = new RotateCylinderDragger(); scaler->addChild(_zDragger.get()); addDragger(_zDragger.get()); _xyzDragger = new RotateSphereDragger(); scaler->addChild(_xyzDragger.get()); addDragger(_xyzDragger.get()); } else { _xDragger = new RotateCylinderDragger(); addChild(_xDragger.get()); addDragger(_xDragger.get()); _yDragger = new RotateCylinderDragger(); addChild(_yDragger.get()); addDragger(_yDragger.get()); _zDragger = new RotateCylinderDragger(); addChild(_zDragger.get()); addDragger(_zDragger.get()); _xyzDragger = new RotateSphereDragger(); addChild(_xyzDragger.get()); addDragger(_xyzDragger.get()); } setParentDragger(getParentDragger()); } TrackballDragger::~TrackballDragger() { } void TrackballDragger::setupDefaultGeometry() { osg::Geode* geode = new osg::Geode; { osg::TessellationHints* hints = new osg::TessellationHints; hints->setCreateTop(false); hints->setCreateBottom(false); hints->setCreateBackFace(false); osg::Cylinder* cylinder = new osg::Cylinder; cylinder->setHeight(0.15f); osg::ShapeDrawable* cylinderDrawable = new osg::ShapeDrawable(cylinder,hints); geode->addDrawable(cylinderDrawable); setDrawableToAlwaysCull(*cylinderDrawable); geode->addDrawable(createCircleGeometry(1.0f, 100)); } // Draw in line mode. { osg::PolygonMode* polymode = new osg::PolygonMode; polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE); geode->getOrCreateStateSet()->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); geode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); geode->getOrCreateStateSet()->setAttributeAndModes(new osg::LineWidth(2.0f),osg::StateAttribute::ON); } // Add line to all the individual 1D draggers. _xDragger->addChild(geode); _yDragger->addChild(geode); _zDragger->addChild(geode); // Rotate X-axis dragger appropriately. { osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(1.0f, 0.0f, 0.0f)); _xDragger->setMatrix(osg::Matrix(rotation)); } // Rotate Y-axis dragger appropriately. { osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(0.0f, 1.0f, 0.0f)); _yDragger->setMatrix(osg::Matrix(rotation)); } // Send different colors for each dragger. _xDragger->setColor(osg::Vec4(1.0f,0.0f,0.0f,1.0f)); _yDragger->setColor(osg::Vec4(0.0f,1.0f,0.0f,1.0f)); _zDragger->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f)); // Add invisible sphere for pick the spherical dragger. { osg::Drawable* sphereDrawable = new osg::ShapeDrawable(new osg::Sphere()); setDrawableToAlwaysCull(*sphereDrawable); osg::Geode* sphereGeode = new osg::Geode; sphereGeode->addDrawable(sphereDrawable); _xyzDragger->addChild(sphereGeode); } }