00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <PVLE/Config.h>
00028 #include <PVLE/Util/Assert.h>
00029 #include <PVLE/Input/ControlMapper.h>
00030 #ifdef PVLE_NETWORKING
00031 #include <tnl/tnlEventConnection.h>
00032 #endif
00033
00034 #ifndef CONTROL_MAPPER_WX
00035
00036 #ifdef WIN32
00037
00038 #ifndef WIN32_LEAN_AND_MEAN
00039 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
00040 #endif
00041 #include <windows.h>
00042
00044 inline void getMousePosition(int * pX, int * pY) {
00045 POINT pt;
00046 GetCursorPos(&pt);
00047 if (pX) *pX = pt.x;
00048 if (pY) *pY = pt.y;
00049 }
00050 #elif defined(PVLE_USE_X11)
00051 #include "X11/Xutil.h"
00052 #include <PVLE/Util/Singleton.h>
00053 class DisplaySingleton : public Util::Singleton<DisplaySingleton> {
00054 public:
00055 DisplaySingleton() : display(NULL) {}
00056 ~DisplaySingleton() { close(); }
00058 inline Display * get() {
00059 if (!display) { display = XOpenDisplay(NULL); ASSERT(display); }
00060 }
00062 inline void close() {
00063 if (display) { XCloseDisplay(display); display = NULL; }
00064 }
00065 Display * display;
00066 };
00067
00069 inline void getMousePosition(int * pX, int * pY) {
00070 XMotionEvent xev;
00071 Window root, child;
00072 Display * display = DisplaySingleton::instance().get();
00073 XQueryPointer(display,
00074 DefaultRootWindow(display),
00075 &root, &child,
00076 &(xev.x_root), &(xev.y_root),
00077 &(xev.x), &(xev.y),
00078 &(xev.state));
00079 *pX = xev.x_root;
00080 *pY = xev.y_root;
00081 }
00082 #else
00083
00084
00085
00086
00087
00088
00089
00090 #pragma message("(Platform-specific) Not implemented PVLE: getMousePosition(). Fallback to wxWidgets implementation.")
00091 #define CONTROL_MAPPER_WX
00092 #endif
00093 #endif
00094
00095 #ifdef CONTROL_MAPPER_WX
00096 #include <wx/utils.h>
00097 inline void getMousePosition(int * pX, int * pY) { return wxGetMousePosition(pX, pY); }
00098 #endif
00099
00100
00101
00102 #ifdef WIN32
00104 bool appHasFocus(osgGA::GUIActionAdapter &aa, int mouseX, int mouseY) {
00105
00106
00107 return GetActiveWindow() != NULL;
00108 }
00109
00110 #else
00111 #pragma message("(Platform-specific) Not implemented PVLE: appHasFocus(). Fallback to 'always true'. Maybe something interesing in wxWidgets implementation?")
00112
00114 bool appHasFocus(osgGA::GUIActionAdapter &aa, int mouseX, int mouseY) {
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 return true;
00126 }
00127 #endif
00128
00129
00130
00131 ControlMapper::THandlerList & ControlMapper::getHandlerList(UINT orderIndex) {
00132 THandlerListsList::iterator it = handlerLists.find(orderIndex);
00133 if (it == handlerLists.end()) THROW_TRACED_FMT_EXCEPTION("No handler list exists with orderIndex == %1%", orderIndex);
00134 return it->second;
00135 }
00136
00137 const ControlMapper::THandlerList & ControlMapper::getHandlerList(UINT orderIndex) const {
00138 THandlerListsList::const_iterator it = handlerLists.find(orderIndex);
00139 if (it == handlerLists.end()) THROW_TRACED_FMT_EXCEPTION("No handler list exists with orderIndex == %1%", orderIndex);
00140 return it->second;
00141 }
00142
00143 ControlMapper::THandlerList & ControlMapper::getOrCreateHandlerList(UINT orderIndex) {
00144 THandlerListsList::iterator it = handlerLists.find(orderIndex);
00145 if (it == handlerLists.end()) {
00146 std::pair<THandlerListsList::iterator, bool> ret = handlerLists.insert(THandlerListP(orderIndex, THandlerList()));
00147 ASSERT(ret.second);
00148 return ret.first->second;
00149 }
00150 return it->second;
00151 }
00152
00153 ControlMapper::THandlerLocation ControlMapper::findHandler(ControlEventHandler * pHandler) {
00154 THandlerList::iterator itSub;
00155 for(THandlerListsList::iterator it=handlerLists.begin(), itEnd=handlerLists.end(); it!=itEnd; ++it) {
00156 THandlerList & list = it->second;
00157 itSub = std::find(list.begin(), list.end(), pHandler);
00158 if (itSub != list.end()) return THandlerLocation(&list, itSub);
00159 }
00160 return THandlerLocation(NULL, THandlerList::iterator());
00161 }
00162
00163 void ControlMapper::removeHandler(ControlEventHandler * pHandler) {
00164 THandlerLocation location = findHandler(pHandler);
00165 if (location.first != NULL) {
00166
00167 pHandler->onRemovedFromControler(this);
00168 location.first->erase(location.second);
00169 } else LOG_ERROR << "Cannot remove given handler (does not exist in this ControlMapper)" << std::endl;
00170 }
00171
00172 void ControlMapper::removeHandler(ControlEventHandler * pHandler, UINT orderIndex) {
00173 THandlerList & list = getHandlerList(orderIndex);
00174 THandlerList::iterator it = std::find(list.begin(), list.end(), pHandler);
00175 if (it != list.end()) {
00176
00177 pHandler->onRemovedFromControler(this);
00178 list.erase(it);
00179 } else LOG_ERROR << "Cannot remove given handler (does not exist in this ControlMapper, where orderIndex == " << orderIndex << ")" << std::endl;
00180 }
00181
00182 void ControlMapper::replaceHandler(ControlEventHandler * pOldHandler, ControlEventHandler * pNewHandler, UINT orderIndex) {
00183 if (pOldHandler == pNewHandler) return;
00184
00185 if (!pOldHandler) {
00186
00187 addHandlerBack(pNewHandler, orderIndex);
00188 return;
00189 }
00190 if (!pNewHandler) {
00191
00192 removeHandler(pNewHandler, orderIndex);
00193 return;
00194 }
00195
00196
00197 THandlerList & list = getHandlerList(orderIndex);
00198 THandlerList::iterator it = std::find(list.begin(), list.end(), pOldHandler);
00199 if (it == list.end()) THROW_TRACED_EXCEPTION("Cannot replace handler (old handler not found");
00200
00201 pOldHandler->onRemovedFromControler(this);
00202 ASSERT(*it == pOldHandler);
00203 *it = pNewHandler;
00204 pNewHandler->onAddedToControler(this);
00205 }
00206
00207 void ControlMapper::removeHandlers(UINT orderIndex) {
00208 THandlerListsList::iterator it = handlerLists.find(orderIndex);
00209 if (it == handlerLists.end()) return;
00210 BOOST_FOREACH(osg::observer_ptr<ControlEventHandler> & handler, it->second) {
00211 handler->onRemovedFromControler(this);
00212 }
00213 handlerLists.erase(it);
00214 }
00215
00216 void ControlMapper::removeDeletedHandlers() {
00217 THandlerList::iterator itSub;
00218 for(THandlerListsList::iterator it=handlerLists.begin(); it!=handlerLists.end(); ) {
00219 THandlerList & list = it->second;
00220 for(itSub=list.begin(); itSub!=list.end(); ) {
00221 if (!itSub->valid()) itSub = list.erase(itSub);
00222 else ++itSub;
00223 }
00224 if (it->second.empty()) {
00225 THandlerListsList::iterator itNext = it;
00226 ++itNext;
00227 handlerLists.erase(it);
00228 it = itNext;
00229 }
00230 else ++it;
00231 }
00232 }
00233
00234 bool ControlMapper::processHandlerLists(const ControlEvent & ce) {
00235 DBG_TRY_BLOCK_START
00236
00237 #ifdef PVLE_NETWORKING
00238 TNL::RefPtr<NetControlEvent> pEvent = new NetControlEvent(ce);
00239 #else
00240 NetControlEvent * pEvent = new NetControlEvent(ce);
00241 #endif
00242
00243
00244 bool handlerDeleted = false;
00245 for(THandlerListsList::iterator it=handlerLists.begin(), itEnd=handlerLists.end(); it!=itEnd; ++it) {
00246 BOOST_FOREACH(osg::observer_ptr<ControlEventHandler> & handler, it->second) {
00247 if (!handler) handlerDeleted = true;
00248 else if (handler->handleEvent(pEvent, pConnection)) {
00249 if (handlerDeleted) removeDeletedHandlers();
00250 #ifndef PVLE_NETWORKING
00251 delete pEvent;
00252 #endif
00253 return true;
00254 }
00255 }
00256 }
00257 if (handlerDeleted) removeDeletedHandlers();
00258 #ifndef PVLE_NETWORKING
00259 delete pEvent;
00260 #endif
00261 return false;
00262
00263 DBG_TRY_BLOCK_END
00264 }
00265
00266
00267 bool ControlMapper::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa) {
00268 DBG_TRY_BLOCK_START
00269
00270 ASSERT(pBindings && pAxisBindings);
00271
00272 double time = ea.time();
00273 bool pushed;
00274
00275
00276 pushed = ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN;
00277 if (pushed || ea.getEventType() == osgGA::GUIEventAdapter::KEYUP) {
00278 int key = ea.getKey();
00279 ControlState::ESwitchId mappedSwitch;
00280
00281 int keyLower = key;
00282 if (keyLower >= 'A' && keyLower <= 'Z') keyLower += 'a' - 'A';
00283 if (keyLower < 32) keyLower += 96;
00284
00285 Bindings::const_iterator it = pBindings->find(keyLower);
00286 if (it == pBindings->end()) {
00287
00288 if (sendUnmappedKeyboard) mappedSwitch = ControlState::NONE;
00289 else return false;
00290 }
00291 else mappedSwitch = it->second;
00292 processHandlerListsOrDoSwitch(time, mappedSwitch, key, pushed);
00293 return true;
00294 }
00295
00296 pushed = ea.getEventType() == osgGA::GUIEventAdapter::PUSH;
00297 if (pushed || ea.getEventType() == osgGA::GUIEventAdapter::RELEASE) {
00298 int key = BUTTON_MOUSE_MODIFIER + ea.getButton();
00299 ControlState::ESwitchId mappedSwitch;
00300 Bindings::const_iterator it = pBindings->find(key);
00301 if (it == pBindings->end()) {
00302
00303 if (sendUnmappedButtons) mappedSwitch = ControlState::NONE;
00304 else return false;
00305 }
00306 else mappedSwitch = it->second;
00307 processHandlerListsOrDoSwitch(time, mappedSwitch, key, pushed);
00308 return true;
00309 }
00310
00311
00312
00313 if (ea.getEventType() == osgGA::GUIEventAdapter::FRAME) {
00314
00315 processHandlerListsOrAppend(ControlEvent(time, ControlEvent::GFX_FRAME));
00316
00317
00318 int mouseX, mouseY;
00319 getMousePosition(&mouseX, &mouseY);
00320
00321 if (appHasFocus(aa, mouseX, mouseY))
00322 {
00323 if (mouseX!=prevMouseX || mouseX!=prevMouseY) {
00324
00325 {
00326 AxisBindings::const_iterator it0 = pAxisBindings->find(AXIS_MOUSE_MODIFIER + 0);
00327 AxisBindings::const_iterator it1 = pAxisBindings->find(AXIS_MOUSE_MODIFIER + 1);
00328
00329
00330 if (it0 != pAxisBindings->end()) processHandlerListsOrAxisMove(time, it0->second.axisId, computeMouseMovement(mouseX - prevMouseX, it0->second));
00331 if (it1 != pAxisBindings->end()) processHandlerListsOrAxisMove(time, it1->second.axisId, computeMouseMovement(mouseY - prevMouseY, it1->second));
00332 }
00333 state.setPointer(ea.getX(), ea.getY());
00334
00335 prevMouseX = mouseX;
00336 prevMouseY = mouseY;
00337
00338
00339 if (!pointerMouse) {
00340
00341
00342
00343
00344
00345
00346
00347
00348 float absX = ea.getXmin() + ea.getXmax()/2.f;
00349 float absY = ea.getYmin() + ea.getYmax()/2.f;
00350 aa.requestWarpPointer(absX, absY);
00351
00352
00353
00354
00355 getMousePosition(&mouseX, &mouseY);
00356 prevMouseX = mouseX;
00357 prevMouseY = mouseY;
00358 }
00359 }
00360 }
00361
00362 return false;
00363 }
00364
00365
00366 if (ea.getEventType() == osgGA::GUIEventAdapter::SCROLL)
00367 {
00368 pushed = ea.getScrollingMotion() == osgGA::GUIEventAdapter::SCROLL_UP;
00369 if (pushed || ea.getScrollingMotion() == osgGA::GUIEventAdapter::SCROLL_DOWN) {
00370 AxisBindings::const_iterator it = pAxisBindings->find(AXIS_MOUSE_MODIFIER + 2);
00371 if (it == pAxisBindings->end()) return false;
00372 processHandlerListsOrAxisMove(time, it->second.axisId, it->second.sensitivity * pushed ? 1 : -1);
00373 return true;
00374 }
00375 else {
00376 pushed = ea.getScrollingMotion() == osgGA::GUIEventAdapter::SCROLL_RIGHT;
00377 if (pushed || ea.getScrollingMotion() == osgGA::GUIEventAdapter::SCROLL_LEFT) {
00378 AxisBindings::const_iterator it = pAxisBindings->find(AXIS_MOUSE_MODIFIER + 3);
00379 if (it == pAxisBindings->end()) return false;
00380 processHandlerListsOrAxisMove(time, it->second.axisId, it->second.sensitivity * pushed ? 1 : -1);
00381 return true;
00382 }
00383 else if (ea.getScrollingMotion() == osgGA::GUIEventAdapter::SCROLL_2D) {
00384 AxisBindings::const_iterator itX = pAxisBindings->find(AXIS_MOUSE_MODIFIER + 2);
00385 AxisBindings::const_iterator itY = pAxisBindings->find(AXIS_MOUSE_MODIFIER + 3);
00386 if (itX != pAxisBindings->end()) processHandlerListsOrAxisMove(time, itX->second.axisId, itX->second.sensitivity * ea.getScrollingDeltaX());
00387 if (itY != pAxisBindings->end()) processHandlerListsOrAxisMove(time, itY->second.axisId, itY->second.sensitivity * ea.getScrollingDeltaY());
00388 if (itX == pAxisBindings->end() || itY != pAxisBindings->end()) return false;
00389 return true;
00390 }
00391 }
00392
00393
00394
00395 }
00396
00397
00398 if (ea.getEventType() == osgGA::GUIEventAdapter::RESIZE) {
00399 ControlEvent ce (time, ControlEvent::GFX_RESIZE);
00400 if (processHandlerLists(ce)) {
00401 vEvents.push_back(ce);
00402 return true;
00403 }
00404 return false;
00405 }
00406
00407 return false;
00408
00409 DBG_TRY_BLOCK_END
00410 }
00411
00412
00413
00414 float ControlMapper::computeMouseMovement(float mouseDiff, const AxisControl & ac) {
00415
00416 if ( fabs(mouseDiff) < ac.deadzone) return 0;
00417
00418 mouseDiff /= 1000.f;
00419
00420
00421 float beforePow = mouseDiff * ac.sensitivity;
00422 return copySign( powf(fabs(beforePow), ac.accel), beforePow );
00423
00424 }
00425
00426
00427 #include <osgUtil/LineSegmentIntersector>
00428 #include <osgViewer/View>
00429
00430 void ControlMapper::computePickPos(osgViewer::View & view, osg::NodePath * pPickNodePath) {
00431 if (pPickNodePath && pPickNodePath->empty()) return;
00432 osgUtil::LineSegmentIntersector::Intersections intersections;
00433 bool intersected;
00434 if (pPickNodePath) intersected = view.computeIntersections(state.getPointerX(), state.getPointerY(), *pPickNodePath, intersections);
00435 else intersected = view.computeIntersections(state.getPointerX(), state.getPointerY(), intersections);
00436 if (intersected)
00437 {
00438 ASSERT(intersections.size() <= 1);
00439 if (intersections.size()>0) state.setPickPosition(intersections.begin()->getWorldIntersectPoint());
00440
00441
00442
00443
00444
00445
00446 }
00447 }