Skip to content

Commit

Permalink
Update to v1.10.1
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
lawwong committed Dec 21, 2018
2 parents db5b52f + 2f0e732 commit cdf181b
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -1,37 +1,181 @@
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. ===========

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace HTC.UnityPlugin.Utility
{
[CustomPropertyDrawer(typeof(FlagsFromEnumAttribute))]
[CanEditMultipleObjects]
public class FlagsFromEnumAttributeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
private static GUIStyle s_popup;
private static GUIContent s_tempContent;
private static List<bool> s_displayedMask;

private bool m_foldoutOpen = false;

private static GUIContent GetTextContent(string text) { s_tempContent.text = text; return s_tempContent; }

static FlagsFromEnumAttributeDrawer()
{
s_popup = new GUIStyle(EditorStyles.popup);
s_tempContent = new GUIContent();
s_displayedMask = new List<bool>();
}

private bool TryGetEnumInfo(out EnumUtils.EnumDisplayInfo info)
{
// First get the attribute since it contains the range for the slider
var ffeAttribute = attribute as FlagsFromEnumAttribute;

if (ffeAttribute.EnumType == null || !ffeAttribute.EnumType.IsEnum)
{
info = null;
return false;
}

info = EnumUtils.GetDisplayInfo(ffeAttribute.EnumType);
return info != null;
}

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
EnumUtils.EnumDisplayInfo enumInfo;

if (!m_foldoutOpen || !TryGetEnumInfo(out enumInfo))
{
return EditorGUIUtility.singleLineHeight;
}
else
{
return EditorGUIUtility.singleLineHeight * (enumInfo.displayedMaskNames.Length + 2);
}
}

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);

EnumUtils.EnumDisplayInfo enumInfo;

if (property.propertyType != SerializedPropertyType.Integer)
{
EditorGUI.LabelField(position, label.text, "Use FlagFromEnum with integer.");
}
else if (ffeAttribute.EnumType == null || !ffeAttribute.EnumType.IsEnum)
else if (!TryGetEnumInfo(out enumInfo))
{
EditorGUI.LabelField(position, label.text, "Set FlagFromEnum argument with enum type.");
}
else
{
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), new GUIContent(property.displayName));
position = EditorGUI.PrefixLabel(position, new GUIContent(property.displayName));

// get display mask value
s_displayedMask.Clear();
var enumDisplayLength = enumInfo.displayedMaskLength;
var realMask = (ulong)property.longValue;
var firstSelected = string.Empty;
for (int i = 0; i < enumDisplayLength; ++i)
{
if (EnumUtils.GetFlag(realMask, enumInfo.displayedMaskValues[i]))
{
s_displayedMask.Add(true);
if (string.IsNullOrEmpty(firstSelected)) { firstSelected = enumInfo.displayedMaskNames[i]; }
}
else
{
s_displayedMask.Add(false);
}
}

var flagsCount = 0;
for (var i = 0; i < EnumUtils.ULONG_MASK_FIELD_LENGTH; ++i)
{
if (EnumUtils.GetFlag(realMask, i)) { ++flagsCount; }
}

if (EditorGUI.showMixedValue)
{
s_tempContent.text = " - ";
}
else if (flagsCount == 0)
{
s_tempContent.text = "None";
}
else if (flagsCount == 1)
{
s_tempContent.text = firstSelected;
}
else if (flagsCount < enumDisplayLength)
{
s_tempContent.text = "Mixed...";
}
else
{
s_tempContent.text = "All";
}

var controlPos = position;
controlPos.height = EditorGUIUtility.singleLineHeight;
var id = GUIUtility.GetControlID(FocusType.Passive, controlPos);

switch (Event.current.GetTypeForControl(id))
{
case EventType.MouseDown:
if (controlPos.Contains(Event.current.mousePosition))
{
GUIUtility.hotControl = id;
GUIUtility.keyboardControl = id;
Event.current.Use();
}
break;
case EventType.MouseUp:
if (GUIUtility.hotControl == id)
{
GUIUtility.hotControl = 0;
GUIUtility.keyboardControl = 0;
Event.current.Use();
m_foldoutOpen = !m_foldoutOpen;
}
break;
case EventType.Repaint:
s_popup.Draw(position, s_tempContent, id, false);
break;
}

