├── .gitattributes ├── .gitignore ├── IsadoraExample ├── TT_logo_rgba_72.png └── kinect2share_demo-v3.izz ├── README.md ├── addons.make ├── icon.rc ├── kinect2share.sln ├── kinect2share.vcxproj ├── kinect2share.vcxproj.filters ├── screenshots └── sampleapp1.png └── src ├── main.cpp ├── ofApp.cpp └── ofApp.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ 246 | /FunctionKeys2016-v1.izz 247 | /kinect2share_demo-v2.izz 248 | /FunctionKeys2016-v2.izz 249 | /FunctionKeys2016-v3.izz 250 | /FunctionKeys2016-v4.izz 251 | /fk_media 252 | /FunctionKeys2016-v5.izz 253 | /FunctionKeys2016-v6.izz 254 | /FunctionKeys2016-v7.izz 255 | /IsadoraExample/kinect2share_demo-v2.izz 256 | /misc 257 | /notes.txt 258 | -------------------------------------------------------------------------------- /IsadoraExample/TT_logo_rgba_72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwebber/kinect2share/0767dbd419449e102b863f149f4096600d080b99/IsadoraExample/TT_logo_rgba_72.png -------------------------------------------------------------------------------- /IsadoraExample/kinect2share_demo-v3.izz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwebber/kinect2share/0767dbd419449e102b863f149f4096600d080b99/IsadoraExample/kinect2share_demo-v3.izz -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | #### kinect2share 3 | Share skeleton and video data from the Kinect V2 with Isadora or any other software which supports OSC (Open Sound Control), Spout, and/or NDI. 4 | 5 | ![Screen Shot including Isadora sample file](https://raw.githubusercontent.com/rwebber/kinect2share/master/screenshots/sampleapp1.png) 6 | 7 | Kinect2share is a *Windows only* OpenFrameworks app based on the example projects included in [Elliot Woods](https://github.com/elliotwoods) fantastic OpenFrameworks plugin, [ofxKinectForWindows2](https://github.com/elliotwoods/ofxKinectForWindows2). 8 | 9 | The goal of this project is to make as many Kinect2 features available to creative platforms as possible using open standards including OSC (opensoundcontrol), and [Spout](http://spout.zeal.co/). 10 | 11 | Specific care has been given to providing a demo file for use with the [Isadora creativity server](http://troikatronix.com/). 12 | This demo file provides basic functional examples that Isadora users can build upon. 13 | Currently the [Isadora version 2.5.x ](http://troikatronix.com/get-it/) is required to run the demo file. 14 | 15 | Since this project is developed using open standards it can easily be used with other popular tools/frameworks including: processing, resolume, max msp, touchdesigner, vvvv, qlab, and many more. 16 | Additionally Kinect2share allows sharing both the skeleton data and multiple video feeds over a network connection. 17 | This allows the Kinect V2 data to be used by Apple / Mac computers. (note this requires 2 computers, 1 mac and 1 pc) 18 | To connect a Mac to a PC running kinect2share you will require: 19 | - network router ( not required, but much easier than a direct PC/Mac network connection ) 20 | - to access the video feeds. Syphon2NDI for the Mac ( http://techlife.sg/TCPSyphon/ ) 21 | - to access the Skeleton data. Configure the OSC to broadcast. ( see: https://forum.openframeworks.cc/t/broadcasting-with-ofxosc/1625/3 ) 22 | Both video and skeleton data can be shared over a wireless connection, however; video performance is much better with a gigabit ethernet connection. 23 | 24 | ## Features 25 | ### Video 26 | Supported (provided via Spout): 27 | - Black and White Mask (512 x 424) 28 | - Color (1920 x 1080) 29 | - Keyed (512 x 424) *CPU process 30 | - Depth Image (512 x 424) 31 | 32 | ### OSC : Skeleton 33 | Supported: 34 | - Body data as JSON 35 | - Body elements as individual OSC addresses 36 | 37 | ### License 38 | MIT License http://en.wikipedia.org/wiki/MIT_License 39 | 40 | #### TODO 41 | - [video] Infrared 42 | - [video] Long Exposure Infrared 43 | - ~~[video] Depth~~ 44 | - [video] Keyed via GLSL 45 | - ~~[OSC] add body features (eg hands open/closed)~~ 46 | - [video] add option to adjust levels for depth image / IR images 47 | - ~~[NDI] network video sharing~~ 48 | 49 | 50 | ### Donations Accepted 51 | *** 52 | > [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CUG2B3AK7WYVQ) 53 | *** 54 | 55 | 56 | ## Notes 57 | 1. The release version requires the Kinect V2 SDK. 58 | https://www.microsoft.com/en-us/download/details.aspx?id=44561 59 | 2. The x86 2015 c++ redistributable is required from Microsoft as well. 60 | https://www.microsoft.com/en-us/download/confirmation.aspx?id=48145 61 | 3. To work with the code, you'll need the Kinect v2 SDK and the NewTek NDI sdk 62 | http://pages.newtek.com/NDI-Developers.html 63 | 64 | Additional ofx addons are used: 65 | - ofxGui (create parameters gui) *core addon 66 | - ofxOsc (shares skeleton data) *core addon 67 | - ofxInputField (adds text field for editing of OSC port & ip) https://github.com/fx-lange/ofxInputField 68 | - ofxSpout2 (shares video with other applications) https://github.com/Kj1/ofxSpout2 69 | - ofxNDI (networked video sharing) https://github.com/leadedge/ofxNDI 70 | - ofxKinectForWindows2 https://github.com/elliotwoods/ofxKinectForWindows2 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /addons.make: -------------------------------------------------------------------------------- 1 | ofxGui 2 | ofxInputField 3 | ofxKinectForWindows2 4 | ofxNDI 5 | ofxOsc 6 | ofxSpout2 7 | -------------------------------------------------------------------------------- /icon.rc: -------------------------------------------------------------------------------- 1 | // Icon Resource Definition 2 | #define MAIN_ICON 102 3 | 4 | #if defined(_DEBUG) 5 | MAIN_ICON ICON "icon_debug.ico" 6 | #else 7 | MAIN_ICON ICON "icon.ico" 8 | #endif 9 | -------------------------------------------------------------------------------- /kinect2share.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.25420.1 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kinect2share", "kinect2share.vcxproj", "{7FD42DF7-442E-479A-BA76-D0022F99702A}" 6 | EndProject 7 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openframeworksLib", "..\..\..\libs\openFrameworksCompiled\project\vs\openframeworksLib.vcxproj", "{5837595D-ACA9-485C-8E76-729040CE4B0B}" 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ofxKinectForWindows2Lib", "..\..\..\addons\ofxKinectForWindows2\ofxKinectForWindows2Lib\ofxKinectForWindows2Lib.vcxproj", "{F6008D6A-6D39-4B68-840E-E7AC8ED855DA}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Win32 = Debug|Win32 14 | Debug|x64 = Debug|x64 15 | Release|Win32 = Release|Win32 16 | Release|x64 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Debug|Win32.ActiveCfg = Debug|Win32 20 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Debug|Win32.Build.0 = Debug|Win32 21 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Debug|x64.ActiveCfg = Debug|x64 22 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Debug|x64.Build.0 = Debug|x64 23 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Release|Win32.ActiveCfg = Release|Win32 24 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Release|Win32.Build.0 = Release|Win32 25 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Release|x64.ActiveCfg = Release|x64 26 | {7FD42DF7-442E-479A-BA76-D0022F99702A}.Release|x64.Build.0 = Release|x64 27 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Debug|Win32.ActiveCfg = Debug|Win32 28 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Debug|Win32.Build.0 = Debug|Win32 29 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Debug|x64.ActiveCfg = Debug|x64 30 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Debug|x64.Build.0 = Debug|x64 31 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Release|Win32.ActiveCfg = Release|Win32 32 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Release|Win32.Build.0 = Release|Win32 33 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Release|x64.ActiveCfg = Release|x64 34 | {5837595D-ACA9-485C-8E76-729040CE4B0B}.Release|x64.Build.0 = Release|x64 35 | {F6008D6A-6D39-4B68-840E-E7AC8ED855DA}.Debug|Win32.ActiveCfg = Debug|Win32 36 | {F6008D6A-6D39-4B68-840E-E7AC8ED855DA}.Debug|Win32.Build.0 = Debug|Win32 37 | {F6008D6A-6D39-4B68-840E-E7AC8ED855DA}.Debug|x64.ActiveCfg = Debug|x64 38 | {F6008D6A-6D39-4B68-840E-E7AC8ED855DA}.Debug|x64.Build.0 = Debug|x64 39 | {F6008D6A-6D39-4B68-840E-E7AC8ED855DA}.Release|Win32.ActiveCfg = Release|Win32 40 | {F6008D6A-6D39-4B68-840E-E7AC8ED855DA}.Release|Win32.Build.0 = Release|Win32 41 | {F6008D6A-6D39-4B68-840E-E7AC8ED855DA}.Release|x64.ActiveCfg = Release|x64 42 | {F6008D6A-6D39-4B68-840E-E7AC8ED855DA}.Release|x64.Build.0 = Release|x64 43 | EndGlobalSection 44 | GlobalSection(SolutionProperties) = preSolution 45 | HideSolutionNode = FALSE 46 | EndGlobalSection 47 | EndGlobal 48 | -------------------------------------------------------------------------------- /kinect2share.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {7FD42DF7-442E-479A-BA76-D0022F99702A} 23 | Win32Proj 24 | kinect2share 25 | 26 | 27 | 28 | Application 29 | Unicode 30 | v140 31 | 32 | 33 | Application 34 | Unicode 35 | v140 36 | 37 | 38 | Application 39 | Unicode 40 | true 41 | v140 42 | 43 | 44 | Application 45 | Unicode 46 | true 47 | v140 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | bin\ 73 | obj\$(Configuration)\ 74 | $(ProjectName)_debug 75 | true 76 | true 77 | 78 | 79 | bin\ 80 | obj\$(Configuration)\ 81 | $(ProjectName)_debug 82 | true 83 | true 84 | 85 | 86 | bin\ 87 | obj\$(Configuration)\ 88 | false 89 | 90 | 91 | bin\ 92 | obj\$(Configuration)\ 93 | false 94 | 95 | 96 | 97 | Disabled 98 | EnableFastChecks 99 | %(PreprocessorDefinitions) 100 | MultiThreadedDebugDLL 101 | Level3 102 | %(AdditionalIncludeDirectories);src;..\..\..\addons\ofxGui\src;..\..\..\addons\ofxInputField\src;..\..\..\addons\ofxKinectForWindows2\src;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Data;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source;..\..\..\addons\ofxNDI\libs;..\..\..\addons\ofxNDI\libs\NDI;..\..\..\addons\ofxNDI\libs\NDI\Libs;..\..\..\addons\ofxNDI\libs\NDI\Libs\x64;..\..\..\addons\ofxNDI\libs\NDI\Libs\x86;..\..\..\addons\ofxNDI\src;..\..\..\addons\ofxOsc\libs;..\..\..\addons\ofxOsc\libs\oscpack;..\..\..\addons\ofxOsc\libs\oscpack\src;..\..\..\addons\ofxOsc\libs\oscpack\src\ip;..\..\..\addons\ofxOsc\libs\oscpack\src\ip\posix;..\..\..\addons\ofxOsc\libs\oscpack\src\ip\win32;..\..\..\addons\ofxOsc\libs\oscpack\src\osc;..\..\..\addons\ofxOsc\src;..\..\..\addons\ofxSpout2\libs;..\..\..\addons\ofxSpout2\libs\include;..\..\..\addons\ofxSpout2\libs\src;..\..\..\addons\ofxSpout2\src;..\..\..\addons\ofxNDI\include 103 | CompileAsCpp 104 | 105 | 106 | true 107 | Console 108 | false 109 | Processing.NDI.Lib.x86.lib;%(AdditionalDependencies) 110 | ../../../addons/ofxNDI/libs/NDI/Libs/x86;..\..\..\addons\ofxNDI\libs\NDI\Libs\x86;%(AdditionalLibraryDirectories) 111 | 112 | 113 | 114 | 115 | 116 | Disabled 117 | EnableFastChecks 118 | %(PreprocessorDefinitions) 119 | MultiThreadedDebugDLL 120 | Level3 121 | %(AdditionalIncludeDirectories);src;..\..\..\addons\ofxGui\src;..\..\..\addons\ofxInputField\src;..\..\..\addons\ofxKinectForWindows2\src;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Data;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source;..\..\..\addons\ofxNDI\libs;..\..\..\addons\ofxNDI\libs\NDI;..\..\..\addons\ofxNDI\libs\NDI\Libs;..\..\..\addons\ofxNDI\libs\NDI\Libs\x64;..\..\..\addons\ofxNDI\libs\NDI\Libs\x86;..\..\..\addons\ofxNDI\src;..\..\..\addons\ofxOsc\libs;..\..\..\addons\ofxOsc\libs\oscpack;..\..\..\addons\ofxOsc\libs\oscpack\src;..\..\..\addons\ofxOsc\libs\oscpack\src\ip;..\..\..\addons\ofxOsc\libs\oscpack\src\ip\posix;..\..\..\addons\ofxOsc\libs\oscpack\src\ip\win32;..\..\..\addons\ofxOsc\libs\oscpack\src\osc;..\..\..\addons\ofxOsc\src;..\..\..\addons\ofxSpout2\libs;..\..\..\addons\ofxSpout2\libs\include;..\..\..\addons\ofxSpout2\libs\src;..\..\..\addons\ofxSpout2\src 122 | CompileAsCpp 123 | true 124 | 125 | 126 | true 127 | Console 128 | false 129 | %(AdditionalDependencies) 130 | %(AdditionalLibraryDirectories) 131 | 132 | 133 | 134 | 135 | 136 | false 137 | %(PreprocessorDefinitions) 138 | MultiThreadedDLL 139 | Level3 140 | %(AdditionalIncludeDirectories);src;..\..\..\addons\ofxGui\src;..\..\..\addons\ofxInputField\src;..\..\..\addons\ofxKinectForWindows2\src;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Data;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source;..\..\..\addons\ofxNDI\libs;..\..\..\addons\ofxNDI\libs\NDI;..\..\..\addons\ofxNDI\libs\NDI\Libs;..\..\..\addons\ofxNDI\libs\NDI\Libs\x64;..\..\..\addons\ofxNDI\libs\NDI\Libs\x86;..\..\..\addons\ofxNDI\src;..\..\..\addons\ofxOsc\libs;..\..\..\addons\ofxOsc\libs\oscpack;..\..\..\addons\ofxOsc\libs\oscpack\src;..\..\..\addons\ofxOsc\libs\oscpack\src\ip;..\..\..\addons\ofxOsc\libs\oscpack\src\ip\posix;..\..\..\addons\ofxOsc\libs\oscpack\src\ip\win32;..\..\..\addons\ofxOsc\libs\oscpack\src\osc;..\..\..\addons\ofxOsc\src;..\..\..\addons\ofxSpout2\libs;..\..\..\addons\ofxSpout2\libs\include;..\..\..\addons\ofxSpout2\libs\src;..\..\..\addons\ofxSpout2\src;..\..\..\addons\ofxNDI\include 141 | CompileAsCpp 142 | true 143 | 144 | 145 | false 146 | false 147 | Console 148 | true 149 | true 150 | false 151 | Processing.NDI.Lib.x86.lib;%(AdditionalDependencies) 152 | ../../../addons/ofxNDI/libs/NDI/Libs/x86;..\..\..\addons\ofxNDI\libs\NDI\Libs\x86;%(AdditionalLibraryDirectories) 153 | 154 | 155 | 156 | 157 | 158 | false 159 | %(PreprocessorDefinitions) 160 | MultiThreadedDLL 161 | Level3 162 | %(AdditionalIncludeDirectories);src;..\..\..\addons\ofxGui\src;..\..\..\addons\ofxInputField\src;..\..\..\addons\ofxKinectForWindows2\src;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Data;..\..\..\addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source;..\..\..\addons\ofxNDI\libs;..\..\..\addons\ofxNDI\libs\NDI;..\..\..\addons\ofxNDI\libs\NDI\Libs;..\..\..\addons\ofxNDI\libs\NDI\Libs\x64;..\..\..\addons\ofxNDI\libs\NDI\Libs\x86;..\..\..\addons\ofxNDI\src;..\..\..\addons\ofxOsc\libs;..\..\..\addons\ofxOsc\libs\oscpack;..\..\..\addons\ofxOsc\libs\oscpack\src;..\..\..\addons\ofxOsc\libs\oscpack\src\ip;..\..\..\addons\ofxOsc\libs\oscpack\src\ip\posix;..\..\..\addons\ofxOsc\libs\oscpack\src\ip\win32;..\..\..\addons\ofxOsc\libs\oscpack\src\osc;..\..\..\addons\ofxOsc\src;..\..\..\addons\ofxSpout2\libs;..\..\..\addons\ofxSpout2\libs\include;..\..\..\addons\ofxSpout2\libs\src;..\..\..\addons\ofxSpout2\src 163 | CompileAsCpp 164 | 165 | 166 | false 167 | false 168 | Console 169 | true 170 | true 171 | false 172 | %(AdditionalDependencies) 173 | %(AdditionalLibraryDirectories) 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | {5837595d-aca9-485c-8e76-729040ce4b0b} 291 | 292 | 293 | {f6008d6a-6d39-4b68-840e-e7ac8ed855da} 294 | 295 | 296 | 297 | 298 | /D_DEBUG %(AdditionalOptions) 299 | /D_DEBUG %(AdditionalOptions) 300 | $(OF_ROOT)\libs\openFrameworksCompiled\project\vs 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | -------------------------------------------------------------------------------- /kinect2share.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | src 6 | 7 | 8 | src 9 | 10 | 11 | src 12 | 13 | 14 | src 15 | 16 | 17 | addons\ofxGui\src 18 | 19 | 20 | addons\ofxGui\src 21 | 22 | 23 | addons\ofxGui\src 24 | 25 | 26 | addons\ofxGui\src 27 | 28 | 29 | addons\ofxGui\src 30 | 31 | 32 | addons\ofxGui\src 33 | 34 | 35 | addons\ofxGui\src 36 | 37 | 38 | addons\ofxGui\src 39 | 40 | 41 | addons\ofxInputField\src 42 | 43 | 44 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Data 45 | 46 | 47 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Data 48 | 49 | 50 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2 51 | 52 | 53 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 54 | 55 | 56 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 57 | 58 | 59 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 60 | 61 | 62 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 63 | 64 | 65 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 66 | 67 | 68 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 69 | 70 | 71 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 72 | 73 | 74 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2 75 | 76 | 77 | addons\ofxNDI\src 78 | 79 | 80 | addons\ofxNDI\src 81 | 82 | 83 | addons\ofxNDI\src 84 | 85 | 86 | addons\ofxOsc\src 87 | 88 | 89 | addons\ofxOsc\src 90 | 91 | 92 | addons\ofxOsc\src 93 | 94 | 95 | addons\ofxOsc\src 96 | 97 | 98 | addons\ofxOsc\src 99 | 100 | 101 | addons\ofxOsc\libs\oscpack\src\ip 102 | 103 | 104 | addons\ofxOsc\libs\oscpack\src\ip\win32 105 | 106 | 107 | addons\ofxOsc\libs\oscpack\src\ip\win32 108 | 109 | 110 | addons\ofxOsc\libs\oscpack\src\osc 111 | 112 | 113 | addons\ofxOsc\libs\oscpack\src\osc 114 | 115 | 116 | addons\ofxOsc\libs\oscpack\src\osc 117 | 118 | 119 | addons\ofxOsc\libs\oscpack\src\osc 120 | 121 | 122 | addons\ofxSpout2\src 123 | 124 | 125 | addons\ofxSpout2\libs\src 126 | 127 | 128 | addons\ofxSpout2\libs\src 129 | 130 | 131 | addons\ofxSpout2\libs\src 132 | 133 | 134 | addons\ofxSpout2\libs\src 135 | 136 | 137 | addons\ofxSpout2\libs\src 138 | 139 | 140 | addons\ofxSpout2\libs\src 141 | 142 | 143 | addons\ofxSpout2\libs\src 144 | 145 | 146 | addons\ofxSpout2\libs\src 147 | 148 | 149 | addons\ofxSpout2\libs\src 150 | 151 | 152 | 153 | 154 | {d8376475-7454-4a24-b08a-aac121d3ad6f} 155 | 156 | 157 | {71834F65-F3A9-211E-73B8-DC85} 158 | 159 | 160 | {4F2A59AF-5F4E-704B-D067-EC13} 161 | 162 | 163 | {645E9533-4DCD-6179-1CDF-CB65} 164 | 165 | 166 | {D638171E-C38D-0A35-CFB3-8971} 167 | 168 | 169 | {A25CD3D6-9534-BE4E-B514-C157} 170 | 171 | 172 | {79EE9CEE-5877-E1B3-C373-D5C8} 173 | 174 | 175 | {BBA641E3-A9C6-8646-2A06-7A9D} 176 | 177 | 178 | {849A6419-451E-EB51-E82D-5D04} 179 | 180 | 181 | {D3FA8E7E-7250-B64E-BCC8-522E} 182 | 183 | 184 | {D8ABF3AE-C83C-4B28-80F0-8B6D} 185 | 186 | 187 | {577C5AAC-F44E-A0BE-E58F-B066} 188 | 189 | 190 | {3BB183CD-62BF-E58A-FD5C-A603} 191 | 192 | 193 | {D91DCA33-6E5D-4481-2AEC-9FBB} 194 | 195 | 196 | {B9DD339A-D93D-92A1-0A2F-4B41} 197 | 198 | 199 | {99ECA1D9-873F-4622-8FC0-FC7B} 200 | 201 | 202 | {D3A98534-1602-4FEF-57A6-6593} 203 | 204 | 205 | {BFB5BB47-98C8-BBCB-3066-1046} 206 | 207 | 208 | {5A029128-EB41-95C5-CBC0-CDED} 209 | 210 | 211 | {79DFDFE2-400B-8654-3675-01A3} 212 | 213 | 214 | {EDACB89C-9768-9551-4D41-B590} 215 | 216 | 217 | {DB49CB87-27C8-0C02-F602-86D7} 218 | 219 | 220 | {917203BC-05C2-034C-1B38-B098} 221 | 222 | 223 | {68A64BA7-C89A-C657-EC7A-10D6} 224 | 225 | 226 | {76E15BF2-5348-07F8-F8E1-A911} 227 | 228 | 229 | {EED9D931-64B9-6EC6-5E54-A96C} 230 | 231 | 232 | 233 | 234 | src 235 | 236 | 237 | src 238 | 239 | 240 | addons\ofxGui\src 241 | 242 | 243 | addons\ofxGui\src 244 | 245 | 246 | addons\ofxGui\src 247 | 248 | 249 | addons\ofxGui\src 250 | 251 | 252 | addons\ofxGui\src 253 | 254 | 255 | addons\ofxGui\src 256 | 257 | 258 | addons\ofxGui\src 259 | 260 | 261 | addons\ofxGui\src 262 | 263 | 264 | addons\ofxGui\src 265 | 266 | 267 | addons\ofxInputField\src 268 | 269 | 270 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Data 271 | 272 | 273 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Data 274 | 275 | 276 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2 277 | 278 | 279 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 280 | 281 | 282 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 283 | 284 | 285 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 286 | 287 | 288 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 289 | 290 | 291 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 292 | 293 | 294 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 295 | 296 | 297 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 298 | 299 | 300 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2\Source 301 | 302 | 303 | addons\ofxKinectForWindows2\src\ofxKinectForWindows2 304 | 305 | 306 | addons\ofxKinectForWindows2\src 307 | 308 | 309 | addons\ofxNDI\src 310 | 311 | 312 | addons\ofxNDI\src 313 | 314 | 315 | addons\ofxNDI\src 316 | 317 | 318 | addons\ofxNDI\src 319 | 320 | 321 | addons\ofxOsc\src 322 | 323 | 324 | addons\ofxOsc\src 325 | 326 | 327 | addons\ofxOsc\src 328 | 329 | 330 | addons\ofxOsc\src 331 | 332 | 333 | addons\ofxOsc\src 334 | 335 | 336 | addons\ofxOsc\src 337 | 338 | 339 | addons\ofxOsc\src 340 | 341 | 342 | addons\ofxOsc\libs\oscpack\src\ip 343 | 344 | 345 | addons\ofxOsc\libs\oscpack\src\ip 346 | 347 | 348 | addons\ofxOsc\libs\oscpack\src\ip 349 | 350 | 351 | addons\ofxOsc\libs\oscpack\src\ip 352 | 353 | 354 | addons\ofxOsc\libs\oscpack\src\ip 355 | 356 | 357 | addons\ofxOsc\libs\oscpack\src\osc 358 | 359 | 360 | addons\ofxOsc\libs\oscpack\src\osc 361 | 362 | 363 | addons\ofxOsc\libs\oscpack\src\osc 364 | 365 | 366 | addons\ofxOsc\libs\oscpack\src\osc 367 | 368 | 369 | addons\ofxOsc\libs\oscpack\src\osc 370 | 371 | 372 | addons\ofxOsc\libs\oscpack\src\osc 373 | 374 | 375 | addons\ofxOsc\libs\oscpack\src\osc 376 | 377 | 378 | addons\ofxOsc\libs\oscpack\src\osc 379 | 380 | 381 | addons\ofxSpout2\src 382 | 383 | 384 | addons\ofxSpout2\libs\include 385 | 386 | 387 | addons\ofxSpout2\libs\include 388 | 389 | 390 | addons\ofxSpout2\libs\include 391 | 392 | 393 | addons\ofxSpout2\libs\include 394 | 395 | 396 | addons\ofxSpout2\libs\include 397 | 398 | 399 | addons\ofxSpout2\libs\include 400 | 401 | 402 | addons\ofxSpout2\libs\include 403 | 404 | 405 | addons\ofxSpout2\libs\include 406 | 407 | 408 | addons\ofxSpout2\libs\include 409 | 410 | 411 | addons\ofxSpout2\libs\include 412 | 413 | 414 | addons\ofxSpout2\libs\include 415 | 416 | 417 | 418 | 419 | 420 | -------------------------------------------------------------------------------- /screenshots/sampleapp1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwebber/kinect2share/0767dbd419449e102b863f149f4096600d080b99/screenshots/sampleapp1.png -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") // Hide console window 2 | 3 | #include "ofMain.h" 4 | #include "ofApp.h" 5 | 6 | /* 7 | * kinect2share 8 | * 9 | * Created by Ryan Webber 10 | * http://www.DusXproductions.com 11 | * https://github.com/rwebber 12 | * 13 | * The goal of this project is to make as many Kinect2 features available to creative platforms as possible, 14 | * using open standards including OSC (opensoundcontrol), Spout, and NDI (https://www.newtek.com/ndi/). 15 | * 16 | * Specific care has been given to providing a demo file for use with the Isadora creativity server. 17 | * The demo file provides basic functional examples that Isadora users can build upon. 18 | * http://troikatronix.com/ 19 | * 20 | * MIT License http://en.wikipedia.org/wiki/MIT_License 21 | * 22 | * This project is built using OpenFrameWorks and utilizes a number of amazing addons offered by the community. 23 | * Please read the ReadMe file included in the github reprository, for details. 24 | */ 25 | 26 | //======================================================================== 27 | int main( ){ 28 | 29 | // this kicks off the running of my app 30 | // can be OF_WINDOW or OF_FULLSCREEN 31 | // pass in width and height too: 32 | 33 | //ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 34 | //ofRunApp(new ofApp()); 35 | 36 | 37 | // custom windows setup. 38 | ofGLFWWindowSettings settings; 39 | //settings.iconified = true; 40 | settings.resizable = false; 41 | settings.width = 1024; 42 | settings.height = 768; 43 | ofCreateWindow(settings); 44 | return ofRunApp(new ofApp); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | /* 4 | * kinect2share 5 | * 6 | * Created by Ryan Webber 7 | * http://www.DusXproductions.com 8 | * https://github.com/rwebber 9 | * 10 | * The goal of this project is to make as many Kinect2 features available to creative platforms as possible, 11 | * using open standards including OSC (opensoundcontrol), Spout, and NDI (https://www.newtek.com/ndi/). 12 | * 13 | * Specific care has been given to providing a demo file for use with the Isadora creativity server. 14 | * The demo file provides basic functional examples that Isadora users can build upon. 15 | * http://troikatronix.com/ 16 | * 17 | * MIT License http://en.wikipedia.org/wiki/MIT_License 18 | * 19 | * This project is built using OpenFrameWorks and utilizes a number of amazing addons offered by the community. 20 | * Please read the ReadMe file included in the github reprository, for details. 21 | */ 22 | 23 | #define DEPTH_WIDTH 512 24 | #define DEPTH_HEIGHT 424 25 | #define DEPTH_SIZE DEPTH_WIDTH * DEPTH_HEIGHT 26 | 27 | #define COLOR_WIDTH 1920 28 | #define COLOR_HEIGHT 1080 29 | 30 | int previewWidth = DEPTH_WIDTH / 2; // width and hieght of Depth Camera scaled 31 | int previewHeight = DEPTH_HEIGHT / 2; 32 | 33 | string guiFile = "settings.xml"; 34 | 35 | // REF: http://www.cplusplus.com/reference/cstring/ 36 | 37 | // TODO: look into https://forum.openframeworks.cc/t/ofxkinectforwindows2-depth-threshold-for-blob-tracking/19012/2 38 | 39 | // TODO: refactor 'kv2status' into user defineable address 40 | 41 | //-------------------------------------------------------------- 42 | void ofApp::setup() { 43 | ofSetWindowTitle("kinect2share"); 44 | ofSetFrameRate(30); 45 | ofSetVerticalSync(true); 46 | 47 | color_StreamName = "kv2_color"; 48 | cutout_StreamName = "kv2_cutout"; 49 | depth_StreamName = "kv2_depth"; 50 | keyed_StreamName = "kv2_keyed"; 51 | 52 | kinect.open(); 53 | kinect.initDepthSource(); 54 | kinect.initColorSource(); 55 | kinect.initInfraredSource(); 56 | kinect.initBodySource(); 57 | kinect.initBodyIndexSource(); 58 | 59 | // added for coordmapping 60 | if (kinect.getSensor()->get_CoordinateMapper(&coordinateMapper) < 0) { 61 | ofLogError() << "Could not acquire CoordinateMapper!"; 62 | } 63 | numBodiesTracked = 0; 64 | bHaveAllStreams = false; 65 | foregroundImg.allocate(DEPTH_WIDTH, DEPTH_HEIGHT, OF_IMAGE_COLOR_ALPHA); 66 | colorCoords.resize(DEPTH_WIDTH * DEPTH_HEIGHT); 67 | // end add for coordmapping 68 | 69 | ofSetWindowShape(previewWidth * 3, previewHeight * 2); 70 | 71 | //ofDisableArbTex(); // needed for textures to work... May be needed for NDI? 72 | // seems above is needed if loading an image file -> texture 73 | bgCB.load("images/checkerbg.png"); 74 | 75 | // TODO: depth and IR to be added -> fboDepth 76 | fboDepth.allocate(DEPTH_WIDTH, DEPTH_HEIGHT, GL_RGBA); //setup offscreen buffer in openGL RGBA mode (used for Keyed and B+W bodies.) 77 | fboColor.allocate(COLOR_WIDTH, COLOR_HEIGHT, GL_RGB); //setup offscreen buffer in openGL RGB mode 78 | 79 | 80 | // GUI SETUP ***************** http://openframeworks.cc/documentation/ofxGui/ 81 | gui.setup("Parameters", guiFile); 82 | gui.setHeaderBackgroundColor(ofColor::darkRed); 83 | gui.setBorderColor(ofColor::darkRed); 84 | //gui.setDefaultWidth(320); 85 | 86 | OSCgroup.setup("OSC"); 87 | OSCgroup.add(jsonGrouped.setup("OSC as JSON", true)); 88 | OSCgroup.add(HostField.setup("Host ip", "localhost")); 89 | OSCgroup.add(oscPort.setup("Output port", 1234)); 90 | OSCgroup.add(oscPortIn.setup("Input port", 4321)); 91 | gui.add(&OSCgroup); 92 | 93 | SPOUTgroup.setup("Spout"); 94 | SPOUTgroup.add(spoutCutOut.setup("BnW cutouts -> spout", true)); 95 | SPOUTgroup.add(spoutColor.setup("Color -> spout", true)); 96 | SPOUTgroup.add(spoutKeyed.setup("Keyed -> spout", true)); 97 | SPOUTgroup.add(spoutDepth.setup("Depth -> spout", true)); 98 | gui.add(&SPOUTgroup); 99 | 100 | NDIgroup.setup("NDI"); 101 | NDIgroup.add(ndiActive.setup("On-Off ", true)); 102 | NDIgroup.add(ndiCutOut.setup("BnW cutouts -> NDI", true)); 103 | NDIgroup.add(ndiColor.setup("Color -> NDI", true)); 104 | NDIgroup.add(ndiKeyed.setup("Keyed -> NDI", true)); 105 | NDIgroup.add(ndiDepth.setup("Depth -> NDI", true)); 106 | gui.add(&NDIgroup); 107 | 108 | gui.loadFromFile(guiFile); 109 | //if (!gui.loadFromFile(guiFile)) { 110 | // ofLogError("kv2") << "Unable to load settings xml"; 111 | // ofExit(); 112 | //} 113 | 114 | // HostField.addListener(this, &ofApp::HostFieldChanged); 115 | 116 | // OSC setup * * * * * * * * * * * * * 117 | // OSC setup * * * * * * * * * * * * * 118 | // OSC setup * * * * * * * * * * * * * 119 | oscSender.disableBroadcast(); 120 | oscSender.setup(HostField, oscPort); 121 | oscReceiver.setup(oscPortIn); 122 | 123 | // NDI setup * * * * * * * * * * * * * 124 | // NDI setup * * * * * * * * * * * * * 125 | // NDI setup * * * * * * * * * * * * * 126 | 127 | if (ndiActive){ 128 | NDIlock = false; 129 | cout << "NDI SDK copyright NewTek (http:\\NDI.NewTek.com)" << endl; 130 | // Set the dimensions of the sender output here 131 | // This is independent of the size of the display window 132 | //senderWidth = 1920; // HD - PBO 150fps / 120fps Async/Sync unclocked 133 | //senderHeight = 1080; // FBO 80fps / 75fps Async/Sync unclocked 134 | 135 | // TODO : async currently doesn't work??? 136 | // Optionally set NDI asynchronous sending instead of clocked at 60fps 137 | ndiSender1.SetAsync(false); // change to true for async 138 | ndiSender2.SetAsync(false); // change to true for async 139 | ndiSender3.SetAsync(false); // change to true for async 140 | ndiSender4.SetAsync(false); // change to true for async 141 | 142 | int senderWidth; 143 | int senderHeight; 144 | 145 | //================================================== 146 | //================================================== 147 | senderWidth = COLOR_WIDTH; 148 | senderHeight = COLOR_HEIGHT; 149 | 150 | // Initialize ofPixel buffers 151 | color_ndiBuffer[0].allocate(senderWidth, senderHeight, 4); 152 | color_ndiBuffer[1].allocate(senderWidth, senderHeight, 4); 153 | 154 | //// Create a new sender 155 | strcpy(senderName, color_StreamName.c_str()); 156 | ndiSender1.CreateSender(senderName, senderWidth, senderHeight, NDIlib_FourCC_type_RGBA); //// Specify RGBA format here 157 | cout << "Created NDI sender [" << senderName << "] (" << senderWidth << "x" << senderHeight << ")" << endl; 158 | color_idx = 0; // index used for buffer swapping 159 | 160 | //================================================== 161 | //================================================== 162 | senderWidth = DEPTH_WIDTH; 163 | senderHeight = DEPTH_HEIGHT; 164 | 165 | // Initialize ofPixel buffers 166 | cutout_ndiBuffer[0].allocate(senderWidth, senderHeight, 4); 167 | cutout_ndiBuffer[1].allocate(senderWidth, senderHeight, 4); 168 | 169 | // Create a new sender 170 | strcpy(senderName, cutout_StreamName.c_str()); 171 | ndiSender2.CreateSender(senderName, senderWidth, senderHeight, NDIlib_FourCC_type_RGBA); //// Specify RGBA format here 172 | cout << "Created NDI sender [" << senderName << "] (" << senderWidth << "x" << senderHeight << ")" << endl; 173 | cutout_idx = 0; // index used for buffer swapping 174 | 175 | //================================================== 176 | //================================================== 177 | senderWidth = DEPTH_WIDTH; 178 | senderHeight = DEPTH_HEIGHT; 179 | 180 | // Initialize ofPixel buffers 181 | depth_ndiBuffer[0].allocate(senderWidth, senderHeight, 4); 182 | depth_ndiBuffer[1].allocate(senderWidth, senderHeight, 4); 183 | 184 | // Create a new sender 185 | strcpy(senderName, depth_StreamName.c_str()); 186 | ndiSender3.CreateSender(senderName, senderWidth, senderHeight, NDIlib_FourCC_type_RGBA); //// Specify RGBA format here 187 | cout << "Created NDI sender [" << senderName << "] (" << senderWidth << "x" << senderHeight << ")" << endl; 188 | depth_idx = 0; // index used for buffer swapping 189 | 190 | //================================================== 191 | //================================================== 192 | senderWidth = DEPTH_WIDTH; 193 | senderHeight = DEPTH_HEIGHT; 194 | 195 | // Initialize ofPixel buffers 196 | keyed_ndiBuffer[0].allocate(senderWidth, senderHeight, 4); 197 | keyed_ndiBuffer[1].allocate(senderWidth, senderHeight, 4); 198 | 199 | // Create a new sender 200 | strcpy(senderName, keyed_StreamName.c_str()); 201 | ndiSender4.CreateSender(senderName, senderWidth, senderHeight, NDIlib_FourCC_type_RGBA); //// Specify RGBA format here 202 | cout << "Created NDI sender [" << senderName << "] (" << senderWidth << "x" << senderHeight << ")" << endl; 203 | keyed_idx = 0; // index used for buffer swapping 204 | 205 | //NDI SENDER 1 colorSize============================ 206 | //================================================== 207 | // Initialize OpenGL pbos for asynchronous read of fbo data 208 | 209 | senderWidth = COLOR_WIDTH; // DUSX resetting to work with color_ndi 210 | senderHeight = COLOR_HEIGHT; 211 | glGenBuffers(2, ndiPbo1); 212 | glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ndiPbo1[0]); 213 | glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, senderWidth*senderHeight * 4, 0, GL_STREAM_READ); 214 | glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ndiPbo1[1]); 215 | glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, senderWidth*senderHeight * 4, 0, GL_STREAM_READ); 216 | glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 217 | Pbo1Index = NextPbo1Index = 0; 218 | bUsePBO1 = true; // Change to false to compare // DUSX was originally true 219 | 220 | //NDI SENDER 2 depthSize============================ 221 | //================================================== 222 | // Initialize OpenGL pbos for asynchronous read of fbo data 223 | 224 | senderWidth = DEPTH_WIDTH; // DUSX resetting to work with color_ndi 225 | senderHeight = DEPTH_HEIGHT; 226 | glGenBuffers(2, ndiPbo2); 227 | glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ndiPbo2[0]); 228 | glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, senderWidth*senderHeight * 4, 0, GL_STREAM_READ); 229 | glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ndiPbo2[1]); 230 | glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, senderWidth*senderHeight * 4, 0, GL_STREAM_READ); 231 | glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 232 | Pbo2Index = NextPbo2Index = 0; 233 | bUsePBO2 = true; // Change to false to compare // DUSX was originally true 234 | } 235 | else { 236 | NDIlock = true; 237 | } 238 | // NDI setup DONE ^ ^ ^ * * * * * * * * * * 239 | // NDI setup DONE ^ ^ ^ * * * * * * * * * * 240 | // NDI setup DONE ^ ^ ^ * * * * * * * * * * 241 | } 242 | 243 | //-------------------------------------------------------------- 244 | void ofApp::update() { 245 | // get OSC messages 246 | while (oscReceiver.hasWaitingMessages()) { 247 | ofxOscMessage m; 248 | oscReceiver.getNextMessage(&m); 249 | 250 | if (m.getAddress() == "/app-exit") { 251 | bool trigger = m.getArgAsInt(0); 252 | //string s = m.getArgAsString(0); 253 | if (trigger) { 254 | exit(); 255 | std::exit(0); 256 | oscSendMsg("exit", "/kv2status/"); 257 | } 258 | } 259 | } 260 | 261 | //KV2 262 | kinect.update(); 263 | 264 | // Get pixel data 265 | auto& depthPix = kinect.getDepthSource()->getPixels(); 266 | auto& bodyIndexPix = kinect.getBodyIndexSource()->getPixels(); 267 | auto& colorPix = kinect.getColorSource()->getPixels(); 268 | 269 | // Make sure there's some data here, otherwise the cam probably isn't ready yet 270 | if (!depthPix.size() || !bodyIndexPix.size() || !colorPix.size()) { 271 | bHaveAllStreams = false; 272 | return; 273 | } 274 | else { 275 | bHaveAllStreams = true; 276 | } 277 | 278 | // Count number of tracked bodies 279 | numBodiesTracked = 0; 280 | auto& bodies = kinect.getBodySource()->getBodies(); 281 | for (auto& body : bodies) { 282 | if (body.tracked) { 283 | numBodiesTracked++; 284 | } 285 | } 286 | 287 | // Do the depth space -> color space mapping 288 | // More info here: 289 | // https://msdn.microsoft.com/en-us/library/windowspreview.kinect.coordinatemapper.mapdepthframetocolorspace.aspx 290 | // https://msdn.microsoft.com/en-us/library/dn785530.aspx 291 | coordinateMapper->MapDepthFrameToColorSpace(DEPTH_SIZE, (UINT16*)depthPix.getPixels(), DEPTH_SIZE, (ColorSpacePoint*)colorCoords.data()); 292 | 293 | // Loop through the depth image 294 | if (spoutKeyed || ndiKeyed) { 295 | for (int y = 0; y < DEPTH_HEIGHT; y++) { 296 | for (int x = 0; x < DEPTH_WIDTH; x++) { 297 | int index = (y * DEPTH_WIDTH) + x; 298 | 299 | ofColor trans(0, 0, 0, 0); 300 | foregroundImg.setColor(x, y, trans); 301 | 302 | // This is the check to see if a given pixel is inside a tracked body or part of the background. 303 | // If it's part of a body, the value will be that body's id (0-5), or will > 5 if it's 304 | // part of the background 305 | // More info here: https://msdn.microsoft.com/en-us/library/windowspreview.kinect.bodyindexframe.aspx 306 | float val = bodyIndexPix[index]; 307 | if (val >= bodies.size()) { 308 | continue; // exit for loop without executing the following code 309 | } 310 | 311 | // For a given (x,y) in the depth image, lets look up where that point would be 312 | // in the color image 313 | ofVec2f mappedCoord = colorCoords[index]; 314 | 315 | // Mapped x/y coordinates in the color can come out as floats since it's not a 1:1 mapping 316 | // between depth <-> color spaces i.e. a pixel at (100, 100) in the depth image could map 317 | // to (405.84637, 238.13828) in color space 318 | // So round the x/y values down to ints so that we can look up the nearest pixel 319 | mappedCoord.x = floor(mappedCoord.x); 320 | mappedCoord.y = floor(mappedCoord.y); 321 | 322 | // Make sure it's within some sane bounds, and skip it otherwise 323 | if (mappedCoord.x < 0 || mappedCoord.y < 0 || mappedCoord.x >= COLOR_WIDTH || mappedCoord.y >= COLOR_HEIGHT) { 324 | continue; 325 | } 326 | 327 | // Finally, pull the color from the color image based on its coords in 328 | // the depth image 329 | foregroundImg.setColor(x, y, colorPix.getColor(mappedCoord.x, mappedCoord.y)); 330 | } 331 | } 332 | } 333 | 334 | // Update the images since we manipulated the pixels manually. This uploads to the 335 | // pixel data to the texture on the GPU so it can get drawn to screen 336 | foregroundImg.update(); 337 | 338 | //-- 339 | //Getting joint positions (skeleton tracking) 340 | //-- 341 | // 342 | 343 | /****************** ENUM copied from kinectv2 addon 344 | JointType_SpineBase = 0, 345 | JointType_SpineMid = 1, 346 | JointType_Neck = 2, 347 | JointType_Head = 3, 348 | JointType_ShoulderLeft = 4, 349 | JointType_ElbowLeft = 5, 350 | JointType_WristLeft = 6, 351 | JointType_HandLeft = 7, 352 | JointType_ShoulderRight = 8, 353 | JointType_ElbowRight = 9, 354 | JointType_WristRight = 10, 355 | JointType_HandRight = 11, 356 | JointType_HipLeft = 12, 357 | JointType_KneeLeft = 13, 358 | JointType_AnkleLeft = 14, 359 | JointType_FootLeft = 15, 360 | JointType_HipRight = 16, 361 | JointType_KneeRight = 17, 362 | JointType_AnkleRight = 18, 363 | JointType_FootRight = 19, 364 | JointType_SpineShoulder = 20, 365 | JointType_HandTipLeft = 21, 366 | JointType_ThumbLeft = 22, 367 | JointType_HandTipRight = 23, 368 | JointType_ThumbRight = 24, 369 | JointType_Count = (JointType_ThumbRight + 1) 370 | */ 371 | 372 | 373 | // shorten names to minimize packet size 374 | const char * jointNames[] = { "SpineBase", "SpineMid", "Neck", "Head", 375 | "ShldrL", "ElbowL", "WristL", "HandL", 376 | "ShldrR", "ElbowR", "WristR", "HandR", 377 | "HipL", "KneeL", "AnkleL", "FootL", 378 | "HipR", "KneeR", "AnkleR", "FootR", 379 | "SpineShldr", "HandTipL", "ThumbL", "HandTipR", "ThumbR", "Count" }; 380 | 381 | /* MORE joint. values >>> 382 | second. positionInWorld[] x y z , positionInDepthMap[] x y 383 | second. orientation. _v[] x y z w ??what is this 384 | second. trackingState 385 | */ 386 | 387 | /* MORE body. values >>> 388 | body. tracked (bool) 389 | body. leftHandState (_Handstate) enum? 390 | body. rightHandState (_Handstate) 391 | body. activity ??what is this 392 | */ 393 | 394 | // defined in new coordmap section as & 395 | // auto bodies = kinect.getBodySource()->getBodies(); 396 | 397 | 398 | if (jsonGrouped) { 399 | body2JSON(bodies, jointNames); 400 | }else{ 401 | // TODO:: seperate function and add additional features like hand open/closed 402 | // NON JSON osc messages 403 | for (auto body : bodies) { 404 | for (auto joint : body.joints) { 405 | auto pos = joint.second.getPositionInWorld(); 406 | ofxOscMessage m; 407 | string adrs = "/" + to_string(body.bodyId) + "/" + jointNames[joint.first]; 408 | m.setAddress(adrs); 409 | m.addFloatArg(pos.x); 410 | m.addFloatArg(pos.y); 411 | m.addFloatArg(pos.z); 412 | m.addStringArg(jointNames[joint.first]); 413 | oscSender.sendMessage(m); 414 | 415 | } // end inner joints loop 416 | } // end body loop 417 | 418 | } // end if/else 419 | 420 | 421 | 422 | //-- 423 | //Getting bones (connected joints) 424 | //-- 425 | // 426 | 427 | { 428 | //// Note that for this we need a reference of which joints are connected to each other. 429 | //// We call this the 'boneAtlas', and you can ask for a reference to this atlas whenever you like 430 | //auto bodies = kinect.getBodySource()->getBodies(); 431 | //auto boneAtlas = ofxKinectForWindows2::Data::Body::getBonesAtlas(); 432 | 433 | //for (auto body : bodies) { 434 | // for (auto bone : boneAtlas) { 435 | // auto firstJointInBone = body.joints[bone.first]; 436 | // auto secondJointInBone = body.joints[bone.second]; 437 | 438 | // //now do something with the joints 439 | // } 440 | //} 441 | } 442 | 443 | // 444 | //-- 445 | } 446 | 447 | 448 | //-------------------------------------------------------------- 449 | void ofApp::draw() { 450 | stringstream ss; 451 | 452 | ofClear(0, 0, 0); 453 | bgCB.draw(0, 0, ofGetWidth(), ofGetHeight()); 454 | 455 | // Color is at 1920x1080 instead of 512x424 so we should fix aspect ratio 456 | float colorHeight = previewWidth * (kinect.getColorSource()->getHeight() / kinect.getColorSource()->getWidth()); 457 | float colorTop = (previewHeight - colorHeight) / 2.0; 458 | 459 | { 460 | // Draw Depth Source 461 | // TODO: brighten depth image. https://github.com/rickbarraza/KinectV2_Lessons/tree/master/3_MakeRawDepthBrigther 462 | // MORE: https://forum.openframeworks.cc/t/kinect-v2-pixel-depth-and-color/18974/4 463 | fboDepth.begin(); // start drawing to off screenbuffer 464 | ofClear(255, 255, 255, 0); 465 | kinect.getDepthSource()->draw(0, 0, DEPTH_WIDTH, DEPTH_HEIGHT); // note that the depth texture is RAW so may appear dark 466 | fboDepth.end(); 467 | //Spout 468 | if (spoutDepth) { 469 | spout.sendTexture(fboDepth.getTextureReference(), depth_StreamName); 470 | } 471 | // NDI 472 | if (ndiDepth && ndiActive && !NDIlock) { 473 | // Set the sender name 474 | strcpy(senderName, depth_StreamName.c_str()); // convert from std string to cstring 475 | sendNDI(ndiSender3, fboDepth, bUsePBO2, DEPTH_WIDTH, DEPTH_HEIGHT, senderName, depth_ndiBuffer, depth_idx); 476 | } 477 | //Draw from FBO 478 | fboDepth.draw(0, 0, previewWidth, previewHeight); 479 | //fboDepth.clear(); 480 | } 481 | 482 | { 483 | // Draw Color Source 484 | fboColor.begin(); // start drawing to off screenbuffer 485 | ofClear(255, 255, 255, 0); 486 | kinect.getColorSource()->draw(0, 0, COLOR_WIDTH, COLOR_HEIGHT); 487 | fboColor.end(); 488 | //Spout 489 | if (spoutColor) { 490 | spout.sendTexture(fboColor.getTextureReference(), color_StreamName); 491 | } 492 | //NDI 493 | if (ndiColor && ndiActive && !NDIlock) { 494 | // Set the sender name 495 | strcpy(senderName, color_StreamName.c_str()); // convert from std string to cstring 496 | sendNDI(ndiSender1, fboColor, bUsePBO1, COLOR_WIDTH, COLOR_HEIGHT, senderName, color_ndiBuffer, color_idx); 497 | } 498 | //Draw from FBO to UI 499 | fboColor.draw(previewWidth, 0 + colorTop, previewWidth, colorHeight); 500 | //fboColor.clear(); 501 | } 502 | 503 | { 504 | // Draw IR Source 505 | kinect.getInfraredSource()->draw(0, previewHeight, DEPTH_WIDTH, DEPTH_HEIGHT); 506 | //kinect.getLongExposureInfraredSource()->draw(0, previewHeight, previewWidth, previewHeight); 507 | } 508 | 509 | { 510 | // Draw B+W cutout of Bodies 511 | fboDepth.begin(); // start drawing to off screenbuffer 512 | ofClear(255, 255, 255, 0); 513 | kinect.getBodyIndexSource()->draw(0, 0, DEPTH_WIDTH, DEPTH_HEIGHT); 514 | fboDepth.end(); 515 | //Spout 516 | if (spoutCutOut) { 517 | spout.sendTexture(fboDepth.getTextureReference(), "kv2_cutout"); 518 | } 519 | // NDI 520 | if (ndiCutOut && ndiActive && !NDIlock){ 521 | // Set the sender name 522 | strcpy(senderName, cutout_StreamName.c_str()); // convert from std string to cstring 523 | sendNDI(ndiSender2, fboDepth, bUsePBO2, DEPTH_WIDTH, DEPTH_HEIGHT, senderName, cutout_ndiBuffer, cutout_idx); 524 | } 525 | //Draw from FBO 526 | fboDepth.draw(previewWidth, previewHeight, previewWidth, previewHeight); 527 | //fboDepth.clear(); 528 | } 529 | 530 | { 531 | // greenscreen/keyed fx from coordmaping 532 | fboDepth.begin(); // start drawing to off screenbuffer 533 | ofClear(255, 255, 255, 0); 534 | foregroundImg.draw(0, 0, DEPTH_WIDTH, DEPTH_HEIGHT); 535 | fboDepth.end(); 536 | //Spout 537 | if (spoutKeyed) { 538 | //ofSetFrameRate(30); 539 | spout.sendTexture(fboDepth.getTextureReference(), "kv2_keyed"); 540 | //Draw from FBO, removed if not checked 541 | ofEnableBlendMode(OF_BLENDMODE_ALPHA); 542 | fboDepth.draw(previewWidth * 2, 0, previewWidth, previewHeight); 543 | } else { 544 | //ofSetFrameRate(60); 545 | ss.str(""); 546 | ss << "Keyed image only shown when" << endl; 547 | ss << "checked in Parameters window" << endl; 548 | ss << "and, a body is being tracked."; 549 | ofDrawBitmapStringHighlight(ss.str(), previewWidth * 2 + 20, previewHeight - (previewHeight / 2 + 60)); 550 | } 551 | // NDI 552 | if (ndiKeyed && ndiActive && !NDIlock) { 553 | // Set the sender name 554 | strcpy(senderName, keyed_StreamName.c_str()); // convert from std string to cstring 555 | sendNDI(ndiSender4, fboDepth, bUsePBO2, DEPTH_WIDTH, DEPTH_HEIGHT, senderName, keyed_ndiBuffer, keyed_idx); 556 | } 557 | } 558 | 559 | { 560 | // Draw bodies joints+bones over 561 | kinect.getBodySource()->drawProjected(previewWidth * 2, previewHeight, previewWidth, previewHeight, ofxKFW2::ProjectionCoordinates::DepthCamera); 562 | } 563 | 564 | ss.str(""); 565 | ss << "fps : " << ofGetFrameRate(); 566 | if (!bHaveAllStreams) ss << endl << "Not all streams detected!"; 567 | ofDrawBitmapStringHighlight(ss.str(), 20, previewHeight * 2 - 25); 568 | 569 | ss.str(""); 570 | ss << "Keyed FX : cpu heavy"; 571 | ofDrawBitmapStringHighlight(ss.str(), previewWidth * 2 + 20, 20); 572 | 573 | ss.str(""); 574 | ss << "Color : HD 1920x1080"; 575 | ofDrawBitmapStringHighlight(ss.str(), previewWidth + 20, 20); 576 | 577 | ss.str(""); 578 | ss << "BnW : body outlines"; 579 | ofDrawBitmapStringHighlight(ss.str(), previewWidth + 20, previewHeight + 20); 580 | 581 | ss.str(""); 582 | ss << "Bodies : coordinates -> OSC" << endl; 583 | ss << "Tracked bodies: " << numBodiesTracked; 584 | ofDrawBitmapStringHighlight(ss.str(), previewWidth * 2 + 20, previewHeight + 20); 585 | 586 | ss.str(""); 587 | ss << "Depthmap : "; 588 | ofDrawBitmapStringHighlight(ss.str(), 20, 20); 589 | 590 | ss.str(""); 591 | ss << "Infrared : "; 592 | ofDrawBitmapStringHighlight(ss.str(), 20, previewHeight + 20); 593 | 594 | if (ndiActive && NDIlock) { 595 | // NDI active has been toggled, and a restart of the app is required to use NDI 596 | ss.str(""); 597 | ss << "The application must be relaunched to allow the NDI fucntions."; 598 | ofDrawBitmapStringHighlight(ss.str(), 20, previewHeight * 2 - 10, ofColor::black, ofColor::red); 599 | } 600 | 601 | gui.draw(); 602 | } 603 | 604 | void ofApp::exit() { 605 | gui.saveToFile(guiFile); 606 | if (ndiPbo1[0]) glDeleteBuffers(2, ndiPbo1); // clean up NDI_1 - HD 607 | if (ndiPbo2[0]) glDeleteBuffers(2, ndiPbo2); // clean up NDI_2 - DepthsSize 608 | oscSendMsg("closed", "/kv2status/"); 609 | } 610 | 611 | //--- OSC send message ----------------------------------------------------------- 612 | // Requires the address be wrapped in forward slashes: eg "/status/" 613 | void ofApp::oscSendMsg(string message, string address) 614 | { 615 | // send OSC message // oscSendMsg("no device","/status/"); 616 | ofxOscMessage m; 617 | m.setAddress(address); 618 | m.addStringArg(message); 619 | oscSender.sendMessage(m); 620 | } 621 | 622 | string ofApp::escape_quotes(const string &before) 623 | // sourced from: http://stackoverflow.com/questions/1162619/fastest-quote-escaping-implementation 624 | { 625 | string after; 626 | after.reserve(before.length() + 4); // TODO: may need to increase reserve... 627 | 628 | for (string::size_type i = 0; i < before.length(); ++i) { 629 | switch (before[i]) { 630 | case '"': 631 | case '\\': 632 | after += '\\'; 633 | // Fall through. 634 | default: 635 | after += before[i]; 636 | } 637 | } 638 | return after; 639 | } 640 | 641 | //-------------------------------------------------------------- 642 | void ofApp::HostFieldChanged() { 643 | cout << "fieldChange" << endl; 644 | oscSender.disableBroadcast(); 645 | oscSender.setup(HostField, oscPort); 646 | oscReceiver.setup(oscPortIn); 647 | cout << "updated" << endl; 648 | oscSendMsg("fieldUpdated", "/kv2status/"); 649 | } 650 | 651 | //-------------------------------------------------------------- 652 | void ofApp::body2JSON(vector bodies, const char * jointNames[]) { 653 | // TODO: create factory 654 | for (auto body : bodies) { 655 | string bdata = ""; // start JSON array build of body data 656 | string newData = ""; // start JSON array build of joints data 657 | for (auto joint : body.joints) { 658 | auto pos = joint.second.getPositionInWorld(); 659 | string name = jointNames[joint.first]; 660 | newData = "\"j\":"; // j for joint ;) 661 | newData = newData + "\"" + name + "\","; 662 | newData = newData + "\"x\":" + to_string(pos.x) + ","; 663 | newData = newData + "\"y\":" + to_string(pos.y) + ","; 664 | newData = newData + "\"z\":" + to_string(pos.z); 665 | newData = "{" + newData + "}"; 666 | // format= {"\j\":\"jointName\",\"x\":0.1,\"y\":0.2,\"z\":0.3 } 667 | if (bdata == "") { // if bdata = "" no comma 668 | bdata = newData; 669 | } 670 | else { 671 | bdata = bdata + "," + newData; 672 | } 673 | } // end inner joints loop 674 | 675 | // format= {"\joint\":\"jointName\",\"x\":0.1,\"y\":0.2,\"z\":0.3 } 676 | // {"j":"SpineBase","x":-0.102359,"y":-0.669035,"z":1.112273} 677 | 678 | // TODO: add below features to non Json OSC 679 | // body.activity ?? contains more.. worth looking into 680 | newData = "\"LH-st8\":" + to_string(body.leftHandState); 681 | newData = "{" + newData + "}"; 682 | // if tracked add ',' and bdata, otherwise bdata = newData. Fixes trailing ',' for non tracked bodies 683 | if (!body.tracked) { 684 | bdata = newData; 685 | } 686 | else { 687 | bdata = newData + "," + bdata; 688 | } 689 | 690 | newData = "\"RH-st8\":" + to_string(body.rightHandState); 691 | newData = "{" + newData + "}"; 692 | bdata = newData + "," + bdata; 693 | 694 | newData = "\"ID\":" + to_string(body.trackingId); 695 | newData = "{" + newData + "}"; 696 | bdata = newData + "," + bdata; 697 | 698 | newData = "\"tracked\":" + to_string(body.tracked); 699 | newData = "{" + newData + "}"; 700 | bdata = newData + "," + bdata; 701 | 702 | // need to escape all " in bdata 703 | bdata = escape_quotes(bdata); 704 | bdata = "[" + bdata + "]"; 705 | bdata = "{\"b" + to_string(body.bodyId) + "\": \"" + bdata + "\"}"; 706 | //cout << bdata << endl; 707 | ofxOscMessage m; 708 | string adrs = "/kV2/body/" + to_string(body.bodyId); 709 | m.setAddress(adrs); 710 | m.addStringArg(bdata); 711 | oscSender.sendMessage(m); 712 | } // end body loop 713 | } 714 | 715 | // NDI 716 | // straight from ofxNDI examples 717 | void ofApp::sendNDI(ofxNDIsender & ndiSender_, ofFbo & sourceFBO_, 718 | bool bUsePBO_, int senderWidth_, int senderHeight_, char senderName_[256], ofPixels ndiBuffer_[], int idx_) 719 | { 720 | if (ndiSender_.GetAsync()) 721 | idx_ = (idx_ + 1) % 2; 722 | 723 | // Extract pixels from the fbo. 724 | if (bUsePBO_) { 725 | // Read fbo using two pbos 726 | // if (&ndiSender == &ndiSender1) {} 727 | ReadFboPixels(sourceFBO_, senderWidth_, senderHeight_, ndiBuffer_[idx_].getPixels()); 728 | 729 | } 730 | else { 731 | // Read fbo directly 732 | sourceFBO_.bind(); 733 | glReadPixels(0, 0, senderWidth_, senderHeight_, GL_RGBA, GL_UNSIGNED_BYTE, ndiBuffer_[idx_].getPixels()); 734 | sourceFBO_.unbind(); 735 | } 736 | 737 | // Send the RGBA ofPixels buffer to NDI 738 | // If you did not set the sender pixel format to RGBA in CreateSender 739 | // you can convert to bgra within SendImage (specify true for bSwapRB) 740 | if (ndiSender_.SendImage(ndiBuffer_[idx_].getPixels(), senderWidth_, senderHeight_)) { 741 | // Send Image was successful 742 | } 743 | } 744 | 745 | // NDI 746 | // Asynchronous Read-back 747 | // adapted from : http://www.songho.ca/opengl/gl_pbo.html 748 | // straight from ofxNDI examples 749 | bool ofApp::ReadFboPixels(ofFbo fbo, unsigned int width, unsigned int height, unsigned char *data) 750 | { 751 | void *pboMemory; 752 | 753 | if (width == COLOR_WIDTH) { 754 | // dealing with HD size video 755 | Pbo1Index = (Pbo1Index + 1) % 2; 756 | NextPbo1Index = (Pbo1Index + 1) % 2; 757 | 758 | // Bind the fbo passed in 759 | fbo.bind(); 760 | 761 | // Set the target framebuffer to read 762 | glReadBuffer(GL_FRONT); 763 | 764 | // Bind the current PBO 765 | glBindBuffer(GL_PIXEL_PACK_BUFFER, ndiPbo1[Pbo1Index]); 766 | 767 | // Read pixels from framebuffer to the current PBO - glReadPixels() should return immediately. 768 | //glReadPixels(0, 0, width, height, GL_BGRA_EXT GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)0); 769 | // Send RGBA 770 | glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)0); 771 | 772 | // Map the previous PBO to process its data by CPU 773 | glBindBuffer(GL_PIXEL_PACK_BUFFER, ndiPbo1[NextPbo1Index]); 774 | } 775 | else { 776 | // dealing with depth size video 777 | Pbo2Index = (Pbo2Index + 1) % 2; 778 | NextPbo2Index = (Pbo2Index + 1) % 2; 779 | fbo.bind(); 780 | glReadBuffer(GL_FRONT); 781 | glBindBuffer(GL_PIXEL_PACK_BUFFER, ndiPbo2[Pbo2Index]); 782 | glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)0); 783 | glBindBuffer(GL_PIXEL_PACK_BUFFER, ndiPbo2[NextPbo2Index]); 784 | } 785 | 786 | 787 | pboMemory = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); 788 | if (pboMemory) { 789 | // Use SSE2 mempcy 790 | ofxNDIutils::CopyImage((unsigned char *)pboMemory, data, width, height, width * 4); 791 | glUnmapBuffer(GL_PIXEL_PACK_BUFFER); 792 | } 793 | else { 794 | glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 795 | fbo.unbind(); 796 | return false; 797 | } 798 | 799 | // Back to conventional pixel operation 800 | glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 801 | fbo.unbind(); 802 | 803 | return true; 804 | } 805 | 806 | //-------------------------------------------------------------- 807 | void ofApp::keyPressed(int key) { 808 | 809 | } 810 | 811 | //-------------------------------------------------------------- 812 | void ofApp::keyReleased(int key) { 813 | // https://forum.openframeworks.cc/t/keypressed-and-getting-the-special-keys/5727 814 | if (key == OF_KEY_RETURN) { 815 | cout << "ENTER" << endl; 816 | HostFieldChanged(); 817 | } 818 | } 819 | 820 | //-------------------------------------------------------------- 821 | void ofApp::gotMessage(ofMessage msg) { 822 | 823 | } 824 | 825 | //-------------------------------------------------------------- 826 | void ofApp::mouseMoved(int x, int y) { 827 | 828 | } 829 | 830 | //-------------------------------------------------------------- 831 | void ofApp::mouseDragged(int x, int y, int button) { 832 | 833 | } 834 | 835 | //-------------------------------------------------------------- 836 | void ofApp::mousePressed(int x, int y, int button) { 837 | 838 | } 839 | 840 | //-------------------------------------------------------------- 841 | void ofApp::mouseReleased(int x, int y, int button) { 842 | 843 | } 844 | 845 | //-------------------------------------------------------------- 846 | void ofApp::windowResized(int w, int h) { 847 | // textField = ofToString(w) + "x" + ofToString(h); 848 | } 849 | 850 | //-------------------------------------------------------------- 851 | void ofApp::dragEvent(ofDragInfo dragInfo) { 852 | 853 | } -------------------------------------------------------------------------------- /src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * kinect2share 5 | * 6 | * Created by Ryan Webber 7 | * http://www.DusXproductions.com 8 | * https://github.com/rwebber 9 | * 10 | * The goal of this project is to make as many Kinect2 features available to creative platforms as possible, 11 | * using open standards including OSC (opensoundcontrol), Spout, and NDI (https://www.newtek.com/ndi/). 12 | * 13 | * Specific care has been given to providing a demo file for use with the Isadora creativity server. 14 | * The demo file provides basic functional examples that Isadora users can build upon. 15 | * http://troikatronix.com/ 16 | * 17 | * MIT License http://en.wikipedia.org/wiki/MIT_License 18 | * 19 | * This project is built using OpenFrameWorks and utilizes a number of amazing addons offered by the community. 20 | * Please read the ReadMe file included in the github reprository, for details. 21 | */ 22 | 23 | #include "ofMain.h" 24 | #include "ofxKinectForWindows2.h" 25 | #include "ofxOsc.h" 26 | #include "ofxGui.h" 27 | #include "ofxInputField.h" 28 | #include "ofxSpout2.h" 29 | #include "ofxNDI.h" 30 | 31 | // ** added from NDI sender example ** 32 | // BGRA definition should be in glew.h 33 | // but define it here just in case it is not 34 | #ifndef GL_BGRA_EXT 35 | #define GL_BGRA_EXT 0x80E1 36 | #endif 37 | // ^^ added from NDI sender example ^^ 38 | 39 | class ofApp : public ofBaseApp { 40 | 41 | public: 42 | void setup(); 43 | void update(); 44 | void draw(); 45 | void exit(); // added 46 | 47 | void keyPressed(int key); 48 | void keyReleased(int key); 49 | void mouseMoved(int x, int y); 50 | void mouseDragged(int x, int y, int button); 51 | void mousePressed(int x, int y, int button); 52 | void mouseReleased(int x, int y, int button); 53 | void windowResized(int w, int h); 54 | void dragEvent(ofDragInfo dragInfo); 55 | void gotMessage(ofMessage msg); 56 | 57 | ofxKFW2::Device kinect; 58 | ICoordinateMapper* coordinateMapper; 59 | 60 | // void HostFieldChanged(string & HostField); 61 | void HostFieldChanged(); 62 | 63 | // BG 64 | ofImage bgCB; // background checkerboard 65 | 66 | // offscreen buffers (frame buffer object) 67 | ofFbo fboDepth; // draw to for spout, setup at Kinect native 512x 68 | ofFbo fboColor; // draw to for spout, setup at 1080x 69 | 70 | // Spout obj 71 | ofxSpout2 spout; 72 | 73 | 74 | // *** added from NDI sender example *** 75 | // NDI definitions 76 | bool NDIlock; // used to block NDI functions incase the ON/OFF param is activated. 77 | ofxNDIsender ndiSender1; // NDI sender object, HD format (color_) 78 | ofxNDIsender ndiSender2; // Depth-Image format (cutout_) 79 | ofxNDIsender ndiSender3; // INFRARED 80 | ofxNDIsender ndiSender4; // KEYED 81 | string color_StreamName; 82 | string cutout_StreamName; 83 | string depth_StreamName; 84 | string keyed_StreamName; 85 | string infrared_StreamName; // TODO add this.. currently not setup 86 | char senderName[256]; // for conversions... char[] required for ndiSender functions 87 | 88 | // NOTE using W+H defined already 89 | //unsigned int senderWidth; // Width of the sender output 90 | //unsigned int senderHeight; // Height of the sender output 91 | 92 | // ofFbo ndiFbo; // NOTE using fbos created for spout 93 | 94 | // NOTE: need a Buffer array and a index used for async for EACH NDIstream being created 95 | ofPixels color_ndiBuffer[2]; // Two pixel buffers for async sending 96 | ofPixels cutout_ndiBuffer[2]; // Two pixel buffers for async sending 97 | ofPixels depth_ndiBuffer[2]; // Two pixel buffers for async sending 98 | ofPixels keyed_ndiBuffer[2]; // Two pixel buffers for async sending 99 | //ofPixels infrared_ndiBuffer[2]; // Two pixel buffers for async sending 100 | int color_idx; // Index used for async buffer swapping ??? 101 | int cutout_idx; 102 | int depth_idx; 103 | int keyed_idx; 104 | // int infrared_idx; 105 | 106 | // PBO and control vars for ndiSender1 HD format 107 | GLuint ndiPbo1[2]; 108 | int Pbo1Index; 109 | int NextPbo1Index; 110 | bool bUsePBO1; 111 | 112 | // PBO and control vars for ndiSender2+ DepthImage sized 113 | GLuint ndiPbo2[2]; 114 | int Pbo2Index; 115 | int NextPbo2Index; 116 | bool bUsePBO2; 117 | 118 | 119 | bool ReadFboPixels(ofFbo fbo, unsigned int width, unsigned int height, unsigned char *data); 120 | // ^^^ added from NDI sender example ^^^ 121 | 122 | 123 | // OSC 124 | ofxOscSender oscSender; 125 | ofxOscReceiver oscReceiver; 126 | 127 | // custom functions DX 128 | void oscSendMsg(std::string message, std::string address); 129 | 130 | 131 | // GUI 132 | ofxPanel gui; 133 | 134 | ofxGuiGroup OSCgroup; 135 | ofxToggle jsonGrouped; 136 | // ofxInputField 137 | ofxIntField oscPort; // Output 138 | ofxIntField oscPortIn; 139 | ofxTextField HostField; 140 | 141 | ofxGuiGroup SPOUTgroup; 142 | ofxToggle spoutCutOut; 143 | ofxToggle spoutColor; 144 | ofxToggle spoutKeyed; 145 | ofxToggle spoutDepth; 146 | 147 | ofxGuiGroup NDIgroup; 148 | ofxToggle ndiActive; 149 | ofxToggle ndiCutOut; 150 | ofxToggle ndiColor; 151 | ofxToggle ndiKeyed; 152 | ofxToggle ndiDepth; 153 | 154 | 155 | // added for coordmapping 156 | ofImage bodyIndexImg, foregroundImg; 157 | vector colorCoords; 158 | int numBodiesTracked; 159 | bool bHaveAllStreams; 160 | 161 | // helper Functions 162 | string escape_quotes(const string & before); 163 | void body2JSON(vector bodies, const char * jointNames[]); 164 | void sendNDI(ofxNDIsender & ndiSender, ofFbo & sourceFBO, bool bUsePBO, int senderWidth, int senderHeight, char senderName[256], ofPixels ndiBuffer[], int idx); 165 | }; --------------------------------------------------------------------------------