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

Revision 13041, 7.0 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/Scale1DDragger>
16#include <osgManipulator/Command>
17
18#include <osg/ShapeDrawable>
19#include <osg/Geometry>
20#include <osg/LineWidth>
21#include <osg/Material>
22
23using namespace osgManipulator;
24
25namespace
26{
27
28double computeScale(const osg::Vec3d& startProjectedPoint,
29                   const osg::Vec3d& projectedPoint, double scaleCenter)
30{
31    double denom = startProjectedPoint[0] - scaleCenter;
32    double scale = denom ? (projectedPoint[0] - scaleCenter)/denom : 1.0;
33    return scale;
34}
35
36}
37
38Scale1DDragger::Scale1DDragger(ScaleMode scaleMode) : Dragger(), _minScale(0.001), _scaleMode(scaleMode)
39{
40    _projector = new LineProjector(osg::Vec3d(-0.5,0.0,0.0),osg::Vec3d(0.5,0.0,0.0));
41    setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
42    setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
43}
44
45Scale1DDragger::~Scale1DDragger()
46{
47}
48
49bool Scale1DDragger::handle(const PointerInfo& pointer, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
50{
51    // Check if the dragger node is in the nodepath.
52    if (!pointer.contains(this)) return false;
53
54    switch (ea.getEventType())
55    {
56        // Pick start.
57        case (osgGA::GUIEventAdapter::PUSH):
58            {
59                // Get the LocalToWorld matrix for this node and set it for the projector.
60                osg::NodePath nodePathToRoot;
61                computeNodePathToRoot(*this,nodePathToRoot);
62                osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
63                _projector->setLocalToWorld(localToWorld);
64
65                if (_projector->project(pointer, _startProjectedPoint))
66                {
67                    _scaleCenter = 0.0;
68                    if (_scaleMode == SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT)
69                    {
70                        if ( pointer.contains(_leftHandleNode.get()) )
71                            _scaleCenter = _projector->getLineEnd()[0];
72                        else if ( pointer.contains( _rightHandleNode.get()) )
73                            _scaleCenter = _projector->getLineStart()[0];
74                    }
75
76                    // Generate the motion command.
77                    osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();
78                    cmd->setStage(MotionCommand::START);
79                    cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
80
81                    // Dispatch command.
82                    dispatch(*cmd);
83
84                    // Set color to pick color.
85                    setMaterialColor(_pickColor,*this);
86
87                    aa.requestRedraw();
88                }
89                return true;
90            }
91
92        // Pick move.
93        case (osgGA::GUIEventAdapter::DRAG):
94            {
95                osg::Vec3d projectedPoint;
96                if (_projector->project(pointer, projectedPoint))
97                {
98                    // Generate the motion command.
99                    osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();
100
101                    // Compute scale.
102                    double scale = computeScale(_startProjectedPoint,projectedPoint,_scaleCenter);
103                    if (scale < getMinScale()) scale = getMinScale();
104
105                    // Snap the referencePoint to the line start or line end depending on which is closer.
106                    double referencePoint = _startProjectedPoint[0];
107                    if (fabs(_projector->getLineStart()[0] - referencePoint) <
108                        fabs(_projector->getLineEnd()[0]   - referencePoint))
109                        referencePoint = _projector->getLineStart()[0];
110                    else
111                        referencePoint = _projector->getLineEnd()[0];
112
113                    cmd->setStage(MotionCommand::MOVE);
114                    cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
115                    cmd->setScale(scale);
116                    cmd->setScaleCenter(_scaleCenter);
117                    cmd->setReferencePoint(referencePoint);
118                    cmd->setMinScale(getMinScale());
119
120                    // Dispatch command.
121                    dispatch(*cmd);
122
123                    aa.requestRedraw();
124                }
125                return true;
126            }
127
128        // Pick finish.
129        case (osgGA::GUIEventAdapter::RELEASE):
130            {
131                osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();
132
133                cmd->setStage(MotionCommand::FINISH);
134                cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
135
136                // Dispatch command.
137                dispatch(*cmd);
138
139                // Reset color.
140                setMaterialColor(_color,*this);
141
142                aa.requestRedraw();
143
144                return true;
145            }
146        default:
147            return false;
148    }
149}
150
151void Scale1DDragger::setupDefaultGeometry()
152{
153    // Get the line length and direction.
154    osg::Vec3 lineDir = _projector->getLineEnd()-_projector->getLineStart();
155    float lineLength = lineDir.length();
156    lineDir.normalize();
157
158    osg::Geode* lineGeode = new osg::Geode;
159    // Create a line.
160    {
161        osg::Geometry* geometry = new osg::Geometry();
162
163        osg::Vec3Array* vertices = new osg::Vec3Array(2);
164        (*vertices)[0] = _projector->getLineStart();
165        (*vertices)[1] = _projector->getLineEnd();
166
167        geometry->setVertexArray(vertices);
168        geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
169
170        lineGeode->addDrawable(geometry);
171    }
172
173    // Turn of lighting for line and set line width.
174    lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
175    osg::LineWidth* linewidth = new osg::LineWidth();
176    linewidth->setWidth(2.0f);
177    lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON);
178
179    // Add line and cones to the scene.
180    addChild(lineGeode);
181
182    // Create a left box.
183    {
184        osg::Geode* geode = new osg::Geode;
185        geode->addDrawable(new osg::ShapeDrawable(new osg::Box(_projector->getLineStart(), 0.05 * lineLength)));
186        addChild(geode);
187        setLeftHandleNode(*geode);
188    }
189
190    // Create a right box.
191    {
192        osg::Geode* geode = new osg::Geode;
193        geode->addDrawable(new osg::ShapeDrawable(new osg::Box(_projector->getLineEnd(), 0.05 * lineLength)));
194        addChild(geode);
195        setRightHandleNode(*geode);
196    }
197}
Note: See TracBrowser for help on using the browser.