瀏覽代碼

palmQuad is submitted via tuio as tuioObjects (each corner is a unique tuioObject, angle -> id.position)

Alexander Hendrich 11 年之前
父節點
當前提交
cf127de668

+ 2 - 2
bbiwarg/Parameters.cs

@@ -23,7 +23,7 @@ namespace bbiwarg
         public static readonly int ConsoleHeight = 30;
 
         // input
-        public static readonly InputType InputSource = InputType.Camera;
+        public static readonly InputType InputSource = InputType.Movie;
         public static readonly String InputMoviePath = "..\\..\\videos\\touch\\4.skv";
 
         // Logger
@@ -42,7 +42,7 @@ namespace bbiwarg
         public static readonly int GlassesWindowNumCalibrationPoints = 20;
 
         // TUIO
-        public static readonly bool TuioEnabledByDefault = false;
+        public static readonly bool TuioEnabledByDefault = true;
         public static readonly String TuioDefaultIP = "127.0.0.1";
         public static readonly Int16 TuioDefaultPort = 3333;
 

+ 271 - 0
bbiwarg/TUIO/TUIO/TuioObject.cs

@@ -0,0 +1,271 @@
+/*
+	TUIO C# Library - part of the reacTIVision project
+	http://reactivision.sourceforge.net/
+
+	Copyright (c) 2005-2009 Martin Kaltenbrunner <mkalten@iua.upf.edu>
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+using System;
+using System.Collections.Generic;
+
+namespace TUIO
+{
+
+    /**
+     * The TuioObject class encapsulates /tuio/2Dobj TUIO objects.
+     *
+     * @author Martin Kaltenbrunner
+     * @version 1.4
+     */
+    public class TuioObject : TuioContainer
+    {
+
+        /**
+         * The individual symbol ID number that is assigned to each TuioObject.
+         */
+        protected int symbol_id;
+        /**
+         * The rotation angle value.
+         */
+        protected float angle;
+        /**
+         * The rotation speed value.
+         */
+        protected float rotation_speed;
+        /**
+         * The rotation acceleration value.
+         */
+        protected float rotation_accel;
+        /**
+         * Defines the ROTATING state.
+         */
+        public static readonly int TUIO_ROTATING = 5;
+
+        /**
+         * This constructor takes a TuioTime argument and assigns it along with the provided
+         * Session ID, Symbol ID, X and Y coordinate and angle to the newly created TuioObject.
+         *
+         * @param	ttime	the TuioTime to assign
+         * @param	si	the Session ID to assign
+         * @param	sym	the Symbol ID to assign
+         * @param	xp	the X coordinate to assign
+         * @param	yp	the Y coordinate to assign
+         * @param	a	the angle to assign
+         */
+        public TuioObject(TuioTime ttime, long si, int sym, float xp, float yp, float a)
+            : base(ttime, si, xp, yp)
+        {
+            symbol_id = sym;
+            angle = a;
+            rotation_speed = 0.0f;
+            rotation_accel = 0.0f;
+        }
+
+        /**
+         * This constructor takes the provided Session ID, Symbol ID, X and Y coordinate
+         * and angle, and assigs these values to the newly created TuioObject.
+         *
+         * @param	si	the Session ID to assign
+         * @param	sym	the Symbol ID to assign
+         * @param	xp	the X coordinate to assign
+         * @param	yp	the Y coordinate to assign
+         * @param	a	the angle to assign
+         */
+        public TuioObject(long si, int sym, float xp, float yp, float a)
+            : base(si, xp, yp)
+        {
+            symbol_id = sym;
+            angle = a;
+            rotation_speed = 0.0f;
+            rotation_accel = 0.0f;
+        }
+
+        /**
+         * This constructor takes the atttibutes of the provided TuioObject
+         * and assigs these values to the newly created TuioObject.
+         *
+         * @param	tobj	the TuioObject to assign
+         */
+        public TuioObject(TuioObject tobj)
+            : base(tobj)
+        {
+            symbol_id = tobj.getSymbolID();
+            angle = tobj.getAngle();
+            rotation_speed = 0.0f;
+            rotation_accel = 0.0f;
+        }
+
+        /**
+         * Takes a TuioTime argument and assigns it along with the provided
+         * X and Y coordinate, angle, X and Y velocity, motion acceleration,
+         * rotation speed and rotation acceleration to the private TuioObject attributes.
+         *
+         * @param	ttime	the TuioTime to assign
+         * @param	xp	the X coordinate to assign
+         * @param	yp	the Y coordinate to assign
+         * @param	a	the angle coordinate to assign
+         * @param	xs	the X velocity to assign
+         * @param	ys	the Y velocity to assign
+         * @param	rs	the rotation velocity to assign
+         * @param	ma	the motion acceleration to assign
+         * @param	ra	the rotation acceleration to assign
+         */
+        public void update(TuioTime ttime, float xp, float yp, float a, float xs, float ys, float rs, float ma, float ra)
+        {
+            base.update(ttime, xp, yp, xs, ys, ma);
+            angle = a;
+            rotation_speed = rs;
+            rotation_accel = ra;
+            if ((rotation_accel != 0) && (state != TUIO_STOPPED)) state = TUIO_ROTATING;
+        }
+
+        /**
+         * Assigns the provided X and Y coordinate, angle, X and Y velocity, motion acceleration
+         * rotation velocity and rotation acceleration to the private TuioContainer attributes.
+         * The TuioTime time stamp remains unchanged.
+         *
+         * @param	xp	the X coordinate to assign
+         * @param	yp	the Y coordinate to assign
+         * @param	a	the angle coordinate to assign
+         * @param	xs	the X velocity to assign
+         * @param	ys	the Y velocity to assign
+         * @param	rs	the rotation velocity to assign
+         * @param	ma	the motion acceleration to assign
+         * @param	ra	the rotation acceleration to assign
+         */
+        public void update(float xp, float yp, float a, float xs, float ys, float rs, float ma, float ra)
+        {
+            base.update(xp, yp, xs, ys, ma);
+            angle = a;
+            rotation_speed = rs;
+            rotation_accel = ra;
+            if ((rotation_accel != 0) && (state != TUIO_STOPPED)) state = TUIO_ROTATING;
+        }
+
+        /**
+         * Takes a TuioTime argument and assigns it along with the provided
+         * X and Y coordinate and angle to the private TuioObject attributes.
+         * The speed and accleration values are calculated accordingly.
+         *
+         * @param	ttime	the TuioTime to assign
+         * @param	xp	the X coordinate to assign
+         * @param	yp	the Y coordinate to assign
+         * @param	a	the angle coordinate to assign
+         */
+        public void update(TuioTime ttime, float xp, float yp, float a)
+        {
+            TuioPoint lastPoint = path[path.Count - 1];
+            base.update(ttime, xp, yp);
+
+            TuioTime diffTime = currentTime - lastPoint.getTuioTime();
+            float dt = diffTime.getTotalMilliseconds() / 1000.0f;
+            float last_angle = angle;
+            float last_rotation_speed = rotation_speed;
+            angle = a;
+
+            float da = (angle - last_angle) / (2.0f * (float)Math.PI);
+            if (da > 0.75f) da -= 1.0f;
+            else if (da < -0.75f) da += 1.0f;
+
+            rotation_speed = da / dt;
+            rotation_accel = (rotation_speed - last_rotation_speed) / dt;
+            if ((rotation_accel != 0) && (state != TUIO_STOPPED)) state = TUIO_ROTATING;
+        }
+
+        /**
+         * Takes the atttibutes of the provided TuioObject
+         * and assigs these values to this TuioObject.
+         * The TuioTime time stamp of this TuioContainer remains unchanged.
+         *
+         * @param	tobj	the TuioContainer to assign
+         */
+        public void update(TuioObject tobj)
+        {
+            base.update(tobj);
+            angle = tobj.getAngle();
+            rotation_speed = tobj.getRotationSpeed();
+            rotation_accel = tobj.getRotationAccel();
+            if ((rotation_accel != 0) && (state != TUIO_STOPPED)) state = TUIO_ROTATING;
+        }
+
+        /**
+         * This method is used to calculate the speed and acceleration values of a
+         * TuioObject with unchanged position and angle.
+         */
+        public new void stop(TuioTime ttime)
+        {
+            update(ttime, this.xpos, this.ypos, this.angle);
+        }
+
+        /**
+         * Returns the symbol ID of this TuioObject.
+         * @return	the symbol ID of this TuioObject
+         */
+        public int getSymbolID()
+        {
+            return symbol_id;
+        }
+
+        /**
+         * Returns the rotation angle of this TuioObject.
+         * @return	the rotation angle of this TuioObject
+         */
+        public float getAngle()
+        {
+            return angle;
+        }
+
+        /**
+         * Returns the rotation angle in degrees of this TuioObject.
+         * @return	the rotation angle in degrees of this TuioObject
+         */
+        public float getAngleDegrees()
+        {
+            return angle / (float)Math.PI * 180.0f;
+        }
+
+        /**
+         * Returns the rotation speed of this TuioObject.
+         * @return	the rotation speed of this TuioObject
+         */
+        public float getRotationSpeed()
+        {
+            return rotation_speed;
+        }
+
+        /**
+         * Returns the rotation acceleration of this TuioObject.
+         * @return	the rotation acceleration of this TuioObject
+         */
+        public float getRotationAccel()
+        {
+            return rotation_accel;
+        }
+
+        /**
+         * Returns true of this TuioObject is moving.
+         * @return	true of this TuioObject is moving
+         */
+        public new bool isMoving()
+        {
+            if ((state == TUIO_ACCELERATING) || (state == TUIO_DECELERATING) || (state == TUIO_ROTATING)) return true;
+            else return false;
+        }
+
+    }
+
+}

