FreeCAD

Форк
0
/
SpaceNavigatorDevice.cpp 
187 строк · 6.1 Кб
1
/**************************************************************************\
2
 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3
 * All rights reserved.
4
 * 
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are
7
 * met:
8
 * 
9
 * Redistributions of source code must retain the above copyright notice,
10
 * this list of conditions and the following disclaimer.
11
 * 
12
 * Redistributions in binary form must reproduce the above copyright
13
 * notice, this list of conditions and the following disclaimer in the
14
 * documentation and/or other materials provided with the distribution.
15
 * 
16
 * Neither the name of the copyright holder nor the names of its
17
 * contributors may be used to endorse or promote products derived from
18
 * this software without specific prior written permission.
19
 * 
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
\**************************************************************************/
32

33
#ifdef _MSC_VER
34
#pragma warning(disable : 4267)
35
#endif
36

37
#include <QEvent>
38
#include <QWidget>
39

40
#include <Inventor/events/SoEvent.h>
41
#include <Inventor/events/SoMotion3Event.h>
42
#include <Inventor/events/SoSpaceballButtonEvent.h>
43

44
#ifdef HAVE_SPACENAV_LIB
45
#include <QX11Info>
46
#include <spnav.h>
47
#endif
48

49
#include "NativeEvent.h"
50
#include "devices/SpaceNavigatorDevice.h"
51

52

53
namespace SIM { namespace Coin3D { namespace Quarter {
54
class SpaceNavigatorDeviceP {
55
public:
56
  explicit SpaceNavigatorDeviceP(SpaceNavigatorDevice * master) {
57
    this->master = master;
58
    this->hasdevice = false;
59
    this->windowid = 0;
60
    this->motionevent = new SoMotion3Event;
61
    this->buttonevent = new SoSpaceballButtonEvent;
62
  }
63
  ~SpaceNavigatorDeviceP() {
64
    delete this->motionevent;
65
    delete this->buttonevent;
66
  }
67

68
  static bool customEventFilter(void * message, long * result);
69

70
  SpaceNavigatorDevice * master;
71
  bool hasdevice;
72
  WId windowid;
73

74
  SoMotion3Event * motionevent;
75
  SoSpaceballButtonEvent * buttonevent;
76

77
};
78
}}}
79

80

81
#define PRIVATE(obj) obj->pimpl
82
using namespace SIM::Coin3D::Quarter;
83

84
SpaceNavigatorDevice::SpaceNavigatorDevice(QuarterWidget* quarter) :
85
  InputDevice(quarter)
86
{
87
  PRIVATE(this) = new SpaceNavigatorDeviceP(this);
88

89
#ifdef HAVE_SPACENAV_LIB
90
  PRIVATE(this)->hasdevice =
91
    spnav_x11_open(QX11Info::display(), PRIVATE(this)->windowid) == -1 ? false : true;
92

93
  // FIXME: Use a debugmessage mechanism instead? (20101020 handegar)
94
  if (!PRIVATE(this)->hasdevice) {
95
    fprintf(stderr, "Quarter:: Could not hook up to Spacenav device.\n");
96
  }
97

98
#endif // HAVE_SPACENAV_LIB
99
}
100

101
SpaceNavigatorDevice::~SpaceNavigatorDevice()
102
{
103
  delete PRIVATE(this);
104
}
105

106

107
const SoEvent *
108
SpaceNavigatorDevice::translateEvent(QEvent * event)
109
{
110
  Q_UNUSED(event); 
111
  SoEvent * ret = nullptr;
112

113
#ifdef HAVE_SPACENAV_LIB
114
  NativeEvent * ce = dynamic_cast<NativeEvent *>(event);
115
  if (ce && ce->getEvent()) {
116
    XEvent * xev = ce->getEvent();
117

118
    spnav_event spev;
119
    if(spnav_x11_event(xev, &spev)) {
120
      if(spev.type == SPNAV_EVENT_MOTION) {
121
        // Add rotation
122
        const float axislen = sqrt(spev.motion.rx*spev.motion.rx +
123
                                   spev.motion.ry*spev.motion.ry +
124
                                   spev.motion.rz*spev.motion.rz);
125

126
	const float half_angle = axislen * 0.5 * 0.001;
127
	const float sin_half = sin(half_angle);
128
        SbRotation rot((spev.motion.rx / axislen) * sin_half,
129
                       (spev.motion.ry / axislen) * sin_half,
130
                       (spev.motion.rz / axislen) * sin_half,
131
                       cos(half_angle));
132
        PRIVATE(this)->motionevent->setRotation(rot);
133

134
        // Add translation
135
        SbVec3f pos(spev.motion.x * 0.001,
136
                    spev.motion.y * 0.001,
137
                    spev.motion.z * 0.001);
138
        PRIVATE(this)->motionevent->setTranslation(pos);
139

140
        ret = PRIVATE(this)->motionevent;
141
      }
142
      else if (spev.type == SPNAV_EVENT_BUTTON){
143
        if(spev.button.press) {
144
          PRIVATE(this)->buttonevent->setState(SoButtonEvent::DOWN);
145
          switch(spev.button.bnum) {
146
          case 0: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON1);
147
            break;
148
          case 1: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON2);
149
            break;
150
          case 2: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON3);
151
            break;
152
          case 3: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON4);
153
            break;
154
          case 4: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON5);
155
            break;
156
          case 5: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON6);
157
            break;
158
          case 6: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON7);
159
            break;
160
          case 7: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON8);
161
            break;
162
          default:
163
            // FIXME: Which button corresponds to the
164
            // SoSpaceballButtonEvent::PICK enum? (20101020 handegar)
165
            break;
166
          }
167
        }
168
        else {
169
          PRIVATE(this)->buttonevent->setState(SoButtonEvent::UP);
170
        }
171

172
        ret = PRIVATE(this)->buttonevent;
173
      }
174
      else {
175
        // Unknown Spacenav event.
176
        assert(0 && "Unknown event type");
177
      }
178
    }
179
  }
180
#endif // HAVE_SPACENAV_LIB
181

182
  return ret;
183
}
184

185

186
#undef PRIVATE
187
#undef PUBLIC
188

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.