root/OpenSceneGraph/trunk/src/osgManipulator/RotateCylinderDragger.cpp @ 13041

Revision 13041, 7.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
14
15#include <osgManipulator/RotateCylinderDragger>
16#include <osgManipulator/Command>
17
18#include <osg/ShapeDrawable>
19#include <osg/Geometry>
20#include <osg/Material>
21
22
23using namespace osgManipulator;
24
25namespace
26{
27
28//------------------------------------------------------------------------------
29osg::Geometry* createDiskGeometry(float radius, float offset, float z, unsigned int numSegments
30   )
31{
32   const float angleDelta = 2.0f*osg::PI/float(numSegments);
33   const unsigned int numPoints = (numSegments+1) * 2;
34   float angle = 0.0f;
35   osg::Vec3Array* vertexArray = new osg::Vec3Array(numPoints);
36   osg::Vec3Array* normalArray = new osg::Vec3Array(numPoints);
37   unsigned int p = 0;
38   for(unsigned int i = 0; i < numSegments; ++i,angle+=angleDelta)
39   {
40      float c = cosf(angle);
41      float s = sinf(angle);
42      // Outer point
43      (*vertexArray)[p].set(radius*c, radius*s, z);
44      (*normalArray)[p].set(0.0, 0.0, -1.0);
45      ++p;
46      // Inner point
47      (*vertexArray)[p].set((radius-offset)*c, (radius-offset)*s, z);
48      (*normalArray)[p].set(0.0, 0.0, -1.0);
49      ++p;
50   }
51   // do last points by hand to ensure no round off errors.
52   (*vertexArray)[p] = (*vertexArray)[0];
53   (*normalArray)[p] = (*normalArray)[0];
54   ++p;
55   (*vertexArray)[p] = (*vertexArray)[1];
56   (*normalArray)[p] = (*normalArray)[1];
57
58   osg::Geometry* geometry = new osg::Geometry;
59   geometry->setVertexArray(vertexArray);
60   geometry->setNormalArray(normalArray);
61   geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
62   geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, 0, vertexArray->size()));
63   return geometry;
64}
65
66}
67
68RotateCylinderDragger::RotateCylinderDragger()
69{
70    _projector = new CylinderPlaneProjector();
71    setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
72    setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
73}
74
75RotateCylinderDragger::~RotateCylinderDragger()
76{
77}
78
79bool RotateCylinderDragger::handle(const PointerInfo& pointer, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
80{
81    // Check if the dragger node is in the nodepath.
82    if (!pointer.contains(this)) return false;
83
84    switch (ea.getEventType())
85    {
86        // Pick start.
87        case (osgGA::GUIEventAdapter::PUSH):
88            {
89                // Get the LocalToWorld matrix for this node and set it for the projector.
90                osg::NodePath nodePathToRoot;
91                computeNodePathToRoot(*this,nodePathToRoot);
92                osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
93                _projector->setLocalToWorld(localToWorld);
94
95                _startLocalToWorld = _projector->getLocalToWorld();
96                _startWorldToLocal = _projector->getWorldToLocal();
97
98                if (_projector->isPointInFront(pointer, _startLocalToWorld))
99                    _projector->setFront(true);
100                else
101                    _projector->setFront(false);
102
103                osg::Vec3d projectedPoint;
104                if (_projector->project(pointer, projectedPoint))
105                {
106                    // Generate the motion command.
107                    osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
108                    cmd->setStage(MotionCommand::START);
109                    cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
110
111                    // Dispatch command.
112                    dispatch(*cmd);
113
114                    // Set color to pick color.
115                    setMaterialColor(_pickColor,*this);
116
117                    _prevWorldProjPt = projectedPoint * _projector->getLocalToWorld();
118                    _prevRotation = osg::Quat();
119
120                    aa.requestRedraw();
121                }
122                return true;
123            }
124
125        // Pick move.
126        case (osgGA::GUIEventAdapter::DRAG):
127            {
128                // Get the LocalToWorld matrix for this node and set it for the projector.
129                osg::Matrix localToWorld = osg::Matrix(_prevRotation) * _startLocalToWorld;
130                _projector->setLocalToWorld(localToWorld);
131
132                osg::Vec3d projectedPoint;
133                if (_projector->project(pointer, projectedPoint))
134                {
135                    osg::Vec3d prevProjectedPoint = _prevWorldProjPt * _projector->getWorldToLocal();
136                    osg::Quat  deltaRotation = _projector->getRotation(prevProjectedPoint,
137                                                                      projectedPoint);
138                    osg::Quat rotation = deltaRotation * _prevRotation;
139
140                    // Generate the motion command.
141                    osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
142                    cmd->setStage(MotionCommand::MOVE);
143                    cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
144                    cmd->setRotation(rotation);
145
146                    // Dispatch command.
147                    dispatch(*cmd);
148
149                    _prevWorldProjPt = projectedPoint * _projector->getLocalToWorld();
150                    _prevRotation = rotation;
151                    aa.requestRedraw();
152                }
153                return true;
154            }
155
156        // Pick finish.
157        case (osgGA::GUIEventAdapter::RELEASE):
158            {
159                osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
160
161                cmd->setStage(MotionCommand::FINISH);
162                cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
163
164                // Dispatch command.
165                dispatch(*cmd);
166
167                // Reset color.
168                setMaterialColor(_color,*this);
169
170                aa.requestRedraw();
171
172                return true;
173            }
174        default:
175            return false;
176    }
177}
178
179void RotateCylinderDragger::setupDefaultGeometry()
180{
181    osg::Geode* geode = new osg::Geode;
182    {
183        osg::TessellationHints* hints = new osg::TessellationHints;
184        hints->setCreateTop(false);
185        hints->setCreateBottom(false);
186        hints->setCreateBackFace(false);
187
188        float radius    = 1.0f;
189        float height    = 0.1f;
190        float thickness = 0.1f;
191
192        // outer cylinder
193        osg::Cylinder* cylinder = new osg::Cylinder;
194        cylinder->setHeight(height);
195        cylinder->setRadius(radius);
196        osg::ShapeDrawable* cylinderDrawable = new osg::ShapeDrawable(cylinder, hints);
197        geode->addDrawable(cylinderDrawable);
198
199        // inner cylinder
200        osg::Cylinder* cylinder1 = const_cast<osg::Cylinder*>(_projector->getCylinder());
201        cylinder1->setHeight(height);
202        cylinder1->setRadius(radius-thickness);
203        osg::ShapeDrawable* cylinderDrawable1 = new osg::ShapeDrawable(cylinder1, hints);
204        geode->addDrawable(cylinderDrawable1);
205
206        // top
207        geode->addDrawable(createDiskGeometry(radius, thickness,  height/2, 100));
208        // bottom
209        geode->addDrawable(createDiskGeometry(radius, thickness, -height/2, 100));
210    }
211    addChild(geode);
212}
Note: See TracBrowser for help on using the browser.