if (m_foldoutOpen)
{
position.y += EditorGUIUtility.singleLineHeight;

var halfWidth = position.width * 0.5f;
if (GUI.Button(new Rect(position.x, position.y, halfWidth - 1, EditorGUIUtility.singleLineHeight), "All"))
{
realMask = ~0ul;
//m_foldoutOpen = false;
}

//Draw the None button
if (GUI.Button(new Rect(position.x + halfWidth + 1, position.y, halfWidth - 1, EditorGUIUtility.singleLineHeight), "None"))
{
realMask = 0ul;
//m_foldoutOpen = false;
}

for (int i = 0; i < enumDisplayLength; ++i)
{
position.y += EditorGUIUtility.singleLineHeight;
var toggled = EditorGUI.ToggleLeft(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), enumInfo.displayedMaskNames[i], s_displayedMask[i]);
if (s_displayedMask[i] != toggled)
{
s_displayedMask[i] = toggled;
EnumUtils.SetFlag(ref realMask, enumInfo.displayedMaskValues[i], toggled);
//m_foldoutOpen = false;
}
}

var enumInfo = EnumUtils.GetDisplayInfo(ffeAttribute.EnumType);
var realMask = property.intValue;
var oldDisplayedMask = enumInfo.RealToDisplayedMaskField(realMask);
var newDisplayedMask = EditorGUI.MaskField(position, oldDisplayedMask, enumInfo.displayedMaskNames);
property.intValue = enumInfo.DisplayedToRealMaskField(newDisplayedMask, (uint)newDisplayedMask > (uint)oldDisplayedMask);
property.longValue = (long)realMask;
}
}

property.serializedObject.ApplyModifiedProperties();
Expand Down
71 changes: 34 additions & 37 deletions Assets/HTC.UnityPlugin/Utility/EnumUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static class EnumUtils
// Default = 0,
// EEE,
// FFF,
// GGG = 65,
// }
//
// EnumDisplayInfo for typeof(SomeEnum) will be:
Expand All @@ -39,6 +40,7 @@ public static class EnumUtils
// BBB | 1
// FFF | 2
// CCC | 35
// GGG | 65
// zzz | -2
// Invalid | -1
//
Expand All @@ -52,14 +54,16 @@ public static class EnumUtils
// Default (AAA) | Default | 0
// EEE (BBB) | EEE | 1
// FFF | FFF | 2
// GGG | GGG | 65
//
// displayedMaskNames | displayedMaskRawNames | displayedMaskValues | realMaskField
// ---------------------------------------------------------------------------------
// AAA | AAA | 0 | 1u << 0
// BBB | BBB | 1 | 1u << 1
// Default (AAA) | Default | 0 | 1u << 0
// EEE (BBB) | EEE | 1 | 1u << 1
// FFF | FFF | 2 | 1u << 2
// AAA | AAA | 0 | 1ul << 0
// BBB | BBB | 1 | 1ul << 1
// CCC | CCC | 35 | 1ul << 35
// Default (AAA) | Default | 0 | 1ul << 0
// EEE (BBB) | EEE | 1 | 1ul << 1
// FFF | FFF | 2 | 1ul << 2

