FreeCAD

Форк
0
/
SpaceNavigatorDevice.cpp 
203 строки · 6.5 Кб
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
  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()
85
{
86
  PRIVATE(this) = new SpaceNavigatorDeviceP(this);
87

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

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

97
#endif // HAVE_SPACENAV_LIB
98
}
99

100
SpaceNavigatorDevice::SpaceNavigatorDevice(QuarterWidget *quarter) :
101
    InputDevice(quarter)
102
{
103
    PRIVATE(this) = new SpaceNavigatorDeviceP(this);
104

105
#ifdef HAVE_SPACENAV_LIB
106
    PRIVATE(this)->hasdevice =
107
            spnav_x11_open(QX11Info::display(), PRIVATE(this)->windowid) == -1 ? false : true;
108

109
    // FIXME: Use a debugmessage mechanism instead? (20101020 handegar)
110
    if (!PRIVATE(this)->hasdevice) {
111
        fprintf(stderr, "Quarter:: Could not hook up to Spacenav device.\n");
112
    }
113

114
#endif // HAVE_SPACENAV_LIB
115
}
116

117
SpaceNavigatorDevice::~SpaceNavigatorDevice()
118
{
119
  delete PRIVATE(this);
120
}
121

122

123
const SoEvent *
124
SpaceNavigatorDevice::translateEvent(QEvent * event)
125
{
126
  Q_UNUSED(event); 
127
  SoEvent * ret = nullptr;
128

129
#ifdef HAVE_SPACENAV_LIB
130
  NativeEvent * ce = dynamic_cast<NativeEvent *>(event);
131
  if (ce && ce->getEvent()) {
132
    XEvent * xev = ce->getEvent();
133

134
    spnav_event spev;
135
    if(spnav_x11_event(xev, &spev)) {
136
      if(spev.type == SPNAV_EVENT_MOTION) {
137
        // Add rotation
138
        const float axislen = sqrt(spev.motion.rx*spev.motion.rx +
139
                                   spev.motion.ry*spev.motion.ry +
140
                                   spev.motion.rz*spev.motion.rz);
141

142
	const float half_angle = axislen * 0.5 * 0.001;
143
	const float sin_half = sin(half_angle);
144
        SbRotation rot((spev.motion.rx / axislen) * sin_half,
145
                       (spev.motion.ry / axislen) * sin_half,
146
                       (spev.motion.rz / axislen) * sin_half,
147
                       cos(half_angle));
148
        PRIVATE(this)->motionevent->setRotation(rot);
149

150
        // Add translation
151
        SbVec3f pos(spev.motion.x * 0.001,
152
                    spev.motion.y * 0.001,
153
                    spev.motion.z * 0.001);
154
        PRIVATE(this)->motionevent->setTranslation(pos);
155

156
        ret = PRIVATE(this)->motionevent;
157
      }
158
      else if (spev.type == SPNAV_EVENT_BUTTON){
159
        if(spev.button.press) {
160
          PRIVATE(this)->buttonevent->setState(SoButtonEvent::DOWN);
161
          switch(spev.button.bnum) {
162
          case 0: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON1);
163
            break;
164
          case 1: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON2);
165
            break;
166
          case 2: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON3);
167
            break;
168
          case 3: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON4);
169
            break;
170
          case 4: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON5);
171
            break;
172
          case 5: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON6);
173
            break;
174
          case 6: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON7);
175
            break;
176
          case 7: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON8);
177
            break;
178
          default:
179
            // FIXME: Which button corresponds to the
180
            // SoSpaceballButtonEvent::PICK enum? (20101020 handegar)
181
            break;
182
          }
183
        }
184
        else {
185
          PRIVATE(this)->buttonevent->setState(SoButtonEvent::UP);
186
        }
187

188
        ret = PRIVATE(this)->buttonevent;
189
      }
190
      else {
191
        // Unknown Spacenav event.
192
        assert(0 && "Unknown event type");
193
      }
194
    }
195
  }
196
#endif // HAVE_SPACENAV_LIB
197

198
  return ret;
199
}
200

201

202
#undef PRIVATE
203
#undef PUBLIC
204

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

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

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

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