source: osgVisual/trunk/src/manip_Spacemouse/manip_freeSpaceMouse.cpp @ 344

Last change on this file since 344 was 221, checked in by Torben Dannhauer, 14 years ago

Updated copyright NOTICE
(No code changes)

File size: 6.0 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2011 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, 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 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15*/
16
17#include <manip_freeSpaceMouse.h>
18
19
20
21using namespace osg;
22using namespace osgGA;
23using namespace osgVisual;
24
25FreeManipulator::FreeManipulator(SpaceMouse* spacemouse) : _spaceMouse(spacemouse)
26{
27}
28
29FreeManipulator::~FreeManipulator()
30{
31}
32
33void FreeManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
34{
35}
36
37void FreeManipulator::getUsage(osg::ApplicationUsage& usage) const
38{
39}
40
41bool FreeManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
42{
43    switch(ea.getEventType())
44    {
45    case(GUIEventAdapter::FRAME):
46        if (calcMovement())
47            us.requestRedraw();
48        return false;
49    default:
50        break;
51    }
52
53    return false;
54}
55
56void FreeManipulator::setByMatrix(const osg::Matrixd& matrix)
57{
58    _position = matrix.getTrans();
59    _attitude = matrix.getRotate();
60}
61
62osg::Matrixd FreeManipulator::getMatrix() const
63{
64    return osg::Matrixd::rotate(_attitude)*osg::Matrixd::translate(_position);
65}
66
67osg::Matrixd FreeManipulator::getInverseMatrix() const
68{
69    return osg::Matrixd::translate(-_position)*osg::Matrixd::rotate(_attitude.inverse());
70}
71
72bool FreeManipulator::calcMovement()
73{
74    double dTX, dTY, dTZ;
75    _spaceMouse->getTranslations(dTX, dTY, dTZ);
76
77    double dRX, dRY, dRZ;
78    _spaceMouse->getRotations(dRX, dRY, dRZ);
79
80    osg::Matrix rotation_matrix;
81    rotation_matrix.makeRotate(_attitude);
82
83    osg::Vec3d lookVector = -getUpVector(rotation_matrix);
84    osg::Vec3d sideVector = getSideVector(rotation_matrix);
85    osg::Vec3d upVector = getFrontVector(rotation_matrix);
86
87    lookVector.normalize();
88    sideVector.normalize();
89    upVector.normalize();
90
91    // POSITION
92    _position -= lookVector * dTZ;
93    _position += upVector   * dTY;
94    _position += sideVector * dTX;
95        //std::cout << "Translation: "<< dTX * 1000000.0<< ", " << dTY * 1000000.0<< ", " << dTZ * 1000000.0<< std::endl;
96
97    // ATTITUDE
98    _attitude *= osg::Quat( dRY, osg::Vec3(0.0, 0.0, 1.0));             //Yaw
99    _attitude *= osg::Quat( dRX, sideVector);                                   // Pitch
100        _attitude *= osg::Quat( -dRZ, lookVector);                                      // Bank
101
102
103    if (!_trackNodePath.empty())
104    {
105        osg::Vec3 trackNodeCenter = getTrackNodeCenter();
106
107        osg::Matrix matrixLookAt;
108        matrixLookAt.makeLookAt(_position, trackNodeCenter, osg::Vec3(0.0, 0.0, 1.0));
109
110        osg::Quat attitude = matrixLookAt.getRotate().inverse();
111        _attitude = attitude;
112    }
113
114    return true;
115}
116
117osg::Vec3 FreeManipulator::getTrackNodeCenter()
118{
119    osg::Matrixd localToWorld, worldToLocal;
120    computeNodeLocalToWorld(localToWorld);
121    computeNodeWorldToLocal(worldToLocal);
122
123    osg::Vec3 center(0.0, 0.0, 0.0);
124    if (validateNodePath())
125        center = osg::Vec3d(_trackNodePath.back()->getBound().center())*localToWorld;
126    else
127        center = osg::Vec3d(0.0f,0.0f,0.0f)*localToWorld;
128
129    return(center);
130}
131
132void FreeManipulator::computeNodeWorldToLocal(osg::Matrixd& worldToLocal) const
133{
134    if (validateNodePath())
135    {
136        worldToLocal = osg::computeWorldToLocal(getNodePath());
137    }
138}
139
140void FreeManipulator::computeNodeLocalToWorld(osg::Matrixd& localToWorld) const
141{
142    if (validateNodePath())
143    {
144        localToWorld = osg::computeLocalToWorld(getNodePath());
145    }
146
147}
148
149bool FreeManipulator::validateNodePath() const
150{
151    for(ObserverNodePath::const_iterator itr = _trackNodePath.begin();
152        itr != _trackNodePath.begin();
153        ++itr)
154    {
155        if (*itr==0) 
156        {
157            OSG_NOTIFY(osg::NOTICE)<<"Warning: tracked node path has been invalidated by changes in the scene graph."<<std::endl;
158            const_cast<ObserverNodePath&>(_trackNodePath).clear();
159            return false;
160        }
161    }
162    return true;
163}
164
165osg::NodePath FreeManipulator::getNodePath() const
166{
167    osg::NodePath nodePath;
168    for(ObserverNodePath::const_iterator itr = _trackNodePath.begin();
169        itr != _trackNodePath.end();
170        ++itr)
171    {
172        nodePath.push_back(const_cast<osg::Node*>(itr->get()));
173    }
174    return nodePath;
175}
176
177void FreeManipulator::setTrackNode(osg::Node* node)
178{
179    if (!node)
180    {
181        OSG_NOTIFY(osg::NOTICE)<<"NodeTrackerManipulator::setTrackNode(Node*):  Unable to set tracked node due to null Node*"<<std::endl;
182        return;
183    }
184
185    osg::NodePathList nodePaths = node->getParentalNodePaths();
186    if (!nodePaths.empty())
187    {
188        if (nodePaths.size()>1)
189        {
190            OSG_NOTIFY(osg::NOTICE)<<"osgGA::NodeTrackerManipualtor::setTrackNode(..) taking first parent path, ignoring others."<<std::endl;
191        }
192
193        OSG_NOTIFY(osg::INFO)<<"NodeTrackerManipulator::setTrackNode(Node*"<<node<<" "<<node->getName()<<"): Path set"<<std::endl;
194        _trackNodePath.clear();
195        setTrackNodePath( nodePaths.front() );
196    }
197    else
198    {
199        OSG_NOTIFY(osg::NOTICE)<<"NodeTrackerManipulator::setTrackNode(Node*): Unable to set tracked node due to empty parental path."<<std::endl;
200    }
201   
202    OSG_NOTIFY(osg::INFO)<<"setTrackNode("<<node->getName()<<")"<<std::endl;
203    for(unsigned int i=0; i<_trackNodePath.size(); ++i)
204    {
205        OSG_NOTIFY(osg::INFO)<<"  "<<_trackNodePath[i]->className()<<" '"<<_trackNodePath[i]->getName()<<"'"<<std::endl;
206    }
207
208}
Note: See TracBrowser for help on using the repository browser.