+ 85 - 41
bbiwarg/TUIO/TUIO/TuioServer.cs

@@ -24,6 +24,9 @@ namespace TUIO
         private List<TuioCursor> cursorList;
         private List<TuioCursor> updatedCursorList;
 
+        private List<TuioObject> objectList;
+        private List<TuioObject> updatedObjectList;
+
         public TuioServer() { init(); }
 
         public TuioServer(int port)
@@ -43,6 +46,7 @@ namespace TUIO
         {
             TuioTime.initSession();
             cursorList = new List<TuioCursor>();
+            objectList = new List<TuioObject>();
             transmitter = new OSCTransmitter(host, port);
         }
 
@@ -52,9 +56,9 @@ namespace TUIO
             transmitter.Close();
         }
 
-        public TuioCursor addTuioCursor(float x, float y)
+        public TuioCursor addTuioCursor(float xp, float yp)
         {
-            TuioCursor tcur = new TuioCursor(sessionID, cursorList.Count, x, y);
+            TuioCursor tcur = new TuioCursor(sessionID, cursorList.Count, xp, yp);
             cursorList.Add(tcur);
             updatedCursorList.Add(tcur);
 
@@ -69,60 +73,69 @@ namespace TUIO
                 updatedCursorList.Add(tcur);
         }
 
