1 #include <osgGA/KeySwitchMatrixManipulator>
2 #include <osg/Notify>
3 
4 using namespace osgGA;
5 
addMatrixManipulator(int key,std::string name,CameraManipulator * cm)6 void KeySwitchMatrixManipulator::addMatrixManipulator(int key, std::string name, CameraManipulator *cm)
7 {
8     if(!cm) return;
9 
10     _manips[key]=std::make_pair(name,osg::ref_ptr<CameraManipulator>(cm));
11 
12     if(!_current)
13     {
14         _current=cm;
15         _current->setHomePosition(_homeEye,_homeCenter,_homeUp,_autoComputeHomePosition);
16         _current->setNode(0);
17         _current->setCoordinateFrameCallback(getCoordinateFrameCallback());
18         _current->setByMatrix(getMatrix());
19     }
20 }
21 
addNumberedMatrixManipulator(CameraManipulator * cm)22 void KeySwitchMatrixManipulator::addNumberedMatrixManipulator(CameraManipulator *cm)
23 {
24     if(!cm) return;
25     addMatrixManipulator('1'+_manips.size(),cm->className(),cm);
26 }
27 
selectMatrixManipulator(unsigned int num)28 void KeySwitchMatrixManipulator::selectMatrixManipulator(unsigned int num)
29 {
30     unsigned int manipNo = 0;
31     KeyManipMap::iterator itr;
32     for(itr=_manips.begin();
33         manipNo!=num && itr!=_manips.end();
34         ++itr,++manipNo)
35     {
36     }
37 
38     if (itr!=_manips.end())
39     {
40         itr->second.second->setHomePosition(_homeEye,_homeCenter,_homeUp,_autoComputeHomePosition);
41 
42         if (_current.valid())
43         {
44             if ( !itr->second.second->getCoordinateFrameCallback() )
45             {
46                 itr->second.second->setCoordinateFrameCallback(_current->getCoordinateFrameCallback());
47             }
48 
49             if ( !itr->second.second->getNode() )
50             {
51                 itr->second.second->setNode(_current->getNode());
52             }
53             itr->second.second->setByMatrix(_current->getMatrix());
54         }
55         _current = itr->second.second;
56     }
57 }
58 
setNode(osg::Node * node)59 void KeySwitchMatrixManipulator::setNode(osg::Node* node)
60 {
61     for(KeyManipMap::iterator itr=_manips.begin();
62         itr!=_manips.end();
63         ++itr)
64     {
65         itr->second.second->setNode(node);
66     }
67 }
68 
setHomePosition(const osg::Vec3d & eye,const osg::Vec3d & center,const osg::Vec3d & up,bool autoComputeHomePosition)69 void KeySwitchMatrixManipulator::setHomePosition(const osg::Vec3d& eye, const osg::Vec3d& center, const osg::Vec3d& up, bool autoComputeHomePosition)
70 {
71     CameraManipulator::setHomePosition(eye, center, up, autoComputeHomePosition);
72     for(KeyManipMap::iterator itr=_manips.begin();
73         itr!=_manips.end();
74         ++itr)
75     {
76         itr->second.second->setHomePosition(eye, center, up, autoComputeHomePosition);
77     }
78 }
79 
setAutoComputeHomePosition(bool flag)80 void KeySwitchMatrixManipulator::setAutoComputeHomePosition(bool flag)
81 {
82     _autoComputeHomePosition = flag;
83     for(KeyManipMap::iterator itr=_manips.begin();
84         itr!=_manips.end();
85         ++itr)
86     {
87         itr->second.second->setAutoComputeHomePosition(flag);
88     }
89 }
90 
computeHomePosition()91 void KeySwitchMatrixManipulator::computeHomePosition()
92 {
93     for(KeyManipMap::iterator itr=_manips.begin();
94         itr!=_manips.end();
95         ++itr)
96     {
97         itr->second.second->computeHomePosition();
98     }
99 }
100 
finishAnimation()101 void KeySwitchMatrixManipulator::finishAnimation()
102 {
103     for(KeyManipMap::iterator itr=_manips.begin();
104         itr!=_manips.end();
105         ++itr)
106     {
107         itr->second.second->finishAnimation();
108     }
109 }
110 
111 
home(const GUIEventAdapter & ee,GUIActionAdapter & aa)112 void KeySwitchMatrixManipulator::home(const GUIEventAdapter& ee,GUIActionAdapter& aa)
113 {
114     // call home for all child manipulators
115     // (this can not be done just for current manipulator,
116     // because it is not possible to transfer some manipulator
117     // settings across manipulators using just MatrixManipulator interface
118     // (one problematic variable is for example OrbitManipulator::distance
119     // that can not be passed by setByMatrix method),
120     // thus we have to call home on all of them)
121     for(KeyManipMap::iterator itr=_manips.begin();
122         itr!=_manips.end();
123         ++itr)
124     {
125         itr->second.second->home(ee,aa);
126     }
127 }
128 
setCoordinateFrameCallback(CoordinateFrameCallback * cb)129 void KeySwitchMatrixManipulator::setCoordinateFrameCallback(CoordinateFrameCallback* cb)
130 {
131     _coordinateFrameCallback = cb;
132     for(KeyManipMap::iterator itr=_manips.begin();
133         itr!=_manips.end();
134         ++itr)
135     {
136         itr->second.second->setCoordinateFrameCallback(cb);
137     }
138 }
139 
getMatrixManipulatorWithIndex(unsigned int index)140 CameraManipulator* KeySwitchMatrixManipulator::getMatrixManipulatorWithIndex(unsigned int index)
141 {
142     unsigned i=0;
143     for(KeyManipMap::iterator itr = _manips.begin();
144          itr != _manips.end();
145          ++itr, ++i)
146     {
147         if (i==index) return itr->second.second.get();
148     }
149     return 0;
150 }
151 
getMatrixManipulatorWithIndex(unsigned int index) const152 const CameraManipulator* KeySwitchMatrixManipulator::getMatrixManipulatorWithIndex(unsigned int index) const
153 {
154     unsigned i=0;
155     for(KeyManipMap::const_iterator itr = _manips.begin();
156          itr != _manips.end();
157          ++itr, ++i)
158     {
159         if (i==index) return itr->second.second.get();
160     }
161     return 0;
162 }
163 
getMatrixManipulatorWithKey(unsigned int key)164 CameraManipulator* KeySwitchMatrixManipulator::getMatrixManipulatorWithKey(unsigned int key)
165 {
166     KeyManipMap::iterator itr = _manips.find(key);
167     if (itr!=_manips.end()) return itr->second.second.get();
168     else return 0;
169 }
170 
getMatrixManipulatorWithKey(unsigned int key) const171 const CameraManipulator* KeySwitchMatrixManipulator::getMatrixManipulatorWithKey(unsigned int key) const
172 {
173     KeyManipMap::const_iterator itr = _manips.find(key);
174     if (itr!=_manips.end()) return itr->second.second.get();
175     else return 0;
176 }
177 
handle(const GUIEventAdapter & ea,GUIActionAdapter & aa)178 bool KeySwitchMatrixManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& aa)
179 {
180     if (!_current) return false;
181 
182     bool handled = false;
183 
184     if (!ea.getHandled() && ea.getEventType()==GUIEventAdapter::KEYDOWN)
185     {
186 
187         KeyManipMap::iterator it=_manips.find(ea.getKey());
188         if(it != _manips.end())
189         {
190             CameraManipulator* selectedManipulator = it->second.second.get();
191             if (selectedManipulator!=_current)
192             {
193                 OSG_INFO<<"Switching to manipulator: "<<it->second.first<<std::endl;
194                 if ( !selectedManipulator->getNode() )
195                 {
196                     selectedManipulator->setNode(_current->getNode());
197                 }
198                 selectedManipulator->setByMatrix(_current->getMatrix());
199                 selectedManipulator->init(ea,aa);
200 
201                 _current = selectedManipulator;
202             }
203             handled = true;
204         }
205     }
206 
207     return _current->handle(ea,aa) || handled;
208 }
209 
getUsage(osg::ApplicationUsage & usage) const210 void KeySwitchMatrixManipulator::getUsage(osg::ApplicationUsage& usage) const
211 {
212     for(KeyManipMap::const_iterator itr=_manips.begin();
213         itr!=_manips.end();
214         ++itr)
215     {
216         std::string key; key += (char)(itr->first);
217         std::string explanation(std::string("Select '")+itr->second.first+std::string("' camera manipulator"));
218         if (_current==itr->second.second) explanation += " (default)";
219 
220         usage.addKeyboardMouseBinding(key,explanation);
221         itr->second.second->getUsage(usage);
222     }
223 }
224