0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / WNT / WNT_HIDSpaceMouse.hxx
... / ...
CommitLineData
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#ifndef _WNT_HIDSpaceMouse_Header
15#define _WNT_HIDSpaceMouse_Header
16
17#include <Aspect_VKey.hxx>
18#include <Graphic3d_Vec.hxx>
19
20//! Wrapper over Space Mouse data chunk within WM_INPUT event (known also as Raw Input in WinAPI).
21//! This class predefines specific list of supported devices, which does not depend on 3rdparty library provided by mouse vendor.
22//! Supported input chunks:
23//! - Rotation (3 directions);
24//! - Translation (3 directions);
25//! - Pressed buttons.
26//!
27//! To use the class, register Raw Input device:
28//! @code
29//! Handle(WNT_Window) theWindow;
30//! RAWINPUTDEVICE aRawInDevList[1];
31//! RAWINPUTDEVICE& aRawSpace = aRawInDevList[0];
32//! aRawSpace.usUsagePage = HID_USAGE_PAGE_GENERIC;
33//! aRawSpace.usUsage = HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER;
34//! aRawSpace.dwFlags = 0; // RIDEV_DEVNOTIFY
35//! aRawSpace.hwndTarget = (HWND )theWindow->NativeHandle();
36//! if (!::RegisterRawInputDevices (aRawInDevList, 1, sizeof(aRawInDevList[0]))) { Error; }
37//! @endcode
38//!
39//! Then handle WM_INPUT events within window message loop.
40//! @code
41//! AIS_ViewController theViewCtrl;
42//! case WM_INPUT:
43//! {
44//! UINT aSize = 0;
45//! ::GetRawInputData ((HRAWINPUT )theLParam, RID_INPUT, NULL, &aSize, sizeof(RAWINPUTHEADER));
46//! NCollection_LocalArray<BYTE> aRawData (aSize); // receive Raw Input for any device and process known devices
47//! if (aSize == 0 || ::GetRawInputData ((HRAWINPUT )theLParam, RID_INPUT, aRawData, &aSize, sizeof(RAWINPUTHEADER)) != aSize)
48//! {
49//! break;
50//! }
51//! const RAWINPUT* aRawInput = (RAWINPUT* )(BYTE* )aRawData;
52//! if (aRawInput->header.dwType != RIM_TYPEHID)
53//! {
54//! break;
55//! }
56//!
57//! RID_DEVICE_INFO aDevInfo; aDevInfo.cbSize = sizeof(RID_DEVICE_INFO);
58//! UINT aDevInfoSize = sizeof(RID_DEVICE_INFO);
59//! if (::GetRawInputDeviceInfoW (aRawInput->header.hDevice, RIDI_DEVICEINFO, &aDevInfo, &aDevInfoSize) != sizeof(RID_DEVICE_INFO)
60//! || (aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_LOGITECH
61//! && aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_3DCONNEXION))
62//! {
63//! break;
64//! }
65//!
66//! Aspect_VKeySet& aKeys = theViewCtrl.ChangeKeys();
67//! const double aTimeStamp = theViewCtrl.EventTime();
68//! WNT_HIDSpaceMouse aSpaceData (aDevInfo.hid.dwProductId, aRawInput->data.hid.bRawData, aRawInput->data.hid.dwSizeHid);
69//! if (aSpaceData.IsTranslation())
70//! {
71//! // process translation input
72//! bool isIdle = true, isQuadric = true;
73//! const Graphic3d_Vec3d aTrans = aSpaceData.Translation (isIdle, isQuadric);
74//! aKeys.KeyFromAxis (Aspect_VKey_NavSlideLeft, Aspect_VKey_NavSlideRight, aTimeStamp, aTrans.x());
75//! aKeys.KeyFromAxis (Aspect_VKey_NavForward, Aspect_VKey_NavBackward, aTimeStamp, aTrans.y());
76//! aKeys.KeyFromAxis (Aspect_VKey_NavSlideUp, Aspect_VKey_NavSlideDown, aTimeStamp, aTrans.z());
77//! }
78//! if (aSpaceData.IsRotation()) {} // process rotation input
79//! if (aSpaceData.IsKeyState()) {} // process keys input
80//! break;
81//! }
82//! @endcode
83class WNT_HIDSpaceMouse
84{
85public:
86 //! Vendor HID identifier.
87 enum { VENDOR_ID_LOGITECH = 0x46D, VENDOR_ID_3DCONNEXION = 0x256F };
88
89 //! Return if product id is known by this class.
90 Standard_EXPORT static bool IsKnownProduct (unsigned long theProductId);
91
92public:
93 //! Main constructor.
94 Standard_EXPORT WNT_HIDSpaceMouse (unsigned long theProductId,
95 const Standard_Byte* theData,
96 Standard_Size theSize);
97
98 //! Return the raw value range.
99 int16_t RawValueRange() const { return myValueRange; }
100
101 //! Set the raw value range.
102 void SetRawValueRange (int16_t theRange) { myValueRange = theRange > myValueRange ? theRange : myValueRange; }
103
104 //! Return TRUE if data chunk defines new translation values.
105 bool IsTranslation() const
106 {
107 return myData[0] == SpaceRawInput_Translation
108 && (mySize == 7 || mySize == 13);
109 }
110
111 //! Return new translation values.
112 //! @param theIsIdle [out] flag indicating idle state (no translation)
113 //! @param theIsQuadric [in] flag to apply non-linear scale factor
114 //! @return vector of 3 elements defining translation values within [-1..1] range, 0 meaning idle,
115 //! .x defining left/right slide, .y defining forward/backward and .z defining up/down slide.
116 Standard_EXPORT Graphic3d_Vec3d Translation (bool& theIsIdle,
117 bool theIsQuadric) const;
118
119 //! Return TRUE if data chunk defines new rotation values.
120 bool IsRotation() const
121 {
122 return (myData[0] == SpaceRawInput_Rotation && mySize == 7)
123 || (myData[0] == SpaceRawInput_Translation && mySize == 13);
124 }
125
126 //! Return new rotation values.
127 //! @param theIsIdle [out] flag indicating idle state (no rotation)
128 //! @param theIsQuadric [in] flag to apply non-linear scale factor
129 //! @return vector of 3 elements defining rotation values within [-1..1] range, 0 meaning idle,
130 //! .x defining tilt, .y defining roll and .z defining spin.
131 Standard_EXPORT Graphic3d_Vec3d Rotation (bool& theIsIdle,
132 bool theIsQuadric) const;
133
134 //! Return TRUE for key state data chunk.
135 bool IsKeyState() const { return myData[0] == SpaceRawInput_KeyState; }
136
137 //! Return new keystate.
138 uint32_t KeyState() const { return *reinterpret_cast<const uint32_t*>(myData + 1); }
139
140 //! Convert key state bit into virtual key.
141 Standard_EXPORT Aspect_VKey HidToSpaceKey (unsigned short theKeyBit) const;
142
143private:
144
145 //! Translate raw data chunk of 3 int16 values into normalized vec3.
146 //! The values are considered within the range [-350; 350], with 0 as neutral state.
147 Graphic3d_Vec3d fromRawVec3 (bool& theIsIdle,
148 const Standard_Byte* theData,
149 bool theIsTrans,
150 bool theIsQuadric) const;
151
152 //! Data chunk type.
153 enum
154 {
155 SpaceRawInput_Translation = 0x01, //!< translation data chunk
156 SpaceRawInput_Rotation = 0x02, //!< rotation data chunk
157 SpaceRawInput_KeyState = 0x03, //!< keystate data chunk
158 };
159
160private:
161 const Standard_Byte* myData; //!< RAW data chunk
162 Standard_Size mySize; //!< size of RAW data chunk
163 unsigned long myProductId; //!< product id
164 mutable int16_t myValueRange; //!< RAW value range
165};
166
167#endif // _WNT_HIDSpaceMouse_Header