-        public void updateTuioCursor(long s_id, float xp, float yp)
+        public void removeTuioCursor(TuioCursor tcur)
         {
-            TuioCursor tcur;
-            for (int i = 0; i < cursorList.Count; i++)
-            {
-                tcur = cursorList[i];
-                if (tcur.getSessionID() == s_id)
-                {
-                    updateTuioCursor(tcur, xp, yp);
-                    return;
-                }
-            }
+            cursorList.Remove(tcur);
         }
 
-        public void removeTuioCursor(TuioCursor tcur)
+        public TuioObject addTuioObject(float xp, float yp, float angle)
         {
-            cursorList.Remove(tcur);
+            TuioObject tobj = new TuioObject(sessionID, objectList.Count, xp, yp, angle);
+            objectList.Add(tobj);
+            updatedObjectList.Add(tobj);
+
+            sessionID++;
+            return tobj;
+        }
+
+        public void updateTuioObject(TuioObject tobj, float xp, float yp)
+        {
+            tobj.update(currentFrameTime, xp, yp);
+            if (!updatedObjectList.Contains(tobj))
+                updatedObjectList.Add(tobj);
         }
 
+        public void removeTuioObject(TuioObject tobj)
+        {
+            objectList.Remove(tobj);
+        }
 
         public void initFrame()
         {
             currentFrameTime = TuioTime.getSessionTime();
             updatedCursorList = new List<TuioCursor>();
+            updatedObjectList = new List<TuioObject>();
         }
 
         public void commitFrame()
         {
-            sendMessage(updatedCursorList);
+            sendMessage(updatedCursorList, updatedObjectList);
         }
 
         public void sendFullMessages()
         {
-            sendMessage(cursorList);
+            sendMessage(cursorList, objectList);
         }
 
