Created
March 23, 2015 08:21
-
-
Save gregharding/fa2105d2904a7003e83d to your computer and use it in GitHub Desktop.
TUIO Object Manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
TUIO Object Manager | |
TUIO Object manager that supports tuio input from TouchScript. | |
Usage: | |
Add TUIOObjectManager anywhere (eg. to the EventSystem) and ensure TouchScript is active. | |
Ensure script priority is high. | |
Register listeners for object events. | |
Use #define CANCEL_BRIEF_OBJECTS to cancel objects (touches) that last less than validTouchTime. | |
Requirements: | |
TouchScript https://github.com/TouchScript (by Valentin Simonov https://github.com/valyard) | |
Based on: | |
TouchScriptInputModule | |
Copyright 2015 Flightless. http://www.flightless.co.nz | |
The MIT License (MIT) | |
Copyright (c) 2015 Flightless Ltd. | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in | |
all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
THE SOFTWARE. | |
*/ | |
#define CANCEL_BRIEF_OBJECTS | |
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System; | |
using TouchScript; | |
namespace Flightless { | |
public class TUIOObjectEventArgs : EventArgs { | |
public int objectId { get; private set; } | |
public ITouch touch { get; private set; } | |
public TUIOObjectEventArgs(int objectId, ITouch touch) { | |
this.objectId = objectId; | |
this.touch = touch; | |
} | |
} | |
public class TUIOObjectManager : SingletonMonoBehaviour<TUIOObjectManager> { | |
public event EventHandler<TUIOObjectEventArgs> onObjectBegan; | |
public event EventHandler<TUIOObjectEventArgs> onObjectUpdated; | |
public event EventHandler<TUIOObjectEventArgs> onObjectEnded; | |
public event EventHandler<TUIOObjectEventArgs> onObjectCancelled; | |
#if CANCEL_BRIEF_OBJECTS | |
public bool cancelBriefObjects { | |
get { return _cancelBriefObjects; } | |
set { _cancelBriefObjects = value; } | |
} | |
[SerializeField] | |
private bool _cancelBriefObjects = false; | |
public float validObjectTime { | |
get { return _validObjectsTime; } | |
set { _validObjectsTime = value; } | |
} | |
[SerializeField] | |
[Range(0.0f, 1.0f)] | |
private float _validObjectsTime = 0.15f; | |
#endif | |
public const int initialObjectCapacity = 10; | |
override protected void Initialise() { | |
objects = new Dictionary<int, ITouch>(initialObjectCapacity); | |
} | |
protected void OnEnable() { | |
if (TouchManager.Instance != null) { | |
TouchManager.Instance.TouchesBegan += OnTouchesBeganHandler; | |
TouchManager.Instance.TouchesEnded += OnTouchesEndedHandler; | |
TouchManager.Instance.TouchesMoved += OnTouchesMovedHandler; | |
TouchManager.Instance.TouchesCancelled += OnTouchesCancelledHandler; | |
} | |
} | |
protected void Update() { | |
ProcessObjectEvents(); | |
} | |
protected void OnDisable() { | |
if (TouchManager.Instance != null) { | |
TouchManager.Instance.TouchesBegan -= OnTouchesBeganHandler; | |
TouchManager.Instance.TouchesEnded -= OnTouchesEndedHandler; | |
TouchManager.Instance.TouchesMoved -= OnTouchesMovedHandler; | |
TouchManager.Instance.TouchesCancelled -= OnTouchesCancelledHandler; | |
} | |
ClearObjects(); | |
} | |
// | |
// objects | |
// | |
protected void OnObjectBegan(TUIOObjectEventArgs e) { | |
//Debug.Log(string.Format("OnObjectBegan objectid:{0} touchid:{1}", (int)(e.touch.Properties["ObjectId"]), e.touch.Id)); | |
if (onObjectBegan != null) onObjectBegan(this, e); | |
} | |
protected void OnObjectUpdated(TUIOObjectEventArgs e) { | |
//Debug.Log(string.Format("OnObjectUpdated objectid:{0} touchid:{1}", (int)(e.touch.Properties["ObjectId"]), e.touch.Id)); | |
if (onObjectUpdated != null) onObjectUpdated(this, e); | |
} | |
protected void OnObjectEnded(TUIOObjectEventArgs e) { | |
//Debug.Log(string.Format("OnObjectEnded objectid:{0} touchid:{1}", (int)(e.touch.Properties["ObjectId"]), e.touch.Id)); | |
if (onObjectEnded != null) onObjectEnded(this, e); | |
} | |
protected void OnObjectCancelled(TUIOObjectEventArgs e) { | |
//Debug.Log(string.Format("OnObjectCancelled objectid:{0} touchid:{1}", (int)(e.touch.Properties["ObjectId"]), e.touch.Id)); | |
if (onObjectCancelled != null) onObjectCancelled(this, e); | |
} | |
protected void ProcessObjectEvents() { | |
// process all object events from the objects dictionary | |
foreach (KeyValuePair<int, ITouch> touchKV in objects) { | |
ITouch touch = touchKV.Value; | |
bool began = objectsBeganIDs.Contains(touch.Id); | |
bool released = objectsEndedIDs.Contains(touch.Id); | |
bool cancelled = objectsCancelledIDs.Contains(touch.Id); | |
TUIOObjectEventArgs objectEvent = new TUIOObjectEventArgs((int)(touch.Properties["ObjectId"]), touch); | |
if (cancelled) | |
OnObjectCancelled(objectEvent); | |
else if (released) | |
OnObjectEnded(objectEvent); | |
else if (began) | |
OnObjectBegan(objectEvent); | |
else | |
OnObjectUpdated(objectEvent); | |
} | |
// cleanup, remove ended objects and clear lists of began/ended/cancelled touch ids | |
for (int i=0; i < objectsEndedIDs.Count; i++) { | |
objects.Remove(objectsEndedIDs[i]); | |
#if CANCEL_BRIEF_OBJECTS | |
objectsBeganTime.Remove(objectsEndedIDs[i]); | |
#endif | |
} | |
for (int i=0; i < objectsCancelledIDs.Count; i++) { | |
objects.Remove(objectsCancelledIDs[i]); | |
#if CANCEL_BRIEF_OBJECTS | |
objectsBeganTime.Remove(objectsCancelledIDs[i]); | |
#endif | |
} | |
objectsBeganIDs.Clear(); | |
objectsEndedIDs.Clear(); | |
objectsCancelledIDs.Clear(); | |
} | |
protected void ClearObjects(bool broadcastToListeners = false) { | |
if (broadcastToListeners) { | |
for (int i=0; i<objects.Count; i++) { | |
ITouch touch = objects[i]; | |
OnObjectCancelled(new TUIOObjectEventArgs((int)(touch.Properties["ObjectId"]), touch)); | |
} | |
} | |
objects.Clear(); | |
#if CANCEL_BRIEF_OBJECTS | |
objectsBeganTime.Clear(); | |
#endif | |
objectsBeganIDs.Clear(); | |
objectsEndedIDs.Clear(); | |
objectsCancelledIDs.Clear(); | |
} | |
// | |
// tuio input | |
// | |
public Dictionary<int, ITouch> objects { get; protected set; } | |
private List<int> objectsBeganIDs = new List<int>(initialObjectCapacity); | |
private List<int> objectsEndedIDs = new List<int>(initialObjectCapacity); | |
private List<int> objectsCancelledIDs = new List<int>(initialObjectCapacity); | |
#if CANCEL_BRIEF_OBJECTS | |
private Dictionary<int, float> objectsBeganTime = new Dictionary<int, float>(initialObjectCapacity); | |
#endif | |
private bool IsObjectTouch(ITouch touch) { | |
return (touch.Tags.HasTag(Tags.INPUT_OBJECT) && touch.Properties.ContainsKey("ObjectId")); | |
} | |
private void OnTouchesBeganHandler(object sender, TouchEventArgs e) { | |
for (int i=0; i<e.Touches.Count; i++) { | |
ITouch touch = e.Touches[i]; | |
if (!IsObjectTouch(touch)) continue; | |
objects.Add(touch.Id, touch); | |
objectsBeganIDs.Add(touch.Id); | |
#if CANCEL_BRIEF_OBJECTS | |
objectsBeganTime.Add(touch.Id, Time.realtimeSinceStartup); | |
#endif | |
} | |
} | |
private void UpdateTouch(ITouch touch) { | |
objects[touch.Id] = touch; | |
} | |
private void OnTouchesMovedHandler(object sender, TouchEventArgs e) { | |
for (int i=0; i<e.Touches.Count; i++) { | |
ITouch touch = e.Touches[i]; | |
if (!IsObjectTouch(touch)) continue; | |
ITouch foundTouch; | |
if (!objects.TryGetValue(touch.Id, out foundTouch)) return; | |
UpdateTouch(touch); | |
} | |
} | |
private void OnTouchesEndedHandler(object sender, TouchEventArgs e) { | |
for (int i=0; i<e.Touches.Count; i++) { | |
ITouch touch = e.Touches[i]; | |
if (!IsObjectTouch(touch)) continue; | |
ITouch foundTouch; | |
if (!objects.TryGetValue(touch.Id, out foundTouch)) return; | |
#if CANCEL_BRIEF_OBJECTS | |
// end or cancel touch | |
float touchBeginTime; | |
if (_cancelBriefObjects && objectsBeganTime.TryGetValue(touch.Id, out touchBeginTime) && (Time.realtimeSinceStartup - touchBeginTime < _validObjectsTime)) { | |
objectsCancelledIDs.Add(touch.Id); | |
} else { | |
objectsEndedIDs.Add(touch.Id); | |
} | |
#else | |
// end touch | |
touchesEndedIDs.Add(touch.Id); | |
#endif | |
//touches.Remove(touch.Id); // removed after process handles the touch | |
} | |
} | |
private void OnTouchesCancelledHandler(object sender, TouchEventArgs e) { | |
// cancel touches same as end touches | |
//OnTouchesEndedHandler(sender, e); | |
// specifically cancel touches | |
for (int i=0; i<e.Touches.Count; i++) { | |
ITouch touch = e.Touches[i]; | |
if (!IsObjectTouch(touch)) continue; | |
ITouch foundTouch; | |
if (!objects.TryGetValue(touch.Id, out foundTouch)) return; | |
objectsCancelledIDs.Add(touch.Id); | |
//touches.Remove(touch.Id); // removed after process handles the touch | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you!
I was looking for the solution how directly access active TUIO objects.