0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / WNT / WNT_HIDSpaceMouse.cxx
CommitLineData
d6fbb2ab 1// Copyright (c) 2019-2020 OPEN CASCADE SAS
2//
3// This file is part of Open CASCADE Technology software library.
4//
5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
10//
11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
13
14#include <WNT_HIDSpaceMouse.hxx>
15
16namespace
17{
18 //! Enumeration of known Space Mouse models.
19 enum SpacePid
20 {
21 // VENDOR_ID_LOGITECH
22 SpacePid_SpaceMouse = 0xC603,
23 SpacePid_CADMan = 0xC605,
24 SpacePid_SpaceMouseClassic = 0xC606,
25 SpacePid_SpaceBall5000 = 0xC621,
26 SpacePid_SpaceTraveler = 0xC623,
27 SpacePid_SpacePilot = 0xC625,
28 SpacePid_SpaceNavigator = 0xC626, //!< has only 2 "menu" buttons (second one is treated as SpaceVKey_Fit)
29 SpacePid_SpaceExplorer = 0xC627, //!< 15 buttons
30 SpacePid_NavigatorForNotebooks = 0xC628, //!< has only 2 "menu" buttons (second one is treated as SpaceVKey_Fit)
31 SpacePid_SpacePilotPro = 0xC629, //!< 31 buttons
32 SpacePid_SpaceMousePro = 0xC62B, //!< has only 15 buttons, but codes range from 0 to 26
33 // VENDOR_ID_3DCONNEXION
34 SpacePid_SpaceMouseWireless1 = 0xC62E, //!< [plugged in] has only 2 buttons
35 SpacePid_SpaceMouseWireless2 = 0xC62F, //!< [wireless] has only 2 buttons
36 SpacePid_SpaceMouseProWireless1 = 0xC631, //!< [plugged in] has only 15 buttons
37 SpacePid_SpaceMouseProWireless2 = 0xC632, //!< [wireless] has only 15 buttons
38 SpacePid_SpaceMouseEnterprise = 0xC633, //!< 31 buttons
39 SpacePid_SpaceMouseCompact = 0xC635
40 };
41
42 //! Enumeration of known keys available on various Space Mouse models.
43 enum SpaceVKey
44 {
45 SpaceVKey_INVALID = 0,
46 SpaceVKey_Menu = 1, SpaceVKey_Fit,
47 SpaceVKey_Top, SpaceVKey_Left, SpaceVKey_Right, SpaceVKey_Front, SpaceVKey_Bottom, SpaceVKey_Back,
48 SpaceVKey_RollCW, SpaceVKey_RollCCW,
49 SpaceVKey_ISO1, SpaceVKey_ISO2,
50 SpaceVKey_1, SpaceVKey_2, SpaceVKey_3, SpaceVKey_4, SpaceVKey_5, SpaceVKey_6, SpaceVKey_7, SpaceVKey_8, SpaceVKey_9, SpaceVKey_10,
51 SpaceVKey_Esc, SpaceVKey_Alt, SpaceVKey_Shift, SpaceVKey_Ctrl,
52 SpaceVKey_Rotate, SpaceVKey_PanZoom, SpaceVKey_Dominant,
53 SpaceVKey_Plus, SpaceVKey_Minus,
54 };
55
56 //! The raw value range on tested device is [-350; 350].
57 enum { THE_RAW_RANGE_350 = 350 };
58
59 //! Convert key state bit into virtual key.
60 static SpaceVKey hidToSpaceKey (unsigned long theProductId,
61 unsigned short theKeyBit)
62 {
63 static const SpaceVKey THE_PILOT_KEYS[] =
64 {
65 SpaceVKey_1, SpaceVKey_2, SpaceVKey_3, SpaceVKey_4, SpaceVKey_5, SpaceVKey_6,
66 SpaceVKey_Top, SpaceVKey_Left, SpaceVKey_Right, SpaceVKey_Front,
67 SpaceVKey_Esc, SpaceVKey_Alt, SpaceVKey_Shift, SpaceVKey_Ctrl,
68 SpaceVKey_Fit, SpaceVKey_Menu,
69 SpaceVKey_Plus, SpaceVKey_Minus,
70 SpaceVKey_Dominant, SpaceVKey_Rotate
71 };
72 const int THE_NB_PILOT_KEYS = sizeof(THE_PILOT_KEYS) / sizeof(SpaceVKey);
73
74 static const SpaceVKey THE_EXPLORER_KEYS[] =
75 {
76 SpaceVKey_1, SpaceVKey_2,
77 SpaceVKey_Top, SpaceVKey_Left, SpaceVKey_Right, SpaceVKey_Front,
78 SpaceVKey_Esc, SpaceVKey_Alt, SpaceVKey_Shift, SpaceVKey_Ctrl,
79 SpaceVKey_Fit, SpaceVKey_Menu,
80 SpaceVKey_Plus, SpaceVKey_Minus,
81 SpaceVKey_Rotate
82 };
83 const int THE_NB_EXPLORER_KEYS = sizeof(THE_EXPLORER_KEYS) / sizeof(SpaceVKey);
84
85 // shared by latest 3Dconnexion hardware
86 static const SpaceVKey THE_SPACEMOUSEPRO_KEYS[] =
87 {
88 SpaceVKey_Menu, SpaceVKey_Fit,
89 SpaceVKey_Top, SpaceVKey_Left, SpaceVKey_Right, SpaceVKey_Front, SpaceVKey_Bottom, SpaceVKey_Back,
90 SpaceVKey_RollCW, SpaceVKey_RollCCW, SpaceVKey_ISO1, SpaceVKey_ISO2,
91 SpaceVKey_1, SpaceVKey_2, SpaceVKey_3, SpaceVKey_4,
92 SpaceVKey_5, SpaceVKey_6, SpaceVKey_7, SpaceVKey_8, SpaceVKey_9, SpaceVKey_10,
93 SpaceVKey_Esc, SpaceVKey_Alt, SpaceVKey_Shift, SpaceVKey_Ctrl,
94 SpaceVKey_Rotate,
95 SpaceVKey_PanZoom, SpaceVKey_Dominant, SpaceVKey_Plus, SpaceVKey_Minus
96 };
97 const int THE_NB_SPACEMOUSEPRO_KEYS = sizeof(THE_SPACEMOUSEPRO_KEYS) / sizeof(SpaceVKey);
98
99 switch (theProductId)
100 {
101 case SpacePid_SpacePilot:
102 return theKeyBit < THE_NB_PILOT_KEYS ? THE_PILOT_KEYS[theKeyBit] : SpaceVKey_INVALID;
103 case SpacePid_SpaceExplorer:
104 return theKeyBit < THE_NB_EXPLORER_KEYS ? THE_EXPLORER_KEYS[theKeyBit] : SpaceVKey_INVALID;
105 case SpacePid_SpaceNavigator:
106 case SpacePid_NavigatorForNotebooks:
107 case SpacePid_SpacePilotPro:
108 case SpacePid_SpaceMousePro:
109 case SpacePid_SpaceMouseWireless1:
110 case SpacePid_SpaceMouseWireless2:
111 case SpacePid_SpaceMouseProWireless1:
112 case SpacePid_SpaceMouseProWireless2:
113 case SpacePid_SpaceMouseEnterprise:
114 case SpacePid_SpaceMouseCompact:
115 return theKeyBit < THE_NB_SPACEMOUSEPRO_KEYS ? THE_SPACEMOUSEPRO_KEYS[theKeyBit] : SpaceVKey_INVALID;
116 }
117 return SpaceVKey_INVALID;
118 }
119
120}
121
122// =======================================================================
123// function : WNT_HIDSpaceMouse
124// purpose :
125// =======================================================================
126WNT_HIDSpaceMouse::WNT_HIDSpaceMouse (unsigned long theProductId,
127 const Standard_Byte* theData,
128 Standard_Size theSize)
129: myData (theData),
130 mySize (theSize),
131 myProductId (theProductId),
132 myValueRange (THE_RAW_RANGE_350)
133{
134 //
135}
136
137// =======================================================================
138// function : IsKnownProduct
139// purpose :
140// =======================================================================
141bool WNT_HIDSpaceMouse::IsKnownProduct (unsigned long theProductId)
142{
143 switch (theProductId)
144 {
145 case SpacePid_SpacePilot:
146 case SpacePid_SpaceExplorer:
147 case SpacePid_SpaceNavigator:
148 case SpacePid_NavigatorForNotebooks:
149 case SpacePid_SpacePilotPro:
150 case SpacePid_SpaceMousePro:
151 case SpacePid_SpaceMouseWireless1:
152 case SpacePid_SpaceMouseWireless2:
153 case SpacePid_SpaceMouseProWireless1:
154 case SpacePid_SpaceMouseProWireless2:
155 case SpacePid_SpaceMouseEnterprise:
156 case SpacePid_SpaceMouseCompact:
157 return true;
158 }
159 return false;
160}
161
162// =======================================================================
163// function : Translation
164// purpose :
165// =======================================================================
166Graphic3d_Vec3d WNT_HIDSpaceMouse::Translation (bool& theIsIdle,
167 bool theIsQuadric) const
168{
169 theIsIdle = true;
170 return myData[0] == SpaceRawInput_Translation
171 && (mySize == 7 || mySize == 13)
172 ? fromRawVec3 (theIsIdle, myData + 1, true, theIsQuadric)
173 : Graphic3d_Vec3d();
174}
175
176// =======================================================================
177// function : Rotation
178// purpose :
179// =======================================================================
180Graphic3d_Vec3d WNT_HIDSpaceMouse::Rotation (bool& theIsIdle,
181 bool theIsQuadric) const
182{
183 theIsIdle = true;
184 if (myData[0] == SpaceRawInput_Rotation && mySize == 7)
185 {
186 return fromRawVec3 (theIsIdle, myData + 1, false, theIsQuadric);
187 }
188 else if (myData[0] == SpaceRawInput_Translation && mySize == 13)
189 {
190 return fromRawVec3 (theIsIdle, myData + 7, false, theIsQuadric);
191 }
192 return Graphic3d_Vec3d();
193}
194
195// =======================================================================
196// function : fromRawVec3
197// purpose :
198// =======================================================================
199Graphic3d_Vec3d WNT_HIDSpaceMouse::fromRawVec3 (bool& theIsIdle,
200 const Standard_Byte* theData,
201 bool theIsTrans,
202 bool theIsQuadric) const
203{
204 theIsIdle = true;
205 const NCollection_Vec3<int16_t>& aRaw16 = *reinterpret_cast<const NCollection_Vec3<int16_t>*>(theData);
206 Graphic3d_Vec3d aVec (aRaw16.x(), aRaw16.y(), aRaw16.z());
207 if (theIsTrans)
208 {
209 static const int16_t THE_MIN_RAW_TRANS = 4;
210 static const int16_t THE_MIN_RAW_TRANS_Z = 8;
211 for (int aCompIter = 0; aCompIter < 3; ++aCompIter)
212 {
213 if (aRaw16[aCompIter] > -THE_MIN_RAW_TRANS && aRaw16[aCompIter] < THE_MIN_RAW_TRANS)
214 {
215 aVec[aCompIter] = 0.0;
216 }
217 else
218 {
219 theIsIdle = false;
220 }
221 }
222 if (aRaw16.z() > -THE_MIN_RAW_TRANS_Z && aRaw16.z() < THE_MIN_RAW_TRANS_Z)
223 {
224 aVec.z() = 0.0;
225 }
226 }
227 else
228 {
229 for (int aCompIter = 0; aCompIter < 3; ++aCompIter)
230 {
231 if (aRaw16[aCompIter] != 0)
232 {
233 theIsIdle = false;
234 break;
235 }
236 }
237 }
238
239 // determine raw value range
240 for (int aCompIter = 0; aCompIter < 3; ++aCompIter)
241 {
242 if (aRaw16[aCompIter] > myValueRange
243 || -aRaw16[aCompIter] > myValueRange)
244 {
245 myValueRange = 32767; // SHRT_MAX
246 break;
247 }
248 }
249
250 if (!theIsQuadric)
251 {
252 return aVec / double(myValueRange);
253 }
254
255 for (int aCompIter = 0; aCompIter < 3; ++aCompIter)
256 {
257 aVec[aCompIter] = aRaw16[aCompIter] > 0
258 ? aVec[aCompIter] * aVec[aCompIter]
259 : -aVec[aCompIter] * aVec[aCompIter];
260 }
261 return aVec / (double(myValueRange) * double(myValueRange));
262}
263
264// =======================================================================
265// function : HidToSpaceKey
266// purpose :
267// =======================================================================
268Aspect_VKey WNT_HIDSpaceMouse::HidToSpaceKey (unsigned short theKeyBit) const
269{
270 const SpaceVKey aKey = hidToSpaceKey (myProductId, theKeyBit);
271 switch (aKey)
272 {
273 case SpaceVKey_1:
274 case SpaceVKey_2:
275 case SpaceVKey_3:
276 case SpaceVKey_4:
277 case SpaceVKey_5:
278 case SpaceVKey_6:
279 case SpaceVKey_7:
280 case SpaceVKey_8:
281 case SpaceVKey_9:
282 case SpaceVKey_10:
283 return (int(aKey) - int(SpaceVKey_1)) + Aspect_VKey_1;
284 case SpaceVKey_Esc:
285 return Aspect_VKey_Escape;
286 case SpaceVKey_Shift:
287 return Aspect_VKey_Shift;
288 case SpaceVKey_Alt:
289 return Aspect_VKey_Alt;
290 case SpaceVKey_Ctrl:
291 return Aspect_VKey_Control;
292 case SpaceVKey_Top:
293 return Aspect_VKey_ViewTop;
294 case SpaceVKey_Bottom:
295 return Aspect_VKey_ViewBottom;
296 case SpaceVKey_Left:
297 return Aspect_VKey_ViewLeft;
298 case SpaceVKey_Right:
299 return Aspect_VKey_ViewRight;
300 case SpaceVKey_Front:
301 return Aspect_VKey_ViewFront;
302 case SpaceVKey_Back:
303 return Aspect_VKey_ViewBack;
304 case SpaceVKey_ISO1:
305 return Aspect_VKey_ViewAxoLeftProj;
306 case SpaceVKey_ISO2:
307 return Aspect_VKey_ViewAxoRightProj;
308 case SpaceVKey_Fit:
309 return Aspect_VKey_ViewFitAll;
310 case SpaceVKey_RollCW:
311 return Aspect_VKey_ViewRoll90CW;
312 case SpaceVKey_RollCCW:
313 return Aspect_VKey_ViewRoll90CCW;
314 case SpaceVKey_Rotate:
315 return Aspect_VKey_ViewSwitchRotate;
316 default:
317 break;
318 }
319 return Aspect_VKey_UNKNOWN;
320}