TouchDesigner's .toe files are binary, so this example ships the parts that
can live in a text repository – a Python callbacks script and a recipe for the
network – rather than a project file. Building it takes about five minutes.
| File | Paste into |
|---|---|
trackosc_callbacks.py |
The Callbacks DAT of an OSC In DAT. Parses every TrackOSC message into Table DATs. |
trackosc_skeletons.py |
A Text DAT named trackosc_skeletons (joint names and edge lists, imported by the callbacks). |
trackosc_script_sop.py |
Optional: the callbacks DAT of a Script SOP, to draw skeletons as geometry. |
TrackOSC messages have a variable number of arguments (n detections, and
/faces/contour has a per-face point count) and carry strings (text,
animal labels, barcode payloads). An OSC In CHOP flattens each message
into fixed channels and drops strings, which works only for /camerainfo.
The OSC In DAT hands the raw argument list to Python, where the same
running-cursor parser as every other example turns it into tables – and
tables convert to CHOPs, SOPs or anything else.
- OSC In DAT (
oscin1): Network Port9527, Address Scope*, Bundle Timestamp off. Only one program can listen on a port – quit the native TrackOSC Receiver first. - Text DAT named exactly
trackosc_skeletons: pastetrackosc_skeletons.pyinto it. - Open
oscin1's Callbacks DAT (theoscin1_callbacksText DAT it creates) and replace its contents withtrackosc_callbacks.py. - Table DATs, one per message you want, named exactly:
camerainfo,poses,hands,faces,faces_box,faces_contour,texts,animals,poses3d,barcodes,animalposes,humans, andframes. Tables that don't exist are skipped, so start withposesandframes. Each fills with a header row and one row per joint / point / detection;framesholds the latest width, height and n per address. - Point a TrackOSC sender at this machine's IP, port 9527 (or run
swift run poseiosc-testsend 127.0.0.1 9527from the repository, orpython3 Examples/Python/trackosc_testsend.pywithout Xcode). The tables update live. - To get channels: DAT to CHOP on
poseswith thex,y,ccolumns selected, one sample per row (row = joint, see thenamecolumn). - To draw: a Script SOP with
trackosc_script_sop.pyas its callbacks, inside a Geometry COMP with a Line MAT, gives the body skeleton as line geometry in normalised coordinates; a Camera COMP + Render TOP shows it. ChangeTABLE/COUNTin the script for hands or animals.
| Table | Columns |
|---|---|
poses, hands, faces, animalposes |
det joint name x y c conf – pixels in the sent frame, origin top-left; c == 0 means missing |
texts, animals |
det conf left top width height label |
humans |
det conf left top width height |
faces_box |
det conf left top width height roll yaw pitch (degrees) |
faces_contour |
det point x y conf – an open jawline polyline; a face with no contour has no rows |
poses3d |
det joint name x y z px py conf bodyHeight – x/y/z metres (Vision camera space), px/py pixels |
barcodes |
det conf left top width height tl_x tl_y tr_x tr_y br_x br_y bl_x bl_y symbology payload |
camerainfo |
key value rows: width, height, orientation (0/90/180/270), facing (0 back, 1 front), time |
frames |
address width height n time |
Joint orders and edge lists: Examples/SKELETONS.md.
Wire format: the root README.
The parser is exercised outside TouchDesigner by
python3 -m unittest discover tests (stubbing op() and mod). The network
recipe was written from TouchDesigner's documentation, not run in
TouchDesigner by the author – if you build it, please open an issue or pull
request with the TouchDesigner version you used (and a .toe would be very
welcome).