public class EnumDisplayInfo
{
Expand All @@ -73,21 +77,21 @@ public class EnumDisplayInfo
public Dictionary<int, int> rawValue2index { get; private set; }
public Dictionary<string, int> rawName2index { get; private set; }

public int displayedLength { get { return displayedRawNames.Length; } }
public string[] displayedRawNames { get; private set; } // without parenthesis
public string[] displayedNames { get; private set; }
public int[] displayedValues { get; private set; }
public Dictionary<int, int> value2displayedIndex { get; private set; }
public Dictionary<string, int> name2displayedIndex { get; private set; }

public int displayedMaskLength { get { return displayedMaskRawNames.Length; } }
public string[] displayedMaskRawNames { get; private set; } // without parenthesis
public string[] displayedMaskNames { get; private set; }
public int[] displayedMaskValues { get; private set; }
public ulong[] displayedMaskRealMaskField { get; private set; }
public Dictionary<int, int> value2displayedMaskIndex { get; private set; }
public Dictionary<string, int> name2displayedMaskIndex { get; private set; }

public Dictionary<int, uint> value2displayedMaskField { get; private set; }
public List<uint> displayedMaskIndex2realMaskField { get; private set; }

public EnumDisplayInfo(Type type)
{
if (type == null) { throw new ArgumentNullException("type"); }
Expand Down Expand Up @@ -125,11 +129,10 @@ public EnumDisplayInfo(Type type)
var displayedMaskRawNamesList = new List<string>();
var displayedMaskNamesList = new List<string>();
var displayedMaskValuesList = new List<int>();
var displayedMaskRealMaskFieldList = new List<ulong>();
value2displayedMaskIndex = new Dictionary<int, int>();
name2displayedMaskIndex = new Dictionary<string, int>();

value2displayedMaskField = new Dictionary<int, uint>();
displayedMaskIndex2realMaskField = new List<uint>();

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

if (value < 0 || value >= UINT_MASK_FIELD_LENGTH) { continue; }
if (value < 0 || value >= ULONG_MASK_FIELD_LENGTH) { continue; }

displayedMaskRawNamesList.Add(name);
displayedMaskNamesList.Add(name);
displayedMaskValuesList.Add(value);
displayedMaskRealMaskFieldList.Add(1ul << value);
index = displayedMaskNamesList.Count - 1;

name2displayedMaskIndex[name] = index;

if (!value2displayedMaskIndex.TryGetValue(value, out priorIndex))
{
value2displayedMaskIndex.Add(value, index);
value2displayedMaskField.Add(value, 1u << index);
}
else
{
displayedMaskNamesList[index] += " (" + displayedMaskNamesList[priorIndex] + ")";
name2displayedMaskIndex[displayedMaskNamesList[index]] = index;
value2displayedMaskField[value] |= 1u << index;
}

displayedMaskIndex2realMaskField.Add(1u << value);
}

displayedRawNames = displayedRawNamesList.ToArray();
displayedNames = displayedNamesList.ToArray();
displayedValues = displayedValuesList.ToArray();

displayedMaskRawNames = displayedRawNamesList.ToArray();
displayedMaskRawNames = displayedMaskRawNamesList.ToArray();
displayedMaskNames = displayedMaskNamesList.ToArray();
displayedMaskValues = displayedMaskValuesList.ToArray();
displayedMaskRealMaskField = displayedMaskRealMaskFieldList.ToArray();
}

[Obsolete]
public int RealToDisplayedMaskField(int realMask)
{
var displayedMask = 0u;
var mask = 1u;

for (int value = 0; value < UINT_MASK_FIELD_LENGTH && realMask != 0; ++value, mask <<= 1)
for (int i = 0; i < UINT_MASK_FIELD_LENGTH && realMask != 0; ++i)
{
uint mk;
if ((realMask & mask) > 0 && value2displayedMaskField.TryGetValue(value, out mk))
if (GetFlag((uint)realMask, i))
{
displayedMask |= mk;
UnsetFlag((uint)realMask, i);
if (value2displayedMaskIndex[i] < UINT_MASK_FIELD_LENGTH)
{
displayedMask |= 1u << value2displayedMaskIndex[i];
}
}
}

return (int)displayedMask;
}

[Obsolete]
public int DisplayedToRealMaskField(int displayedMask, bool fillUp = true)
{
var uDisMask = (uint)displayedMask;
var realMask = 0u;

for (int index = 0; index < displayedMaskValues.Length && uDisMask != 0; ++index)
for (int i = 0; i < UINT_MASK_FIELD_LENGTH && displayedMask != 0; ++i)
{
var mask = value2displayedMaskField[displayedMaskValues[index]];

if (fillUp)
{
if ((uDisMask & mask) > 0)
{
realMask |= displayedMaskIndex2realMaskField[index];
}
}
else
if (GetFlag((uint)displayedMask, i))
{
if ((uDisMask & mask) == mask)
UnsetFlag((uint)displayedMask, i);
if (i < UINT_MASK_FIELD_LENGTH)
{
realMask |= displayedMaskIndex2realMaskField[index];
realMask |= (uint)displayedMaskRealMaskField[i];
}
}
}
Expand Down Expand Up @@ -299,14 +296,14 @@ public static bool GetFlag(ulong maskField, int enumValue)

public static void SetFlag(ref ulong maskField, int enumValue, bool value)
{
if (enumValue < 0 || enumValue >= UINT_MASK_FIELD_LENGTH) { return; }
if (enumValue < 0 || enumValue >= ULONG_MASK_FIELD_LENGTH) { return; }
if (value)
{
maskField |= (1u << enumValue);
maskField |= (1ul << enumValue);
}
else
{
maskField &= ~(1u << enumValue);
maskField &= ~(1ul << enumValue);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ namespace HTC.UnityPlugin.Vive
{
public static class VIUVersion
{
public static readonly Version current = new Version("1.10.0.0");
public static readonly Version current = new Version("1.10.1.0");
}
}
Loading

0 comments on commit cdf181b

Please sign in to comment.