source: osgVisual/src/manip_Spacemouse/manip_freeSpaceMouse.cpp @ 87

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

Introductes VS 2008 Memory Leak Debugging.
Todo: Compile on Linux and compare with Valgrind, VS 2008 seems to be awkward in leak debugging

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