-        private void sendMessage(List<TuioCursor> list)
+        private void sendMessage(List<TuioCursor> cursorList, List<TuioObject> objectList)
         {
             OSCBundle packet = new OSCBundle();
-            addAliveMessagesToBundle(packet);
-
             OSCMessage currentMessage;
-            TuioCursor cursor;
-            for (int i = 0; i < list.Count; i++)
+
+            // cursors
+            addAliveCursorMessagesToBundle(packet);
+            TuioCursor tcur;
+            for (int i = 0; i < cursorList.Count; i++)
             {
-                cursor = cursorList[i];
+                tcur = cursorList[i];
                 currentMessage = new OSCMessage("/tuio/2Dcur");
                 currentMessage.Append("set");
-                currentMessage.Append((Int32)cursor.getSessionID());
-                currentMessage.Append(cursor.getX());
-                currentMessage.Append(cursor.getY());
-                currentMessage.Append(cursor.getXSpeed());
-                currentMessage.Append(cursor.getYSpeed());
-                currentMessage.Append(cursor.getMotionAccel());
+                currentMessage.Append((Int32)tcur.getSessionID());
+                currentMessage.Append(tcur.getX());
+                currentMessage.Append(tcur.getY());
+                currentMessage.Append(tcur.getXSpeed());
+                currentMessage.Append(tcur.getYSpeed());
+                currentMessage.Append(tcur.getMotionAccel());
 
                 /*if (Marshal.SizeOf(packet) + Marshal.SizeOf(currentOscElement) >= MAX_PACKET_SIZE)
                 {
@@ -130,7 +143,7 @@ namespace TUIO
                     udpwriter.Send(packet);
 
                     packet = new OscBundle();
-                    addAliveMessagesToBundle(packet);
+                    addAliveCursorMessagesToBundle(packet);
                 }*/
                 packet.Append(currentMessage);
             }
@@ -138,10 +151,45 @@ namespace TUIO
             currentMessage.Append("fseq");
             currentMessage.Append(-1);
             packet.Append(currentMessage);
+
+            // objects
+            addAliveObjectMessagesToBundle(packet);
+            TuioObject tobj;
+            for (int i = 0; i < objectList.Count; i++)
+            {
+                tobj = objectList[i];
+                currentMessage = new OSCMessage("/tuio/2Dobj");
+                currentMessage.Append("set");
+                currentMessage.Append((Int32)tobj.getSessionID());
+                currentMessage.Append(tobj.getSymbolID());
+                currentMessage.Append(tobj.getX());
+                currentMessage.Append(tobj.getY());
+                currentMessage.Append(tobj.getAngle());
+                currentMessage.Append(tobj.getXSpeed());
+                currentMessage.Append(tobj.getYSpeed());
+                currentMessage.Append(tobj.getRotationSpeed());
+                currentMessage.Append(tobj.getMotionAccel());
+                currentMessage.Append(tobj.getRotationAccel());
+
+                /*if (Marshal.SizeOf(packet) + Marshal.SizeOf(currentOscElement) >= MAX_PACKET_SIZE)
+                {
+                    packet.AddElement(new OscElement("/tuio/2Dobj", new Object[] { "fseq", -1 }));
+                    udpwriter.Send(packet);
+
+                    packet = new OscBundle();
+                    addAliveObjectMessagesToBundle(packet);
+                }*/
+            }
+            currentMessage = new OSCMessage("/tuio/2Dobj");
+            currentMessage.Append("fseq");
+            currentMessage.Append(-1);
+            packet.Append(currentMessage);
+
+
             transmitter.Send(packet);
         }
 
-        private void addAliveMessagesToBundle(OSCBundle packet)
+        private void addAliveCursorMessagesToBundle(OSCBundle packet)
         {
             OSCMessage mssg = new OSCMessage("/tuio/2Dcur");
             mssg.Append("alive");
@@ -152,19 +200,15 @@ namespace TUIO
             packet.Append(mssg);
         }
 
-        public List<TuioCursor> getTuioCursor()
+        private void addAliveObjectMessagesToBundle(OSCBundle packet)
         {
-            return cursorList;
-        }
-
-        public TuioCursor getTuioCursor(long s_id)
-        {
-            for (int i = 0; i < cursorList.Count; i++)
+            OSCMessage mssg = new OSCMessage("/tuio/2Dcobj");
+            mssg.Append("alive");
+            for (int i = 0; i < objectList.Count; i++)
             {
-                if (cursorList[i].getSessionID() == s_id)
-                    return cursorList[i];
+                mssg.Append((Int32)objectList[i].getSessionID());
             }
-            return null;
+            packet.Append(mssg);
         }
     }
 }

+ 57 - 12
bbiwarg/TUIO/TuioCommunicator.cs

@@ -6,6 +6,7 @@ using System.Threading.Tasks;
 using System.Net;
 using System.Net.Sockets;
 using bbiwarg.Recognition.TouchRecognition;
