{"id":19684119,"url":"https://github.com/interactivescapegmbh/tuionet","last_synced_at":"2025-04-29T05:32:04.078Z","repository":{"id":187709691,"uuid":"607132584","full_name":"InteractiveScapeGmbH/TuioNet","owner":"InteractiveScapeGmbH","description":"TuioNet is a .Net implementation of the TUIO specification by Martin Kaltenbrunner. It supports TUIO 1.1 and TUIO 2.0 ","archived":false,"fork":false,"pushed_at":"2025-04-22T14:35:00.000Z","size":260,"stargazers_count":8,"open_issues_count":3,"forks_count":1,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-04-22T15:41:01.990Z","etag":null,"topics":["tuio"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/InteractiveScapeGmbH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-02-27T11:36:18.000Z","updated_at":"2025-02-04T10:31:22.000Z","dependencies_parsed_at":"2023-10-16T22:35:35.120Z","dependency_job_id":"31635774-2dde-4136-9201-b521fbe28189","html_url":"https://github.com/InteractiveScapeGmbH/TuioNet","commit_stats":null,"previous_names":["interactivescapegmbh/tuionet"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteractiveScapeGmbH%2FTuioNet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteractiveScapeGmbH%2FTuioNet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteractiveScapeGmbH%2FTuioNet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InteractiveScapeGmbH%2FTuioNet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/InteractiveScapeGmbH","download_url":"https://codeload.github.com/InteractiveScapeGmbH/TuioNet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251444684,"owners_count":21590555,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["tuio"],"created_at":"2024-11-11T18:16:53.143Z","updated_at":"2025-04-29T05:32:03.780Z","avatar_url":"https://github.com/InteractiveScapeGmbH.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# TuioNet\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\nTuioNet is a .Net implementation of the TUIO specification by Martin Kaltenbrunner. It supports [TUIO 1.1](http://tuio.org/?specification) and [TUIO 2.0](http://www.tuio.org/?tuio20) for the following message profiles:\n\n**TUIO 1.1**\n```\n/tuio/2Dobj\n/tuio/2Dcur\n/tuio/2Dblb\n```\n\n**TUIO 2.0**\n```\n/tuio2/frm\n/tuio2/alv\n/tuio2/tok \n/tuio2/ptr \n/tuio2/bnd \n/tuio2/sym \n```\n\n## Documentation\nA brief overview over the most important classes and how to use them.\n\n### Tuio Session\nThe Tuio session class is the entry point for the communication between the client application and a TUIO sender. It takes the TUIO protocol version, the connection type and the IP-Address of the TUIO sender.\n\nBased on the protocol version the `TuioSession` creates a `Processor` which is responsible for parsing the incoming TUIO messages. By default, the `Processor` classes add `MessageListeners` for the currently supported Tuio profiles (see above for a list of the supported profiles). But it is also possible to register for your own custom message profile by calling `AddMessageListener` on the `TuioSession`. Here you are not limited to the Tuio profiles. You can register to every OSC message format your Tuio sender supports.\n\n```csharp\nusing(var session = new TuioSession(TuioVersion.Tuio11, TuioConnectionType.Websocket, \"10.0.0.31\"))\n{\n    session.AddMessageListener(new MessageListener(\"/my/profile/example\", OnMessage);\n    \n    private void OnMessage(object? sender, OSCMessage message)\n    {\n        // Do something with the message\n    }        \n}\n```\n\n### Tuio Processors\nTuio processors are responsible for parsing TUIO messages. There are two types of processors, one for TUIO 1.1 and one for TUIO 2.0. They get a client object and can listen to specific messages by register callback methods for them. In the current implementation the TUIO processors listen to the following message profiles.\n\nTuio11Processor.cs:\n```csharp\npublic Tuio11Processor(TuioClient client)\n{\n    client.AddMessageListeners(new List\u003cMessageListener\u003e()\n    {\n        new MessageListener(\"/tuio/2Dobj\", On2Dobj),\n        new MessageListener(\"/tuio/2Dcur\", On2Dcur),\n        new MessageListener(\"/tuio/2Dblb\", On2Dblb)\n    });\n    \n    TuioTime.Init();\n    _currentTime = TuioTime.GetCurrentTime();\n}\n```\n\nTuio20Processor.cs\n```csharp\npublic Tuio20Processor(TuioClient client)\n{\n    client.AddMessageListeners(new List\u003cMessageListener\u003e()\n    {\n        new MessageListener(\"/tuio2/frm\", OnFrm),\n        new MessageListener(\"/tuio2/alv\", OnAlv),\n        new MessageListener(\"/tuio2/tok\", OnOther),\n        new MessageListener(\"/tuio2/ptr\", OnOther),\n        new MessageListener(\"/tuio2/bnd\", OnOther),\n        new MessageListener(\"/tuio2/sym\", OnOther),\n    });\n    \n    TuioTime.Init();\n    _currentTime = TuioTime.GetCurrentTime();\n}\n```\n\n#### Add/Remove Message Listeners\nThe TUIO Specification ([1.1](http://tuio.org/?specification) and [2.0](http://www.tuio.org/?tuio20)) defines different kinds of\nTUIO message profiles:\u003c/br\u003e\n\nTUIO 1.1 Examples:\n```\n/tuio/2Dobj set s i x y a X Y A m r\n/tuio/2Dcur set s x y X Y m\n/tuio/2Dblb set s x y a w h f X Y A m r\n```\n\nTUIO 2.0 Examples:\n```\n/tuio2/tok s_id tu_id c_id x_pos y_pos angle [x_vel y_vel m_acc r_vel r_acc]\n/tuio2/ptr s_id tu_id c_id x_pos y_pos angle shear radius press [x_vel y_vel p_vel m_acc p_acc]\n/tuio2/bnd s_id x_pos y_pos angle width height area [x_vel y_vel a_vel m_acc r_acc]\n/tuio2/sym s_id tu_id c_id t_des data\n```\n\n## Events\nIn general there are four different kinds of events for TUIO 1.1 and 2.0: `Add`, `Update`, `Remove` and `Refresh`. The `Refresh` event gets triggered at the end of the current frame after all tuio messages were processed and it provides the current `TuioTime`. There are different `Add`, `Update` and `Remove` events for the different kinds of TUIO messages (cursor, object, blob, token...). All possible events are shown below.\n\n### TUIO 1.1\n#### OnRefreshed\nThe Refreshed event is triggered when a TUIO frame is completely processed. This event is useful to handle all updates contained in one TUIO frame together.\n\n```csharp\n_processor.OnRefreshed += OnRefreshed;\n\nprivate void OnRefreshed(object sender, TuioTime time)\n{\n    // update stuff after the whole tuio frame got processed\n}\n```\n\n#### OnCursorAdded\nThis event gets triggered when a new cursor was added this frame.\n```csharp\n_processor.OnCursorAdded += OnCursorAdded;\n\nprivate void OnCursorAdded(object sender, Tuio11Cursor cursor)\n{\n    Console.WriteLine($\"New cursor added -\u003e ID: {cursor.CursorId}\");\n}\n```\n\n#### OnCursorUpdated\nThis event gets triggered when an already known cursor gets updated, for example changes its position.\n```csharp\n_processor.OnCursorUpdated += OnCursorUpdated;\n\nprivate void OnCursorUpdated(object sender, Tuio11Cursor cursor)\n{\n    Console.WriteLine($\"Cursor {cursor.CursorId} -\u003e Position: {cursor.Position}\");\n}\n```\n\n#### OnCursorRemoved\nThis event gets triggered when a cursor was removed this frame.\n```csharp\n_processor.OnCursorRemoved += OnCursorRemoved;\n\nprivate void OnCursorAdded(object sender, Tuio11Cursor cursor)\n{\n    Console.WriteLine($\"Cursor {cursor.CursorId} removed\");\n}\n```\n\n#### OnObjectAdded\nThis event gets triggered when a new TUIO 1.1 object was added this frame.\n```csharp\n_processor.OnObjectAdded += OnObjectAdded;\n\nprivate void OnObjectAdded(object sender, Tuio11Object tuioObject)\n{\n    Console.WriteLine($\"New object added -\u003e ID: {tuioObject.SymbolId}\");\n}\n```\n\n#### OnObjectUpdated\nThis event gets triggered when an already known TUIO 1.1 object gets updated, for example changes its position or rotation.\n```csharp\n_processor.OnObjectUpdated += OnObjectUpdated;\n\nprivate void OnObjectUpdated(object sender, Tuio11Object tuioObject)\n{\n    Console.WriteLine($\"Object {tuioObject.SymbolId} -\u003e Position: {tuioObject.Position}\");\n}\n```\n\n#### OnObjectRemoved\nThis event gets triggered when a TUIO 1.1  object was removed this frame.\n```csharp\n_processor.OnObjectRemoved += OnObjectRemoved;\n\nprivate void OnObjectRemoved(object sender, Tuio11Object tuioObject)\n{\n    Console.WriteLine($\"Object {tuioObject.SymbolId} removed\");\n}\n```\n\n#### OnBlobAdded\nThis event gets triggered when a new TUIO 1.1 blob was added this frame.\n```csharp\n_processor.OnBlobAdded += OnBlobAdded;\n\nprivate void OnBlobAdded(object sender, Tuio11Blob blob)\n{\n    Console.WriteLine($\"New Blob added -\u003e ID: {blob.BlobId}\");\n}\n```\n\n#### OnBlobUpdated\nThis event gets triggered when an already known TUIO 1.1 blob gets updated, for example changes its position or rotation.\n```csharp\n_processor.OnBlobUpdated += OnBlobUpdated;\n\nprivate void OnBlobUpdated(object sender, Tuio11Blob blob)\n{\n    Console.WriteLine($\"Blob {blob.BlobId} -\u003e Position: {blob.Position}\");\n}\n```\n\n#### OnBlobRemoved\nThis event gets triggered when a TUIO 1.1 blob was removed this frame.\n```csharp\n_processor.OnBlobRemoved += OnBlobRemoved;\n\nprivate void OnBlobRemoved(object sender, Tuio11Blob blob)\n{\n    Console.WriteLine($\"Blob {blob.BlobId} removed\");\n}\n```\n\n### TUIO 2.0\n#### OnRefreshed\nThe Refreshed event is triggered when a TUIO frame is completely processed. This event is useful to handle all updates contained in one TUIO frame together.\n\n```csharp\n_processor.OnRefreshed += OnRefreshed;\n\nprivate void OnRefreshed(object sender, TuioTime time)\n{\n    // update stuff after the whole tuio frame got processed\n}\n\n```\n#### OnObjectAdded\nThis event gets triggered when a new TUIO 2.0 object was added this frame. This could be a pointer, token, bounds or symbol.\n```csharp\n_processor.OnObjectAdded += OnObjectAdded;\n\nprivate void OnObjectAdded(object sender, Tuio20Object tuioObject)\n{\n    // if you expect the object to be a pointer you can check it and act accordingly\n    if(tuioObject.ContainsTuioPointer())\n    {\n        Console.WriteLine($\"New Pointer added -\u003e ID: {tuioObject.Pointer.ComponentId}\");\n    }\n            \n}\n```\n\n#### OnObjectUpdated\nThis event gets triggered when an already known TUIO 2.0 object gets updated, for example changes its position.\n```csharp\n_processor.OnObjectUpdated += OnObjectUpdated;\n\nprivate void OnObjectUpdated(object sender, Tuio20Object tuioObject)\n{\n    // if you expect the object to be a token you can check it and act accordingly\n    if(tuioObject.ContainsTuioToken())\n    {\n        Console.WriteLine($\"Token {tuioObject.Token.ComponentId} -\u003e Position: {tuioObject.Token.Position}\");\n    }\n}\n```\n\n#### OnObjectRemoved\nThis event gets triggered when a TUIO 2.0 object was removed this frame.\n```csharp\n_processor.OnObjectRemoved += OnObjectRemoved;\n\nprivate void OnObjectRemoved(object sender, Tuio20Object tuioObject)\n{\n    // if you expect the object to be a symbol you can check it and act accordingly\n    if(tuioObject.ContainsTuioSymbol())\n    {\n        Console.WriteLine($\"Symbol {tuioObject.Symbol.ComponentId} removed\");\n    }\n}\n```\n\n## Demo Console Application\nA simple console application which demonstrates a simple setup for a TUIO 1.1 connection via UDP. \n- First create a `TuioSession` (the default port is 3333)\n- Get the `ITuioDispatcher` from the session object and cast it to the appropriate type based on the TUIO version (`Tuio11Dispatcher` or `Tuio20Dispatcher`).\n- Register methods for the desired events on the dispatcher object.\n- The connecting and disconnecting is handled by the session object. As soon as the session gets disposed it disconnects from the sender.\n- The application runs and prints to the console when TUIO objects/cursors appear, move or get removed.\n- By pressing the ```Q``` button you can stop the application.\n\nProgram.cs\n```csharp\nusing TuioNet.Common;\nusing TuioNet.Tuio11;\n\nnamespace TuioNet.Demo;\n\nclass Program\n{\n    private static void Main(string[] args)\n    {\n        using (var tuioSession = new TuioSession(TuioVersion.Tuio11, TuioConnectionType.UDP))\n        {\n            var dispatcher = (Tuio11Dispatcher)tuioSession.TuioDispatcher;\n            dispatcher.OnCursorAdd += CursorAdded;\n            dispatcher.OnCursorUpdate += UpdateCursor;\n            dispatcher.OnCursorRemove += RemoveCursor;\n            Console.WriteLine(\"Connect...\");\n            while (true)\n            {\n                if (!Console.KeyAvailable) continue;\n                var pressedKey = Console.ReadKey().Key;\n                if (pressedKey == ConsoleKey.Q) break;\n            }\n            Console.WriteLine(\"Disconnect...\");\n            dispatcher.OnCursorAdd -= CursorAdded;\n            dispatcher.OnCursorUpdate -= UpdateCursor;\n            dispatcher.OnCursorRemove -= RemoveCursor;\n        }\n    }\n\n    private static void RemoveCursor(object? sender, Tuio11Cursor cursor)\n    {\n        Console.WriteLine($\"Cursor {cursor.CursorId} removed\");\n    }\n\n    private static void UpdateCursor(object? sender, Tuio11Cursor cursor)\n    {\n        Console.WriteLine($\"Cursor {cursor.CursorId} -\u003e Position: {cursor.Position}\");\n    }\n\n    private static void CursorAdded(object? sender, Tuio11Cursor cursor)\n    {\n        Console.WriteLine($\"New cursor added -\u003e ID: {cursor.CursorId}\");\n    }\n}\n```\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://www.interactive-scape.com/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/51314413?v=4?s=100\" width=\"100px;\" alt=\"Erich Querner\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eErich Querner\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/InteractiveScapeGmbH/TuioNet/commits?author=eqbic\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/gilescoope\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/5291605?v=4?s=100\" width=\"100px;\" alt=\"Giles Coope\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eGiles Coope\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/InteractiveScapeGmbH/TuioNet/commits?author=gilescoope\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://modin.yuri.at/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/115223?v=4?s=100\" width=\"100px;\" alt=\"Martin Kaltenbrunner\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMartin Kaltenbrunner\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/InteractiveScapeGmbH/TuioNet/commits?author=mkalten\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finteractivescapegmbh%2Ftuionet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finteractivescapegmbh%2Ftuionet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finteractivescapegmbh%2Ftuionet/lists"}