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

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

Moved memory leak detection from source file to headerfile. Its still in the class but at least not in the source file.

The leak detection works, but the false positives are not stopped.
Use Linux/Valgrind? to make your final leak detection beyond the easy first approach in MSVC

File size: 6.0 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}
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.