Skip to content

Instantly share code, notes, and snippets.

@gregharding
Created March 23, 2015 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gregharding/fa2105d2904a7003e83d to your computer and use it in GitHub Desktop.
Save gregharding/fa2105d2904a7003e83d to your computer and use it in GitHub Desktop.
TUIO Object Manager
/*
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
}
}
}
}
@gilpark
Copy link

gilpark commented Nov 4, 2016

Thank you!
I was looking for the solution how directly access active TUIO objects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment