using BBIWARG.Input.InputHandling;
using BBIWARG.Recognition.PalmRecognition;
using BBIWARG.Recognition.TouchRecognition;
using BBIWARG.Utility;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using TUIO;
namespace BBIWARG.TUIO
{
///
/// TuioCommunicator sends generated touch events and palm grid coordinates to tuio clients using a .
///
internal class TuioCommunicatorHack
{
///
/// the tuio server
///
private TuioServer server;
///
/// dictionary of lists of tuio cursors indexed by touch id
///
private Dictionary tcursors;
///
/// dictionary of lists of tuio objects indexed by palm id
///
private Dictionary> tobjects;
///
/// Constructs a TuioCommunicator.
///
/// server ip
/// server port
public TuioCommunicatorHack(string host, int port)
{
server = new TuioServer(host, port);
tcursors = new Dictionary();
tobjects = new Dictionary>();
}
///
/// Tries to parse an ip address string.
///
/// the ip address string to parse
/// out parameter for the ip address in *.*.*.* format if ipIn is valid and null otherwise
/// true iff ipIn is a valid ip address
public static bool tryParseIPAddress(String ipIn, out String ipOut)
{
IPAddress ipAddress;
bool result = IPAddress.TryParse(ipIn, out ipAddress) && ipAddress.AddressFamily == AddressFamily.InterNetwork;
if (result)
ipOut = ipAddress.ToString();
else
ipOut = null;
return result;
}
///
/// Tries to parse a port string.
///
/// the port string to parse
/// out parameter for the port if portIn is valid and undefined otherwise
/// true iff portIn is a valid port
public static bool tryParsePort(String portIn, out Int16 portOut)
{
return Int16.TryParse(portIn, out portOut);
}
///
/// Closes the server.
///
public void close()
{
server.close();
}
///
/// Handles the event that a new frame is finished processing by updating the cursors and objects and sending them.
///
/// event sender
/// event arguments
public void handleNewFrameData(object sender, NewProcessedFrameEventArgs e)
{
server.initFrame();
FrameData frameData = e.FrameData;
lock (frameData)
{
if (frameData.ResetFlag)
reset();
foreach (TouchEvent te in frameData.TouchEvents)
{
Point p = getButton(te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
switch (te.Type)
{
case TouchEventType.Down:
TuioCursor tcur = server.addTuioCursor(p.X, p.Y);
tcursors.Add(te.Touch.TrackID, tcur);
break;
case TouchEventType.Move:
server.updateTuioCursor(tcursors[te.Touch.TrackID], p.X, p.Y);
break;
case TouchEventType.Up:
server.removeTuioCursor(tcursors[te.Touch.TrackID]);
tcursors.Remove(te.Touch.TrackID);
break;
}
}
List updatedIDs = new List();
foreach (Palm palm in frameData.TrackedPalms)
{
if (tobjects.Keys.Contains(palm.TrackID))
{
// update / move
List palmTobjs = tobjects[palm.TrackID];
Vector2D[] corners = palm.Quad.Corners;
for (int i = 0; i < 4; i++)
{
/* BEGIN HACK */
int x0 = 0;
int y0 = 0;
int x1 = 0;
int y1 = 0;
if (i == 0)
{
x0 = (int)corners[0].X;
y0 = (int)corners[0].Y;
x1 = (int)corners[2].X;
y1 = (int)corners[2].Y;
}
else if (i == 1)
{
x0 = (int)corners[1].X;
y0 = (int)corners[1].Y;
x1 = (int)corners[3].X;
y1 = (int)corners[3].Y;
}
else if (i == 2)
{
x0 = (int)corners[2].X;
y0 = (int)corners[2].Y;
x1 = (int)corners[0].X;
y1 = (int)corners[0].Y;
}
else if (i == 3)
{
x0 = (int)corners[3].X;
y0 = (int)corners[3].Y;
x1 = (int)corners[1].X;
y1 = (int)corners[1].Y;
}
/* END HACK */
server.updateTuioObject(
palmTobjs[i],
corners[i].X,
corners[i].Y,
frameData.DepthImage.getDepthAtFixed(x0, y0, x1, y1));
//frameData.DepthImage.getDepthAt((int)corners[i].X, (int)corners[i].Y));
}
updatedIDs.Add(palm.TrackID);
}
else
{
// add / create
List palmTobjs = new List();
Vector2D[] corners = palm.Quad.Corners;
for (int i = 0; i < 4; i++)
{
/* BEGIN HACK */
int x0 = 0;
int y0 = 0;
int x1 = 0;
int y1 = 0;
if (i == 0)
{
x0 = (int)corners[0].X;
y0 = (int)corners[0].Y;
x1 = (int)corners[2].X;
y1 = (int)corners[2].Y;
}
else if (i == 1)
{
x0 = (int)corners[1].X;
y0 = (int)corners[1].Y;
x1 = (int)corners[3].X;
y1 = (int)corners[3].Y;
}
else if (i == 2)
{
x0 = (int)corners[2].X;
y0 = (int)corners[2].Y;
x1 = (int)corners[0].X;
y1 = (int)corners[0].Y;
}
else if (i == 3)
{
x0 = (int)corners[3].X;
y0 = (int)corners[3].Y;
x1 = (int)corners[1].X;
y1 = (int)corners[1].Y;
}
/* END HACK */
palmTobjs.Add(server.addTuioObject(
corners[i].X,
corners[i].Y,
frameData.DepthImage.getDepthAtFixed(x0, y0, x1, y1))); //palm.TrackID + 0.1f * i));
}
tobjects.Add(palm.TrackID, palmTobjs);
updatedIDs.Add(palm.TrackID);
}
}
// remove
List ids = tobjects.Keys.ToList();
for (int i = ids.Count - 1; i >= 0; i--)
{
int id = ids[i];
if (!updatedIDs.Contains(id))
{
foreach (TuioObject tobj in tobjects[id])
server.removeTuioObject(tobj);
tobjects.Remove(id);
}
}
}
server.commitFrame();
}
private Point getButton(float rX , float rY)
{
int activeRow = (int)Math.Min(rY * Parameters.ActiveTouches.Count,
Parameters.PalmGridDefaultNumRows - 1);
int activeCol = (int)Math.Min(rX * Parameters.ActiveTouches.ElementAt(activeRow).Count,
Parameters.ActiveTouches.ElementAt(activeRow).Count - 1);
if (activeRow != Parameters.PalmSliderPos)
return new Point(activeRow, activeCol);
else
return new Point(activeRow, Parameters.PalmSliderCurr);
}
///
/// Resets the server by removing all cursors and objects.
///
public void reset()
{
foreach (int id in tcursors.Keys)
server.removeTuioCursor(tcursors[id]);
tcursors.Clear();
foreach (int id in tobjects.Keys)
foreach (TuioObject tobj in tobjects[id])
server.removeTuioObject(tobj);
tobjects.Clear();
}
}
}