+using bbiwarg.Recognition.PalmRecognition;
 using bbiwarg.Utility;
 using bbiwarg.Input.InputHandling;
 using TUIO;
@@ -15,12 +16,14 @@ namespace bbiwarg.TUIO
     class TuioCommunicator
     {
         private TuioServer server;
-        private Dictionary<int, TuioCursor> cursors;
+        private Dictionary<int, TuioCursor> tcursors;
+        private Dictionary<int, List<TuioObject>> tobjects;
 
         public TuioCommunicator(string host, int port)
         {
             server = new TuioServer(host, port);
-            cursors = new Dictionary<int, TuioCursor>();
+            tcursors = new Dictionary<int, TuioCursor>();
+            tobjects = new Dictionary<int, List<TuioObject>>();
         }
 
         public void handleNewFrameData(object sender, NewProcessedFrameEventArgs e)
@@ -37,18 +40,55 @@ namespace bbiwarg.TUIO
                     switch (te.Type)
                     {
                         case TouchEventType.Down:
-                            TuioCursor cursor = server.addTuioCursor(te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
-                            cursors.Add(te.Touch.TrackID, cursor);
+                            TuioCursor tcur = server.addTuioCursor(te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
+                            tcursors.Add(te.Touch.TrackID, tcur);
                             break;
                         case TouchEventType.Move:
-                            server.updateTuioCursor(cursors[te.Touch.TrackID], te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
+                            server.updateTuioCursor(tcursors[te.Touch.TrackID], te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
                             break;
                         case TouchEventType.Up:
-                            server.removeTuioCursor(cursors[te.Touch.TrackID]);
-                            cursors.Remove(te.Touch.TrackID);
+                            server.removeTuioCursor(tcursors[te.Touch.TrackID]);
+                            tcursors.Remove(te.Touch.TrackID);
                             break;
                     }
                 }
+
+                List<int> updatedIDs = new List<int>();
+                foreach (Palm palm in frameData.TrackedPalms)
+                {
+                    if (tobjects.Keys.Contains(palm.TrackID))
+                    {
+                        // update / move
+                        List<TuioObject> palmTobjs = tobjects[palm.TrackID];
+                        Vector2D[] corners = palm.Quad.Corners;
+                        for (int i = 0; i < 4; i++)
+                            server.updateTuioObject(palmTobjs[i], corners[i].X, corners[i].Y);
+                        updatedIDs.Add(palm.TrackID);
+                    }
+                    else
+                    {
+                        // add / create
+                        List<TuioObject> palmTobjs = new List<TuioObject>();
+                        Vector2D[] corners = palm.Quad.Corners;
+                        for (int i = 0; i < 4; i++)
+                            palmTobjs.Add(server.addTuioObject(corners[i].X, corners[i].Y, palm.TrackID + 0.1f*i));
+                        tobjects.Add(palm.TrackID, palmTobjs);
+                        updatedIDs.Add(palm.TrackID);
+                    }
+                }
+
+                // remove
+                List<int> 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();
         }
@@ -60,11 +100,16 @@ namespace bbiwarg.TUIO
 
         public void reset()
         {
-            foreach (int id in cursors.Keys)
-            {
-                server.removeTuioCursor(cursors[id]);
-            }
-            cursors.Clear();
+            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();
         }
 
         public static bool tryParseIPAddress(String ipIn, out String ipOut)

+ 1 - 0
bbiwarg/Utility/Quadrangle.cs

@@ -19,6 +19,7 @@ namespace bbiwarg.Utility
         public Vector2D TopRight { get; private set; }
         public Vector2D BottomRight { get; private set; }
         public Vector2D BottomLeft { get; private set; }
+        public Vector2D[] Corners { get { return new Vector2D[4] { TopLeft, TopRight, BottomRight, BottomLeft }; } }
 
         public Quadrangle(Vector2D topLeft, Vector2D topRight, Vector2D bottomRight, Vector2D bottomLeft)
         {

+ 1 - 0
bbiwarg/bbiwarg.csproj

@@ -89,6 +89,7 @@
     <Compile Include="Output\GlassesOutput\GlassesWindow.Designer.cs">
       <DependentUpon>GlassesWindow.cs</DependentUpon>
     </Compile>
+    <Compile Include="TUIO\TUIO\TuioObject.cs" />
     <Compile Include="Utility\CoordinateConverter.cs" />
     <Compile Include="Utility\ImageSize.cs" />
     <Compile Include="Input\InputHandling\FrameData.cs" />