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

Revision 5371, 6.4 kB (checked in by robert, 8 years ago)

Added Matrix*::getRotate()/setRotate(Quat), deprecating Matrix*::get(Quat&), Matrix*::set(Quat&)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include "TestManipulator.h"
2#include <osg/Notify>
3
4using namespace osg;
5using namespace osgGA;
6
7TestManipulator::TestManipulator()
8{
9    _modelScale = 0.01f;
10    _minimumZoomScale = 0.05f;
11    _thrown = false;
12
13    _distance = 1.0f;
14}
15
16
17TestManipulator::~TestManipulator()
18{
19}
20
21
22void TestManipulator::setNode(osg::Node* node)
23{
24    _node = node;
25    if (_node.get())
26    {
27        const osg::BoundingSphere& boundingSphere=_node->getBound();
28        _modelScale = boundingSphere._radius;
29    }
30}
31
32
33const osg::Node* TestManipulator::getNode() const
34{
35    return _node.get();
36}
37
38
39osg::Node* TestManipulator::getNode()
40{
41    return _node.get();
42}
43
44
45                                 /*ea*/
46void TestManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
47{
48    if(_node.get())
49    {
50
51        const osg::BoundingSphere& boundingSphere=_node->getBound();
52
53        computePosition(boundingSphere.center()+osg::Vec3(0.0f, 0.0f, 20.0f),
54                        osg::Vec3(0.0f, 1.0f, 0.0f),
55                        osg::Vec3(0.0f,  0.0f,  1.0f));
56
57        us.requestRedraw();
58    }
59}
60
61
62void TestManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
63{
64    flushMouseEventStack();
65}
66
67bool TestManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
68{
69    switch(ea.getEventType())
70    {
71        case(GUIEventAdapter::PUSH):
72        {
73            flushMouseEventStack();
74            addMouseEvent(ea);
75            if (calcMovement()) us.requestRedraw();
76            us.requestContinuousUpdate(false);
77            _thrown = false;
78            return true;
79        }
80
81        case(GUIEventAdapter::RELEASE):
82        {
83            if (ea.getButtonMask()==0)
84            {
85
86                if (isMouseMoving())
87                {
88                    if (calcMovement())
89                    {
90                        us.requestRedraw();
91                        us.requestContinuousUpdate(true);
92                        _thrown = true;
93                    }
94                }
95                else
96                {
97                    flushMouseEventStack();
98                    addMouseEvent(ea);
99                    if (calcMovement()) us.requestRedraw();
100                    us.requestContinuousUpdate(false);
101                    _thrown = false;
102                }
103
104            }
105            else
106            {
107                flushMouseEventStack();
108                addMouseEvent(ea);
109                if (calcMovement()) us.requestRedraw();
110                us.requestContinuousUpdate(false);
111                _thrown = false;
112            }
113            return true;
114        }
115
116        case(GUIEventAdapter::DRAG):
117        {
118            addMouseEvent(ea);
119            if (calcMovement()) us.requestRedraw();
120            us.requestContinuousUpdate(false);
121            _thrown = false;
122            return true;
123        }
124
125        case(GUIEventAdapter::MOVE):
126        {
127            return false;
128        }
129
130        case(GUIEventAdapter::KEYDOWN):
131            if (ea.getKey()==' ')
132            {
133                flushMouseEventStack();
134                _thrown = false;
135                home(ea,us);
136                us.requestRedraw();
137                us.requestContinuousUpdate(false);
138                return true;
139            }
140            return false;
141        case(GUIEventAdapter::FRAME):
142            if (_thrown)
143            {
144                if (calcMovement()) us.requestRedraw();
145                return true;
146            }
147            return false;
148        default:
149            return false;
150    }
151}
152
153
154bool TestManipulator::isMouseMoving()
155{
156    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
157
158    static const float velocity = 0.1f;
159
160    float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
161    float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();
162    float len = sqrtf(dx*dx+dy*dy);
163    float dt = _ga_t0->getTime()-_ga_t1->getTime();
164
165    return (len>dt*velocity);
166}
167
168
169void TestManipulator::flushMouseEventStack()
170{
171    _ga_t1 = NULL;
172    _ga_t0 = NULL;
173}
174
175
176void TestManipulator::addMouseEvent(const GUIEventAdapter& ea)
177{
178    _ga_t1 = _ga_t0;
179    _ga_t0 = &ea;
180}
181
182void TestManipulator::setByMatrix(const osg::Matrixd& matrix)
183{
184    _center = matrix.getTrans();
185    _rotation = matrix.getRotate();
186    _distance = 1.0f;
187}
188
189osg::Matrixd TestManipulator::getMatrix() const
190{
191    return osg::Matrixd::rotate(_rotation)*osg::Matrixd::translate(_center);
192}
193
194osg::Matrixd TestManipulator::getInverseMatrix() const
195{
196    return osg::Matrixd::translate(-_center)*osg::Matrixd::rotate(_rotation.inverse());
197}
198
199void TestManipulator::computePosition(const osg::Vec3& eye,const osg::Vec3& lv,const osg::Vec3& up)
200{
201    osg::Vec3 f(lv);
202    f.normalize();
203    osg::Vec3 s(f^up);
204    s.normalize();
205    osg::Vec3 u(s^f);
206    u.normalize();
207   
208    osg::Matrixd rotation_matrix(s[0],     u[0],     -f[0],     0.0f,
209                                s[1],     u[1],     -f[1],     0.0f,
210                                s[2],     u[2],     -f[2],     0.0f,
211                                0.0f,     0.0f,     0.0f,      1.0f);
212                   
213    _center = eye+lv;
214    _distance = lv.length();
215    _rotation = rotation_matrix.getRotate().inverse();
216}
217
218
219bool TestManipulator::calcMovement()
220{
221
222    // return if less then two events have been added.
223    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
224
225    float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
226    float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();
227
228
229    // return if there is no movement.
230    if (dx==0 && dy==0) return false;
231
232    unsigned int buttonMask = _ga_t1->getButtonMask();
233    if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
234    {
235
236        // rotate camera.
237
238        osg::Quat new_rotate;
239        new_rotate.makeRotate(dx / 3.0f, osg::Vec3(0.0f, 0.0f, 1.0f));
240       
241        _rotation = _rotation*new_rotate;
242
243        return true;
244
245    }
246    else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
247    {
248
249        // pan model.
250
251        osg::Vec3 dv = osg::Vec3(0.0f, 0.0f, -500.0f) * dy;
252
253        _center += dv;
254       
255        return true;
256
257    }
258    else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
259    {
260        osg::Matrixd rotation_matrix(_rotation);
261   
262                       
263        osg::Vec3 uv = osg::Vec3(0.0f,1.0f,0.0f)*rotation_matrix;
264        osg::Vec3 sv = osg::Vec3(1.0f,0.0f,0.0f)*rotation_matrix;
265        osg::Vec3 fv = uv ^ sv;
266        osg::Vec3 dv = fv*(dy*-500.0f)-sv*(dx*500.0f);
267
268        _center += dv;
269
270        return true;
271    }
272
273    return false;
274}
Note: See TracBrowser for help on using the browser.