root/OpenSceneGraph/trunk/examples/osgimpostor/TestManipulator.cpp @ 6941

Revision 6941, 7.3 kB (checked in by robert, 8 years ago)

From Martin Lavery and Robert Osfield, Updated examples to use a variation of the MIT License

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgimpostor.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include "TestManipulator.h"
20#include <osg/Notify>
21
22using namespace osg;
23using namespace osgGA;
24
25TestManipulator::TestManipulator()
26{
27    _modelScale = 0.01f;
28    _minimumZoomScale = 0.05f;
29    _thrown = false;
30
31    _distance = 1.0f;
32}
33
34
35TestManipulator::~TestManipulator()
36{
37}
38
39
40void TestManipulator::setNode(osg::Node* node)
41{
42    _node = node;
43    if (_node.get())
44    {
45        const osg::BoundingSphere& boundingSphere=_node->getBound();
46        _modelScale = boundingSphere._radius;
47    }
48}
49
50
51const osg::Node* TestManipulator::getNode() const
52{
53    return _node.get();
54}
55
56
57osg::Node* TestManipulator::getNode()
58{
59    return _node.get();
60}
61
62
63                                 /*ea*/
64void TestManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
65{
66    if(_node.get())
67    {
68
69        const osg::BoundingSphere& boundingSphere=_node->getBound();
70
71        computePosition(boundingSphere.center()+osg::Vec3(0.0f, 0.0f, 20.0f),
72                        osg::Vec3(0.0f, 1.0f, 0.0f),
73                        osg::Vec3(0.0f,  0.0f,  1.0f));
74
75        us.requestRedraw();
76    }
77}
78
79
80void TestManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
81{
82    flushMouseEventStack();
83}
84
85bool TestManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
86{
87    switch(ea.getEventType())
88    {
89        case(GUIEventAdapter::PUSH):
90        {
91            flushMouseEventStack();
92            addMouseEvent(ea);
93            if (calcMovement()) us.requestRedraw();
94            us.requestContinuousUpdate(false);
95            _thrown = false;
96            return true;
97        }
98
99        case(GUIEventAdapter::RELEASE):
100        {
101            if (ea.getButtonMask()==0)
102            {
103
104                if (isMouseMoving())
105                {
106                    if (calcMovement())
107                    {
108                        us.requestRedraw();
109                        us.requestContinuousUpdate(true);
110                        _thrown = true;
111                    }
112                }
113                else
114                {
115                    flushMouseEventStack();
116                    addMouseEvent(ea);
117                    if (calcMovement()) us.requestRedraw();
118                    us.requestContinuousUpdate(false);
119                    _thrown = false;
120                }
121
122            }
123            else
124            {
125                flushMouseEventStack();
126                addMouseEvent(ea);
127                if (calcMovement()) us.requestRedraw();
128                us.requestContinuousUpdate(false);
129                _thrown = false;
130            }
131            return true;
132        }
133
134        case(GUIEventAdapter::DRAG):
135        {
136            addMouseEvent(ea);
137            if (calcMovement()) us.requestRedraw();
138            us.requestContinuousUpdate(false);
139            _thrown = false;
140            return true;
141        }
142
143        case(GUIEventAdapter::MOVE):
144        {
145            return false;
146        }
147
148        case(GUIEventAdapter::KEYDOWN):
149            if (ea.getKey()==' ')
150            {
151                flushMouseEventStack();
152                _thrown = false;
153                home(ea,us);
154                us.requestRedraw();
155                us.requestContinuousUpdate(false);
156                return true;
157            }
158            return false;
159        case(GUIEventAdapter::FRAME):
160            if (_thrown)
161            {
162                if (calcMovement()) us.requestRedraw();
163                return true;
164            }
165            return false;
166        default:
167            return false;
168    }
169}
170
171
172bool TestManipulator::isMouseMoving()
173{
174    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
175
176    static const float velocity = 0.1f;
177
178    float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
179    float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();
180    float len = sqrtf(dx*dx+dy*dy);
181    float dt = _ga_t0->getTime()-_ga_t1->getTime();
182
183    return (len>dt*velocity);
184}
185
186
187void TestManipulator::flushMouseEventStack()
188{
189    _ga_t1 = NULL;
190    _ga_t0 = NULL;
191}
192
193
194void TestManipulator::addMouseEvent(const GUIEventAdapter& ea)
195{
196    _ga_t1 = _ga_t0;
197    _ga_t0 = &ea;
198}
199
200void TestManipulator::setByMatrix(const osg::Matrixd& matrix)
201{
202    _center = matrix.getTrans();
203    _rotation = matrix.getRotate();
204    _distance = 1.0f;
205}
206
207osg::Matrixd TestManipulator::getMatrix() const
208{
209    return osg::Matrixd::rotate(_rotation)*osg::Matrixd::translate(_center);
210}
211
212osg::Matrixd TestManipulator::getInverseMatrix() const
213{
214    return osg::Matrixd::translate(-_center)*osg::Matrixd::rotate(_rotation.inverse());
215}
216
217void TestManipulator::computePosition(const osg::Vec3& eye,const osg::Vec3& lv,const osg::Vec3& up)
218{
219    osg::Vec3 f(lv);
220    f.normalize();
221    osg::Vec3 s(f^up);
222    s.normalize();
223    osg::Vec3 u(s^f);
224    u.normalize();
225   
226    osg::Matrixd rotation_matrix(s[0],     u[0],     -f[0],     0.0f,
227                                s[1],     u[1],     -f[1],     0.0f,
228                                s[2],     u[2],     -f[2],     0.0f,
229                                0.0f,     0.0f,     0.0f,      1.0f);
230                   
231    _center = eye+lv;
232    _distance = lv.length();
233    _rotation = rotation_matrix.getRotate().inverse();
234}
235
236
237bool TestManipulator::calcMovement()
238{
239
240    // return if less then two events have been added.
241    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
242
243    float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
244    float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();
245
246
247    // return if there is no movement.
248    if (dx==0 && dy==0) return false;
249
250    unsigned int buttonMask = _ga_t1->getButtonMask();
251    if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
252    {
253
254        // rotate camera.
255
256        osg::Quat new_rotate;
257        new_rotate.makeRotate(dx / 3.0f, osg::Vec3(0.0f, 0.0f, 1.0f));
258       
259        _rotation = _rotation*new_rotate;
260
261        return true;
262
263    }
264    else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
265    {
266
267        // pan model.
268
269        osg::Vec3 dv = osg::Vec3(0.0f, 0.0f, -500.0f) * dy;
270
271        _center += dv;
272       
273        return true;
274
275    }
276    else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
277    {
278        osg::Matrixd rotation_matrix(_rotation);
279   
280                       
281        osg::Vec3 uv = osg::Vec3(0.0f,1.0f,0.0f)*rotation_matrix;
282        osg::Vec3 sv = osg::Vec3(1.0f,0.0f,0.0f)*rotation_matrix;
283        osg::Vec3 fv = uv ^ sv;
284        osg::Vec3 dv = fv*(dy*-500.0f)-sv*(dx*500.0f);
285
286        _center += dv;
287
288        return true;
289    }
290
291    return false;
292}
Note: See TracBrowser for help on using the browser.