Skip to content

Commit cdf181b

Browse files
author
lawwong
committed
Update to v1.10.1
* New Features - SteamVR Plugin v2.0/v2.1 support - SteamVR New Input System support ([Guide](https://github.com/ViveSoftware/ViveInputUtility-Unity/wiki/SteamVR-Input-System-Support)) * Improvement - Now compatible with Google VR SDK v1.170.0 - Add ControllerAxis.Joystick for Windows Mixed Reality Motion Controller - Extend ControllerButton (DPadXXX are virtual buttons simulated from trackpad/thumbstick values) - BKey (Menu) - BkeyTouch (MenuTouch) - Bumper (Axis3) - BumperTouch (Axis3Touch) - ProximitySensor - DPadLeft - DPadLeftTouch - DPadUp - DPadUpTouch - DPadRight - DPadRightTouch - DPadDown - DPadDownTouch - DPadUpperLeft - DPadUpperLeftTouch - DPadUpperRight - DPadUpperRightTouch - DPadLowerRight - DPadLowerRightTouch - DPadLowerLeft - DPadLowerLeftTouch * Known Issue - When working with SteamVR Plugin v2, VIU can get poses or send vibration pulses for all connected devices, but only able to connect button inputs from up to 2 Vive Controllers or 10 Vive Trackers (due to the limitation of SteamVR input sources). If you know how to work around, please let us know.
2 parents db5b52f + 2f0e732 commit cdf181b

File tree

7 files changed

+233
-90
lines changed

7 files changed

+233
-90
lines changed

Assets/HTC.UnityPlugin/Utility/Attribute/Editor/FlagsFromEnumAttributeDrawer.cs

Lines changed: 153 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,181 @@
11
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. ===========
22

3+
using System.Collections.Generic;
34
using UnityEditor;
45
using UnityEngine;
56

67
namespace HTC.UnityPlugin.Utility
78
{
89
[CustomPropertyDrawer(typeof(FlagsFromEnumAttribute))]
10+
[CanEditMultipleObjects]
911
public class FlagsFromEnumAttributeDrawer : PropertyDrawer
1012
{
11-
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
13+
private static GUIStyle s_popup;
14+
private static GUIContent s_tempContent;
15+
private static List<bool> s_displayedMask;
16+
17+
private bool m_foldoutOpen = false;
18+
19+
private static GUIContent GetTextContent(string text) { s_tempContent.text = text; return s_tempContent; }
20+
21+
static FlagsFromEnumAttributeDrawer()
22+
{
23+
s_popup = new GUIStyle(EditorStyles.popup);
24+
s_tempContent = new GUIContent();
25+
s_displayedMask = new List<bool>();
26+
}
27+
28+
private bool TryGetEnumInfo(out EnumUtils.EnumDisplayInfo info)
1229
{
13-
// First get the attribute since it contains the range for the slider
1430
var ffeAttribute = attribute as FlagsFromEnumAttribute;
1531

32+
if (ffeAttribute.EnumType == null || !ffeAttribute.EnumType.IsEnum)
33+
{
34+
info = null;
35+
return false;
36+
}
37+
38+
info = EnumUtils.GetDisplayInfo(ffeAttribute.EnumType);
39+
return info != null;
40+
}
41+
42+
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
43+
{
44+
EnumUtils.EnumDisplayInfo enumInfo;
45+
46+
if (!m_foldoutOpen || !TryGetEnumInfo(out enumInfo))
47+
{
48+
return EditorGUIUtility.singleLineHeight;
49+
}
50+
else
51+
{
52+
return EditorGUIUtility.singleLineHeight * (enumInfo.displayedMaskNames.Length + 2);
53+
}
54+
}
55+
56+
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
57+
{
1658
EditorGUI.BeginProperty(position, label, property);
1759

60+
EnumUtils.EnumDisplayInfo enumInfo;
61+
1862
if (property.propertyType != SerializedPropertyType.Integer)
1963
{
2064
EditorGUI.LabelField(position, label.text, "Use FlagFromEnum with integer.");
2165
}
22-
else if (ffeAttribute.EnumType == null || !ffeAttribute.EnumType.IsEnum)
66+
else if (!TryGetEnumInfo(out enumInfo))
2367
{
2468
EditorGUI.LabelField(position, label.text, "Set FlagFromEnum argument with enum type.");
2569
}
2670
else
2771
{
28-
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), new GUIContent(property.displayName));
72+
position = EditorGUI.PrefixLabel(position, new GUIContent(property.displayName));
73+
74+
// get display mask value
75+
s_displayedMask.Clear();
76+
var enumDisplayLength = enumInfo.displayedMaskLength;
77+
var realMask = (ulong)property.longValue;
78+
var firstSelected = string.Empty;
79+
for (int i = 0; i < enumDisplayLength; ++i)
80+
{
81+
if (EnumUtils.GetFlag(realMask, enumInfo.displayedMaskValues[i]))
82+
{
83+
s_displayedMask.Add(true);
84+
if (string.IsNullOrEmpty(firstSelected)) { firstSelected = enumInfo.displayedMaskNames[i]; }
85+
}
86+
else
87+
{
88+
s_displayedMask.Add(false);
89+
}
90+
}
91+
92+
var flagsCount = 0;
93+
for (var i = 0; i < EnumUtils.ULONG_MASK_FIELD_LENGTH; ++i)
94+
{
95+
if (EnumUtils.GetFlag(realMask, i)) { ++flagsCount; }
96+
}
97+
98+
if (EditorGUI.showMixedValue)
99+
{
100+
s_tempContent.text = " - ";
101+
}
102+
else if (flagsCount == 0)
103+
{
104+
s_tempContent.text = "None";
105+
}
106+
else if (flagsCount == 1)
107+
{
108+
s_tempContent.text = firstSelected;
109+
}
110+
else if (flagsCount < enumDisplayLength)
111+
{
112+
s_tempContent.text = "Mixed...";
113+
}
114+
else
115+
{
116+
s_tempContent.text = "All";
117+
}
118+
119+
var controlPos = position;
120+
controlPos.height = EditorGUIUtility.singleLineHeight;
121+
var id = GUIUtility.GetControlID(FocusType.Passive, controlPos);
122+
123+
switch (Event.current.GetTypeForControl(id))
124+
{
125+
case EventType.MouseDown:
126+
if (controlPos.Contains(Event.current.mousePosition))
127+
{
128+
GUIUtility.hotControl = id;
129+
GUIUtility.keyboardControl = id;
130+
Event.current.Use();
131+
}
132+
break;
133+
case EventType.MouseUp:
134+
if (GUIUtility.hotControl == id)
135+
{
136+
GUIUtility.hotControl = 0;
137+
GUIUtility.keyboardControl = 0;
138+
Event.current.Use();
139+
m_foldoutOpen = !m_foldoutOpen;
140+
}
141+
break;
142+
case EventType.Repaint:
143+
s_popup.Draw(position, s_tempContent, id, false);
144+
break;
145+
}
146+
147+
if (m_foldoutOpen)
148+
{
149+
position.y += EditorGUIUtility.singleLineHeight;
150+
151+
var halfWidth = position.width * 0.5f;
152+
if (GUI.Button(new Rect(position.x, position.y, halfWidth - 1, EditorGUIUtility.singleLineHeight), "All"))
153+
{
154+
realMask = ~0ul;
155+
//m_foldoutOpen = false;
156+
}
157+
158+
//Draw the None button
159+
if (GUI.Button(new Rect(position.x + halfWidth + 1, position.y, halfWidth - 1, EditorGUIUtility.singleLineHeight), "None"))
160+
{
161+
realMask = 0ul;
162+
//m_foldoutOpen = false;
163+
}
164+
165+
for (int i = 0; i < enumDisplayLength; ++i)
166+
{
167+
position.y += EditorGUIUtility.singleLineHeight;
168+
var toggled = EditorGUI.ToggleLeft(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), enumInfo.displayedMaskNames[i], s_displayedMask[i]);
169+
if (s_displayedMask[i] != toggled)
170+
{
171+
s_displayedMask[i] = toggled;
172+
EnumUtils.SetFlag(ref realMask, enumInfo.displayedMaskValues[i], toggled);
173+
//m_foldoutOpen = false;
174+
}
175+
}
29176

30-
var enumInfo = EnumUtils.GetDisplayInfo(ffeAttribute.EnumType);
31-
var realMask = property.intValue;
32-
var oldDisplayedMask = enumInfo.RealToDisplayedMaskField(realMask);
33-
var newDisplayedMask = EditorGUI.MaskField(position, oldDisplayedMask, enumInfo.displayedMaskNames);
34-
property.intValue = enumInfo.DisplayedToRealMaskField(newDisplayedMask, (uint)newDisplayedMask > (uint)oldDisplayedMask);
177+
property.longValue = (long)realMask;
178+
}
35179
}
36180

37181
property.serializedObject.ApplyModifiedProperties();

Assets/HTC.UnityPlugin/Utility/EnumUtils.cs

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public static class EnumUtils
2727
// Default = 0,
2828
// EEE,
2929
// FFF,
30+
// GGG = 65,
3031
// }
3132
//
3233
// EnumDisplayInfo for typeof(SomeEnum) will be:
@@ -39,6 +40,7 @@ public static class EnumUtils
3940
// BBB | 1
4041
// FFF | 2
4142
// CCC | 35
43+
// GGG | 65
4244
// zzz | -2
4345
// Invalid | -1
4446
//
@@ -52,14 +54,16 @@ public static class EnumUtils
5254
// Default (AAA) | Default | 0
5355
// EEE (BBB) | EEE | 1
5456
// FFF | FFF | 2
57+
// GGG | GGG | 65
5558
//
5659
// displayedMaskNames | displayedMaskRawNames | displayedMaskValues | realMaskField
5760
// ---------------------------------------------------------------------------------
58-
// AAA | AAA | 0 | 1u << 0
59-
// BBB | BBB | 1 | 1u << 1
60-
// Default (AAA) | Default | 0 | 1u << 0
61-
// EEE (BBB) | EEE | 1 | 1u << 1
62-
// FFF | FFF | 2 | 1u << 2
61+
// AAA | AAA | 0 | 1ul << 0
62+
// BBB | BBB | 1 | 1ul << 1
63+
// CCC | CCC | 35 | 1ul << 35
64+
// Default (AAA) | Default | 0 | 1ul << 0
65+
// EEE (BBB) | EEE | 1 | 1ul << 1
66+
// FFF | FFF | 2 | 1ul << 2
6367

6468
public class EnumDisplayInfo
6569
{
@@ -73,21 +77,21 @@ public class EnumDisplayInfo
7377
public Dictionary<int, int> rawValue2index { get; private set; }
7478
public Dictionary<string, int> rawName2index { get; private set; }
7579

80+
public int displayedLength { get { return displayedRawNames.Length; } }
7681
public string[] displayedRawNames { get; private set; } // without parenthesis
7782
public string[] displayedNames { get; private set; }
7883
public int[] displayedValues { get; private set; }
7984
public Dictionary<int, int> value2displayedIndex { get; private set; }
8085
public Dictionary<string, int> name2displayedIndex { get; private set; }
8186

87+
public int displayedMaskLength { get { return displayedMaskRawNames.Length; } }
8288
public string[] displayedMaskRawNames { get; private set; } // without parenthesis
8389
public string[] displayedMaskNames { get; private set; }
8490
public int[] displayedMaskValues { get; private set; }
91+
public ulong[] displayedMaskRealMaskField { get; private set; }
8592
public Dictionary<int, int> value2displayedMaskIndex { get; private set; }
8693
public Dictionary<string, int> name2displayedMaskIndex { get; private set; }
8794

88-
public Dictionary<int, uint> value2displayedMaskField { get; private set; }
89-
public List<uint> displayedMaskIndex2realMaskField { get; private set; }
90-
9195
public EnumDisplayInfo(Type type)
9296
{
9397
if (type == null) { throw new ArgumentNullException("type"); }
@@ -125,11 +129,10 @@ public EnumDisplayInfo(Type type)
125129
var displayedMaskRawNamesList = new List<string>();
126130
var displayedMaskNamesList = new List<string>();
127131
var displayedMaskValuesList = new List<int>();
132+
var displayedMaskRealMaskFieldList = new List<ulong>();
128133
value2displayedMaskIndex = new Dictionary<int, int>();
129134
name2displayedMaskIndex = new Dictionary<string, int>();
130135

131-
value2displayedMaskField = new Dictionary<int, uint>();
132-
displayedMaskIndex2realMaskField = new List<uint>();
133136

134137
foreach (FieldInfo fi in type.GetFields()
135138
.Where(fi => fi.IsStatic && fi.GetCustomAttributes(typeof(HideInInspector), true).Length == 0)
@@ -157,77 +160,71 @@ public EnumDisplayInfo(Type type)
157160
name2displayedIndex[displayedNamesList[index]] = index;
158161
}
159162

160-
if (value < 0 || value >= UINT_MASK_FIELD_LENGTH) { continue; }
163+
if (value < 0 || value >= ULONG_MASK_FIELD_LENGTH) { continue; }
161164

162165
displayedMaskRawNamesList.Add(name);
163166
displayedMaskNamesList.Add(name);
164167
displayedMaskValuesList.Add(value);
168+
displayedMaskRealMaskFieldList.Add(1ul << value);
165169
index = displayedMaskNamesList.Count - 1;
166170

167171
name2displayedMaskIndex[name] = index;
168172

169173
if (!value2displayedMaskIndex.TryGetValue(value, out priorIndex))
170174
{
171175
value2displayedMaskIndex.Add(value, index);
172-
value2displayedMaskField.Add(value, 1u << index);
173176
}
174177
else
175178
{
176179
displayedMaskNamesList[index] += " (" + displayedMaskNamesList[priorIndex] + ")";
177180
name2displayedMaskIndex[displayedMaskNamesList[index]] = index;
178-
value2displayedMaskField[value] |= 1u << index;
179181
}
180182

181-
displayedMaskIndex2realMaskField.Add(1u << value);
182183
}
183184

184185
displayedRawNames = displayedRawNamesList.ToArray();
185186
displayedNames = displayedNamesList.ToArray();
186187
displayedValues = displayedValuesList.ToArray();
187188

188-
displayedMaskRawNames = displayedRawNamesList.ToArray();
189+
displayedMaskRawNames = displayedMaskRawNamesList.ToArray();
189190
displayedMaskNames = displayedMaskNamesList.ToArray();
190191
displayedMaskValues = displayedMaskValuesList.ToArray();
192+
displayedMaskRealMaskField = displayedMaskRealMaskFieldList.ToArray();
191193
}
192194

195+
[Obsolete]
193196
public int RealToDisplayedMaskField(int realMask)
194197
{
195198
var displayedMask = 0u;
196-
var mask = 1u;
197199

198-
for (int value = 0; value < UINT_MASK_FIELD_LENGTH && realMask != 0; ++value, mask <<= 1)
200+
for (int i = 0; i < UINT_MASK_FIELD_LENGTH && realMask != 0; ++i)
199201
{
200-
uint mk;
201-
if ((realMask & mask) > 0 && value2displayedMaskField.TryGetValue(value, out mk))
202+
if (GetFlag((uint)realMask, i))
202203
{
203-
displayedMask |= mk;
204+
UnsetFlag((uint)realMask, i);
205+
if (value2displayedMaskIndex[i] < UINT_MASK_FIELD_LENGTH)
206+
{
207+
displayedMask |= 1u << value2displayedMaskIndex[i];
208+
}
204209
}
205210
}
206211

207212
return (int)displayedMask;
208213
}
209214

215+
[Obsolete]
210216
public int DisplayedToRealMaskField(int displayedMask, bool fillUp = true)
211217
{
212-
var uDisMask = (uint)displayedMask;
213218
var realMask = 0u;
214219

215-
for (int index = 0; index < displayedMaskValues.Length && uDisMask != 0; ++index)
220+
for (int i = 0; i < UINT_MASK_FIELD_LENGTH && displayedMask != 0; ++i)
216221
{
217-
var mask = value2displayedMaskField[displayedMaskValues[index]];
218-
219-
if (fillUp)
220-
{
221-
if ((uDisMask & mask) > 0)
222-
{
223-
realMask |= displayedMaskIndex2realMaskField[index];
224-
}
225-
}
226-
else
222+
if (GetFlag((uint)displayedMask, i))
227223
{
228-
if ((uDisMask & mask) == mask)
224+
UnsetFlag((uint)displayedMask, i);
225+
if (i < UINT_MASK_FIELD_LENGTH)
229226
{
230-
realMask |= displayedMaskIndex2realMaskField[index];
227+
realMask |= (uint)displayedMaskRealMaskField[i];
231228
}
232229
}
233230
}
@@ -299,14 +296,14 @@ public static bool GetFlag(ulong maskField, int enumValue)
299296

300297
public static void SetFlag(ref ulong maskField, int enumValue, bool value)
301298
{
302-
if (enumValue < 0 || enumValue >= UINT_MASK_FIELD_LENGTH) { return; }
299+
if (enumValue < 0 || enumValue >= ULONG_MASK_FIELD_LENGTH) { return; }
303300
if (value)
304301
{
305-
maskField |= (1u << enumValue);
302+
maskField |= (1ul << enumValue);
306303
}
307304
else
308305
{
309-
maskField &= ~(1u << enumValue);
306+
maskField &= ~(1ul << enumValue);
310307
}
311308
}
312309

Assets/HTC.UnityPlugin/ViveInputUtility/Scripts/VIUVersion.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ namespace HTC.UnityPlugin.Vive
66
{
77
public static class VIUVersion
88
{
9-
public static readonly Version current = new Version("1.10.0.0");
9+
public static readonly Version current = new Version("1.10.1.0");
1010
}
1111
}

0 commit comments

Comments
 (0)