├── .gitattributes ├── LICENSE ├── README.md ├── example ├── Kinect64.props ├── addons.make ├── bin │ └── data │ │ ├── .gitkeep │ │ └── _settings │ │ ├── kinect2dscene10.xml │ │ ├── kinect3dscene.xml │ │ ├── kinectcamera.xml │ │ └── triangulator10.xml └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── exampleGestures ├── Kinect64.props ├── addons.make ├── bin │ ├── Kinect20.VisualGestureBuilder.dll │ ├── data │ │ └── gestures.gbd │ └── vgbtechs │ │ ├── AdaBoostTech.dll │ │ └── RFRProgressTech.dll └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── exampleTcpReceiver ├── Kinect64.props ├── addons.make ├── bin │ └── data │ │ └── .gitkeep └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── exampleTcpSender ├── Kinect64.props ├── addons.make ├── bin │ └── data │ │ ├── .gitkeep │ │ ├── _settings │ │ ├── kinect3dscene.xml │ │ ├── kinectcamera.xml │ │ └── tcp_sender.xml │ │ └── tcp.txt └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── exampleTriangulator ├── Kinect64.props ├── addons.make ├── bin │ └── data │ │ ├── .gitkeep │ │ ├── _settings │ │ ├── kinect2dscene10.xml │ │ ├── kinect3dscene.xml │ │ ├── kinectcamera.xml │ │ └── triangulator10.xml │ │ └── _shaders │ │ ├── fullpointcloud.frag │ │ └── fullpointcloud.vert └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── images ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.gif └── pm.jpg ├── libs ├── Kinect20.VisualGestureBuilder.dll ├── copy_these_files_in_bin_for_gesture_detection.txt └── vgbtechs │ ├── AdaBoostTech.dll │ └── RFRProgressTech.dll └── src ├── core ├── ncKinectCamera.cpp ├── ncKinectCamera.h ├── ncKinectEventDispatcher.cpp ├── ncKinectEventDispatcher.h ├── ncKinectUser.h ├── ncKinectUserManager.cpp ├── ncKinectUserManager.h ├── ncKinectv2Core.cpp └── ncKinectv2Core.h └── utils ├── ncKinect2dScene.cpp ├── ncKinect2dScene.h ├── ncKinect3dScene.cpp ├── ncKinect3dScene.h ├── ncKinectAreaManager.cpp ├── ncKinectAreaManager.h ├── ncKinectPCTriangulator.cpp ├── ncKinectPCTriangulator.h ├── ncKinectSeDeserializer.h ├── ncKinectv2GestureDetector.cpp ├── ncKinectv2GestureDetector.h ├── ofxInfiniteCanvas.cpp ├── ofxInfiniteCanvas.h ├── ofxMeshUtils.cpp ├── ofxMeshUtils.h ├── ofxTimer.cpp ├── ofxTimer.h ├── socketCS.cpp ├── socketCS.h ├── tcpClient ├── ncKinectSender.cpp └── ncKinectSender.h └── tcpServer ├── NCKinectV2Objects.h ├── ncKinectReceiver.cpp └── ncKinectReceiver.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 nøcomputer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ofxNCKinect 2 | =========== 3 | 4 | KINECT IS ALIVE! 5 | 6 | After we heard the news Microsoft is reviving the Kinect we decided to upload our [openFrameworks](https://openframeworks.cc/) KinectV2 library. 7 | 8 | This code is a collection of stuff we have been using for the last few years. Speed comes first, so we tried to create code that let's us choose what features we would need for a project (color vs no color, only 2d vs 3d tracking, etc...). It includes stuff like user management, 2d and 3d scene management, sending data over the network, pointcloud triangulation, gesture detection, area management, etc... 9 | 10 | It is no way an official API, so use it at your own risk. 11 | 12 | Installation 13 | ------------ 14 | This code only works on Windows 10/64 bit systems. 15 | 16 | 1) Install openFrameworks: 17 | 18 | * [OF 0.10.1](https://openframeworks.cc/download/) use the master branch of this repo 19 | * [OF 0.9.8](https://openframeworks.cc/download/older/) use the of_0_9_8 branch of this repo 20 | 21 | 2) Required addons: 22 | 23 | * ofxGui 24 | * ofxOpenCV 25 | 26 | 3) Install the KinectV2 sdk: 27 | 28 | * https://www.microsoft.com/en-us/download/details.aspx?id=44561 29 | 30 | To compile the examples use the openFrameworks project generator and the Kinect64.props file to set the paths to the Kinect SDK. Build for 64 bit. 31 | 32 | 33 | 34 | Use the Property Manager in Visual Studio to add the Kinect64.props file. 35 | 36 | Standing on the shoulders of giants 37 | ----------------------------------- 38 | Love to the [openFrameworks](https://openframeworks.cc/) community! 39 | 40 | In this repo we have used code from: 41 | 42 | * [Roy Macdonald - ofxInfiniteCanvas](https://github.com/roymacdonald/ofxInfiniteCanvas) 43 | * [Zach Lieberman- ofxMeshUtils](https://github.com/ofZach/ofxMeshUtils) 44 | * [Vanderlin - ofxTimer](https://github.com/vanderlin/ofxTimer) 45 | * [Rene Nyffenegger- Socket](https://github.com/ReneNyffenegger/Socket.cpp) 46 | 47 | 48 | EXAMPLES 49 | ======== 50 | 51 | 52 | Basic Example 53 | ------------- 54 | ![example](https://raw.githubusercontent.com/wearenocomputer/ofxncKinect/master/images/2.jpg) 55 | This is a basic example combining color, 2d and 3d Kinect data. 56 | 57 | 58 | Gestures Example 59 | ---------------- 60 | ![example](https://raw.githubusercontent.com/wearenocomputer/ofxncKinect/master/images/4.gif) 61 | Using custom trained gestures. 62 | This example loads in a gbd file, in this case trained for the famous Crane Karate Kid Kick, and shows how to handle incoming data. 63 | 64 | When using gestures make sure to: 65 | 1. #define `GESTURES` in the file `ncKinectv2Core.h` 66 | 2. copy the `Kinect20.VisualGestureBuilder.dll` file in the bin folder (see lib folder) 67 | 68 | 69 | TCP Sender/Receiver Example 70 | --------------------------- 71 | ![example](https://raw.githubusercontent.com/wearenocomputer/ofxncKinect/master/images/3.jpg) 72 | You can use multiple senders to send Kinect data over the network to the Kinect Receiver. 73 | 74 | We support sending: 75 | 76 | * Pointcloud 77 | * Floorplane 78 | * Skeleton data 79 | 80 | 81 | Triangulator Example 82 | -------------------- 83 | ![example](https://raw.githubusercontent.com/wearenocomputer/ofxncKinect/master/images/1.jpg) 84 | Example on how to create a mesh from user point cloud data in real time. 85 | -------------------------------------------------------------------------------- /example/Kinect64.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x64;%(AdditionalLibraryDirectories) 9 | 10 | 11 | 12 | 13 | Kinect20.lib;Kinect20.VisualGestureBuilder.lib;%(AdditionalDependencies) 14 | 15 | 16 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\inc;%(AdditionalIncludeDirectories) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /example/addons.make: -------------------------------------------------------------------------------- 1 | ofxGui 2 | ofxNCKinect 3 | ofxOpenCv 4 | -------------------------------------------------------------------------------- /example/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/example/bin/data/.gitkeep -------------------------------------------------------------------------------- /example/bin/data/_settings/kinect2dscene10.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 1 5 | 1 6 | 311 7 | 0 8 | 0 9 | 0 10 | 11 | 12 | -------------------------------------------------------------------------------- /example/bin/data/_settings/kinect3dscene.xml: -------------------------------------------------------------------------------- 1 | 2 | 1 3 | 1 4 | 1 5 | 1 6 | 1 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/bin/data/_settings/kinectcamera.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 1 8 | 1 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/bin/data/_settings/triangulator10.xml: -------------------------------------------------------------------------------- 1 | 2 | 1 3 | 0 4 | 1 5 | 0.5 6 | 0 7 | 1 8 | 1 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetFrameRate(30); 6 | ofBackground(0); 7 | kinectcore.setup(true); 8 | kinectcamera.setup(); 9 | kinectusermanager.setup(kinectcore.getUsers(), kinectcamera); 10 | kinectscene.setup(kinectcore, kinectusermanager, kinectcamera); 11 | 12 | ofAddListener(ncKinectEventDispatcher::NCEVENTDISPATCHER.NEW_USER, this, &ofApp::newUser); 13 | ofAddListener(ncKinectEventDispatcher::NCEVENTDISPATCHER.LOST_USER, this, &ofApp::lostUser); 14 | 15 | } 16 | 17 | //-------------------------------------------------------------- 18 | void ofApp::update(){ 19 | 20 | kinectcore.update(true,true,true); 21 | kinectcamera.update(kinectcore.getFloorPlane()); 22 | kinectusermanager.update(); 23 | 24 | bodyIndexImg.setFromPixels(kinectcore.getBodyIndexPixels()); 25 | 26 | bodyIndexImgColor.setFromPixels(kinectcore.getBodyIndexPixelsColored()); 27 | 28 | depthmapimage.setFromPixels(kinectcore.getDepthMap2D()); 29 | 30 | } 31 | 32 | //-------------------------------------------------------------- 33 | void ofApp::draw(){ 34 | 35 | depthmapimage.draw(0, 0); 36 | bodyIndexImg.draw(512, 0); 37 | bodyIndexImgColor.draw(512*2, 0); 38 | 39 | kinectscene.draw(); 40 | kinectscene.drawGUI(); 41 | 42 | ofDrawBitmapStringHighlight(ofToString(ofGetFrameRate()), 10, 10); 43 | } 44 | 45 | //-------------------------------------------------------------- 46 | void ofApp::keyPressed(int key){ 47 | if (key == 'f') { 48 | ofToggleFullscreen(); 49 | } 50 | } 51 | 52 | 53 | //-------------------------------------------------------------- 54 | void ofApp::newUser(NCGenericEventArg & arg) { 55 | cout << arg.userid << endl; 56 | } 57 | 58 | //-------------------------------------------------------------- 59 | void ofApp::lostUser(NCGenericEventArg & arg) { 60 | cout << arg.userid << endl; 61 | } -------------------------------------------------------------------------------- /example/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ncKinectv2Core.h" 5 | #include "ncKinectCamera.h" 6 | #include "ncKinectUserManager.h" 7 | #include "ncKinect3dScene.h" 8 | 9 | class ofApp : public ofBaseApp{ 10 | 11 | public: 12 | void setup(); 13 | void update(); 14 | void draw(); 15 | 16 | void keyPressed(int key); 17 | 18 | ncKinectv2Core kinectcore; 19 | nCKinectCamera kinectcamera; 20 | ncKinectUserManager kinectusermanager; 21 | ncKinect3dScene kinectscene; 22 | 23 | ofImage bodyIndexImg; 24 | ofImage bodyIndexImgColor; 25 | 26 | ofImage depthmapimage; 27 | 28 | ofImage colorimage; 29 | 30 | void newUser(NCGenericEventArg &arg); 31 | void lostUser(NCGenericEventArg &arg); 32 | 33 | }; 34 | -------------------------------------------------------------------------------- /exampleGestures/Kinect64.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x64;%(AdditionalLibraryDirectories) 9 | 10 | 11 | 12 | 13 | Kinect20.lib;Kinect20.VisualGestureBuilder.lib;%(AdditionalDependencies) 14 | 15 | 16 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\inc;%(AdditionalIncludeDirectories) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /exampleGestures/addons.make: -------------------------------------------------------------------------------- 1 | ofxGui 2 | ofxNCKinect 3 | ofxOpenCv 4 | -------------------------------------------------------------------------------- /exampleGestures/bin/Kinect20.VisualGestureBuilder.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/exampleGestures/bin/Kinect20.VisualGestureBuilder.dll -------------------------------------------------------------------------------- /exampleGestures/bin/data/gestures.gbd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/exampleGestures/bin/data/gestures.gbd -------------------------------------------------------------------------------- /exampleGestures/bin/vgbtechs/AdaBoostTech.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/exampleGestures/bin/vgbtechs/AdaBoostTech.dll -------------------------------------------------------------------------------- /exampleGestures/bin/vgbtechs/RFRProgressTech.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/exampleGestures/bin/vgbtechs/RFRProgressTech.dll -------------------------------------------------------------------------------- /exampleGestures/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(800,424,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /exampleGestures/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | 6 | ofBackground(0); 7 | kinect.setup("gestures.gbd", false); 8 | kinectusermanager.setup(kinect.getUsers()); 9 | kinect2dscene.setup(kinectusermanager.getUsers()); 10 | 11 | ofAddListener(ncKinectEventDispatcher::NCEVENTDISPATCHER.DISCRETE_GESTURE, this, &ofApp::discreteTracked); 12 | ofAddListener(ncKinectEventDispatcher::NCEVENTDISPATCHER.NEW_USER, this, &ofApp::newUser); 13 | ofAddListener(ncKinectEventDispatcher::NCEVENTDISPATCHER.LOST_USER, this, &ofApp::lostUser); 14 | } 15 | 16 | //-------------------------------------------------------------- 17 | void ofApp::update(){ 18 | kinect.update(); 19 | kinectusermanager.update(); 20 | 21 | if (kk.size() == 30) { 22 | kk.erase(kk.begin()); 23 | } 24 | 25 | } 26 | 27 | //-------------------------------------------------------------- 28 | void ofApp::draw(){ 29 | kinect2dscene.drawDepthMap2d(kinect.getDepthMap2D()); 30 | 31 | float startx = 540; 32 | ofSetLineWidth(2); 33 | ofNoFill(); 34 | 35 | ofDrawRectangle(startx, 0, 210, 210); 36 | ofFill(); 37 | for (size_t i = 0; i < kk.size(); i++) { 38 | ofDrawLine(ofPoint((i * 7) + startx, 210), ofPoint((i * 7) + startx, 210 - (kk[i] * 210))); 39 | } 40 | ofSetColor(ofColor::red); 41 | ofDrawLine(ofPoint(startx, 210 - (0.4 * 210)), ofPoint(startx + 210, 210 - (0.4 * 210))); 42 | ofSetColor(255); 43 | ofSetLineWidth(1); 44 | ofDrawBitmapString("Crane Kick", startx, 230); 45 | 46 | } 47 | 48 | //-------------------------------------------------------------- 49 | void ofApp::keyPressed(int key){ 50 | 51 | } 52 | 53 | //-------------------------------------------------------------- 54 | void ofApp::discreteTracked(NCGenericEventArg & arg) { 55 | 56 | if (arg.message == "KarateKid") { 57 | kk.push_back(arg.value); 58 | 59 | } 60 | 61 | 62 | } 63 | 64 | //-------------------------------------------------------------- 65 | void ofApp::newUser(NCGenericEventArg & arg) { 66 | ncKinectUser * user = kinectusermanager.getUserById(arg.userid); 67 | kinect.turnOffGestureDectors(); 68 | kinect.turnOnGestureDetectorForUser(user->id, user->kinectid); 69 | } 70 | 71 | //-------------------------------------------------------------- 72 | void ofApp::lostUser(NCGenericEventArg & arg) { 73 | kinect.turnOffGestureDectors(); 74 | } 75 | -------------------------------------------------------------------------------- /exampleGestures/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ncKinectv2Core.h" 5 | #include "ncKinectUserManager.h" 6 | #include "ncKinect2dScene.h" 7 | class ofApp : public ofBaseApp{ 8 | 9 | public: 10 | void setup(); 11 | void update(); 12 | void draw(); 13 | 14 | void keyPressed(int key); 15 | 16 | void discreteTracked(NCGenericEventArg &arg); 17 | ncKinectv2Core kinect; 18 | ncKinectUserManager kinectusermanager; 19 | ncKinect2dScene kinect2dscene; 20 | 21 | void newUser(NCGenericEventArg &arg); 22 | void lostUser(NCGenericEventArg &arg); 23 | 24 | vector kk; 25 | }; 26 | -------------------------------------------------------------------------------- /exampleTcpReceiver/Kinect64.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x64;%(AdditionalLibraryDirectories) 9 | 10 | 11 | 12 | 13 | Kinect20.lib;Kinect20.VisualGestureBuilder.lib;%(AdditionalDependencies) 14 | 15 | 16 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\inc;%(AdditionalIncludeDirectories) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /exampleTcpReceiver/addons.make: -------------------------------------------------------------------------------- 1 | ofxGui 2 | ofxNCKinect 3 | ofxOpenCv 4 | -------------------------------------------------------------------------------- /exampleTcpReceiver/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/exampleTcpReceiver/bin/data/.gitkeep -------------------------------------------------------------------------------- /exampleTcpReceiver/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /exampleTcpReceiver/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetFrameRate(30); 6 | receiver_one.setup(11999,1); 7 | receiver_two.setup(11998,2); 8 | ofSetWindowTitle("RECEIVER"); 9 | 10 | cam.setDistance(1); 11 | cam.setNearClip(0.01); 12 | } 13 | 14 | //-------------------------------------------------------------- 15 | void ofApp::update(){ 16 | receiver_one.update(); 17 | receiver_two.update(); 18 | } 19 | 20 | //-------------------------------------------------------------- 21 | void ofApp::draw(){ 22 | cam.begin(); 23 | receiver_one.draw(); 24 | receiver_two.draw(); 25 | cam.end(); 26 | 27 | 28 | receiver_one.drawGUI(); 29 | receiver_two.drawGUI(); 30 | 31 | ofDrawBitmapStringHighlight(ofToString(ofGetFrameRate()), 10, 10); 32 | } 33 | 34 | //-------------------------------------------------------------- 35 | void ofApp::keyPressed(int key){ 36 | if (key == 'f') { 37 | ofToggleFullscreen(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /exampleTcpReceiver/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ncKinectReceiver.h" 5 | 6 | class ofApp : public ofBaseApp{ 7 | 8 | public: 9 | void setup(); 10 | void update(); 11 | void draw(); 12 | 13 | void keyPressed(int key); 14 | 15 | 16 | ncKinectReceiver receiver_one; 17 | ncKinectReceiver receiver_two; 18 | 19 | ofEasyCam cam; 20 | 21 | }; 22 | -------------------------------------------------------------------------------- /exampleTcpSender/Kinect64.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x64;%(AdditionalLibraryDirectories) 9 | 10 | 11 | 12 | 13 | Kinect20.lib;Kinect20.VisualGestureBuilder.lib;%(AdditionalDependencies) 14 | 15 | 16 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\inc;%(AdditionalIncludeDirectories) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /exampleTcpSender/addons.make: -------------------------------------------------------------------------------- 1 | ofxGui 2 | ofxNCKinect 3 | ofxOpenCv 4 | -------------------------------------------------------------------------------- /exampleTcpSender/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/exampleTcpSender/bin/data/.gitkeep -------------------------------------------------------------------------------- /exampleTcpSender/bin/data/_settings/kinect3dscene.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /exampleTcpSender/bin/data/_settings/kinectcamera.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 1 9 | 1 10 | 11 | -------------------------------------------------------------------------------- /exampleTcpSender/bin/data/_settings/tcp_sender.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 4 | 1 5 | 6 | -------------------------------------------------------------------------------- /exampleTcpSender/bin/data/tcp.txt: -------------------------------------------------------------------------------- 1 | 127.0.0.1 2 | 11999 -------------------------------------------------------------------------------- /exampleTcpSender/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /exampleTcpSender/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetFrameRate(30); 6 | 7 | //LOAD TCP SETTINGS 8 | //OSC 9 | string host; 10 | int port; 11 | ofFile myfile("tcp.txt"); 12 | ofBuffer mybuffer(myfile); 13 | 14 | int count = 0; 15 | for (auto &line : mybuffer.getLines()) { 16 | if (line != "") { 17 | 18 | if (count == 0) { 19 | host = line; 20 | } 21 | 22 | if (count == 1) { 23 | port = ofToInt(line); 24 | } 25 | count++; 26 | } 27 | } 28 | 29 | sender.setup(1,host,port); 30 | 31 | kinectcore.setup(); 32 | kinectcamera.setup(); 33 | kinectusermanager.setup(kinectcore.getUsers(), kinectcamera); 34 | kinectscene.setup(kinectcore, kinectusermanager, kinectcamera); 35 | 36 | 37 | ofSetWindowTitle("SENDER"); 38 | } 39 | 40 | //-------------------------------------------------------------- 41 | void ofApp::update(){ 42 | 43 | kinectcore.update(false, false, false); 44 | kinectcamera.update(kinectcore.getFloorPlane()); 45 | kinectusermanager.update(); 46 | 47 | ncKinectSeDeSerObject kinectobject; 48 | kinectobject.floorplane = kinectcore.getFloorPlane(); 49 | 50 | //use this to send the pointcloud over TCP 51 | kinectobject.vertices.clear(); 52 | if (sender.bsendpointcloud) { 53 | kinectobject.vertices = kinectcore.getPointCloud3D().getVertices(); 54 | } 55 | kinectobject.users.clear(); 56 | vector users; 57 | for (size_t i = 0; i < kinectusermanager.getUsers().size(); i++) { 58 | users.push_back(*kinectusermanager.getUsers()[i]); 59 | } 60 | kinectobject.users = users; 61 | ncKinectSeDeserializer tcpobject; 62 | ofBuffer data = tcpobject.serialize(kinectobject); 63 | 64 | sender.setBuffer(data); 65 | } 66 | 67 | //-------------------------------------------------------------- 68 | void ofApp::draw(){ 69 | 70 | kinectscene.draw(); 71 | kinectscene.drawGUI(); 72 | 73 | sender.drawGUI(); 74 | 75 | 76 | ofDrawBitmapStringHighlight(ofToString(ofGetFrameRate()), 10, 10); 77 | } 78 | 79 | void ofApp::exit() { 80 | sender.stop(); 81 | } 82 | 83 | //-------------------------------------------------------------- 84 | void ofApp::keyPressed(int key){ 85 | if (key == 'f') { 86 | ofToggleFullscreen(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /exampleTcpSender/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ncKinectv2Core.h" 5 | #include "ncKinectCamera.h" 6 | #include "ncKinectUserManager.h" 7 | #include "ncKinect3dScene.h" 8 | #include "ncKinectSeDeserializer.h" 9 | #include "ncKinectSender.h" 10 | 11 | class ofApp : public ofBaseApp{ 12 | 13 | public: 14 | void setup(); 15 | void update(); 16 | void draw(); 17 | void exit(); 18 | 19 | 20 | 21 | void keyPressed(int key); 22 | 23 | ncKinectSender sender; 24 | 25 | ncKinectv2Core kinectcore; 26 | nCKinectCamera kinectcamera; 27 | ncKinectUserManager kinectusermanager; 28 | ncKinect3dScene kinectscene; 29 | 30 | ncKinectSeDeserializer serializer; 31 | }; 32 | -------------------------------------------------------------------------------- /exampleTriangulator/Kinect64.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x64;%(AdditionalLibraryDirectories) 9 | 10 | 11 | 12 | 13 | Kinect20.lib;Kinect20.VisualGestureBuilder.lib;%(AdditionalDependencies) 14 | 15 | 16 | C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\inc;%(AdditionalIncludeDirectories) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /exampleTriangulator/addons.make: -------------------------------------------------------------------------------- 1 | ofxGui 2 | ofxNCKinect 3 | ofxOpenCv 4 | -------------------------------------------------------------------------------- /exampleTriangulator/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/exampleTriangulator/bin/data/.gitkeep -------------------------------------------------------------------------------- /exampleTriangulator/bin/data/_settings/kinect2dscene10.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0.945502 5 | 1 6 | 311 7 | 0 8 | 0 9 | 0 10 | 11 | 12 | -------------------------------------------------------------------------------- /exampleTriangulator/bin/data/_settings/kinect3dscene.xml: -------------------------------------------------------------------------------- 1 | 2 | 1 3 | 0 4 | 1 5 | 0 6 | 1 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 14 | 15 | -------------------------------------------------------------------------------- /exampleTriangulator/bin/data/_settings/kinectcamera.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 1 8 | 1 9 | 10 | 11 | -------------------------------------------------------------------------------- /exampleTriangulator/bin/data/_settings/triangulator10.xml: -------------------------------------------------------------------------------- 1 | 2 | 1 3 | 0 4 | 1 5 | 0 6 | 0 7 | 6.715 8 | 1 9 | 10 | 11 | -------------------------------------------------------------------------------- /exampleTriangulator/bin/data/_shaders/fullpointcloud.frag: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | uniform sampler2DRect texture; 4 | 5 | void main() { 6 | vec2 st = gl_TexCoord[0].st; 7 | vec4 mycolor = texture2DRect(texture,st); 8 | gl_FragColor = mycolor; 9 | } -------------------------------------------------------------------------------- /exampleTriangulator/bin/data/_shaders/fullpointcloud.vert: -------------------------------------------------------------------------------- 1 | #version 120 2 | void main() { 3 | gl_TexCoord[0] = gl_MultiTexCoord0; 4 | gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; 5 | gl_FrontColor = gl_Color; 6 | } 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /exampleTriangulator/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /exampleTriangulator/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetFrameRate(30); 6 | ofBackground(0); 7 | kinectcore.setup(true); 8 | kinectcamera.setup(); 9 | kinectusermanager.setup(kinectcore.getUsers(), kinectcamera); 10 | kinecttriangulator.setup(kinectusermanager.getUsers(), kinectcore, kinectcamera, kinectcore.getBodyIndexPixels(), kinectcore.getPointCloud3D(), 10); 11 | } 12 | 13 | //-------------------------------------------------------------- 14 | void ofApp::update(){ 15 | kinectcore.update(true,false,false); 16 | kinectcamera.update(kinectcore.getFloorPlane()); 17 | kinectusermanager.update(); 18 | kinecttriangulator.update(); 19 | } 20 | 21 | //-------------------------------------------------------------- 22 | void ofApp::draw(){ 23 | 24 | kinecttriangulator.draw(); 25 | kinecttriangulator.drawGUI(); 26 | kinectcamera.drawGUI(); 27 | ofDrawBitmapStringHighlight(ofToString(ofGetFrameRate()), 10, 10); 28 | 29 | } 30 | 31 | //-------------------------------------------------------------- 32 | void ofApp::keyPressed(int key){ 33 | if (key == 'f') { 34 | ofToggleFullscreen(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /exampleTriangulator/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ncKinectv2Core.h" 5 | #include "ncKinectCamera.h" 6 | #include "ncKinectUserManager.h" 7 | #include "ncKinectPCTriangulator.h" 8 | 9 | 10 | class ofApp : public ofBaseApp{ 11 | 12 | public: 13 | void setup(); 14 | void update(); 15 | void draw(); 16 | 17 | void keyPressed(int key); 18 | 19 | ncKinectv2Core kinectcore; 20 | nCKinectCamera kinectcamera; 21 | ncKinectUserManager kinectusermanager; 22 | ncKinectPCTriangulator kinecttriangulator; 23 | }; 24 | -------------------------------------------------------------------------------- /images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/images/1.jpg -------------------------------------------------------------------------------- /images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/images/2.jpg -------------------------------------------------------------------------------- /images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/images/3.jpg -------------------------------------------------------------------------------- /images/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/images/4.gif -------------------------------------------------------------------------------- /images/pm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/images/pm.jpg -------------------------------------------------------------------------------- /libs/Kinect20.VisualGestureBuilder.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/libs/Kinect20.VisualGestureBuilder.dll -------------------------------------------------------------------------------- /libs/copy_these_files_in_bin_for_gesture_detection.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/libs/copy_these_files_in_bin_for_gesture_detection.txt -------------------------------------------------------------------------------- /libs/vgbtechs/AdaBoostTech.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/libs/vgbtechs/AdaBoostTech.dll -------------------------------------------------------------------------------- /libs/vgbtechs/RFRProgressTech.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/libs/vgbtechs/RFRProgressTech.dll -------------------------------------------------------------------------------- /src/core/ncKinectCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectCamera.h" 2 | 3 | void nCKinectCamera::setupGUI() { 4 | gui.setup("Kinect Camera", "_settings/kinectcamera.xml"); 5 | gui.add(kinectcamxposin3dworld.set("x pos in 3d world", 0, -5, 5)); 6 | gui.add(kinectcamyposin3dworld.set("y pos in 3d world", 0, -5, 5)); 7 | gui.add(kinectcamzposin3dworld.set("z pos in 3d world", 0, -5, 5)); 8 | gui.add(kinectyawin3dworld.set("yaw in 3d world", 0, -180, 180)); 9 | gui.add(freezeFloorplane.set("freeze floorplane", false)); 10 | gui.add(drawCamera.set("draw camera", true)); 11 | gui.add(mapKinectto3DWorld.set("map Kinect to 3d world", true)); 12 | 13 | gui.loadFromFile("_settings/kinectcamera.xml"); 14 | 15 | gui.setPosition(10, 470); 16 | } 17 | 18 | nCKinectCamera ::~nCKinectCamera(){ 19 | 20 | } 21 | 22 | nCKinectCamera::nCKinectCamera() { 23 | 24 | } 25 | 26 | void nCKinectCamera::setup() { 27 | setupGUI(); 28 | model.set(0.3, 0.1, 0.1); 29 | loadcounter = 0; 30 | freezefloorplanecounter = 0; 31 | floorplaneshouldbein = false; 32 | } 33 | 34 | void nCKinectCamera::update(ofVec4f _floorplane){ 35 | 36 | //BUG IN OFXGUIPLUS LOADING VALUES 37 | //RELOAD IT HERE THREE TIMES AS FAST AS POSSIBLE 38 | if (loadcounter < 3) { 39 | if (ofGetFrameNum() % 1 == 0) { 40 | loadcounter++; 41 | gui.loadFromFile("_settings/kinectcamera.xml"); 42 | } 43 | } 44 | 45 | 46 | //EVEN WHEN FREEZE FLOORPLANE IS ON 47 | //GIVE THE KINECT 2 FRAMES TO FIND THE FLOORPLANE 48 | 49 | if (ofGetFrameNum() % 120 == 0) { 50 | 51 | freezefloorplanecounter++; 52 | 53 | if (freezefloorplanecounter == 2) { 54 | floorplaneshouldbein = true; 55 | } 56 | 57 | } 58 | 59 | if (floorplaneshouldbein) { 60 | if (!freezeFloorplane) { 61 | floorplane = _floorplane; 62 | } 63 | } 64 | else { 65 | floorplane = _floorplane; 66 | } 67 | 68 | 69 | //http://blog.hackandi.com/inst/blog/2014/03/18/convert-kinect-cameraspace-to-worldspace-relative-to-floor/ 70 | ofVec3f up = ofVec3f(floorplane.x, floorplane.y, floorplane.z); 71 | ofVec3f forward = up.getCrossed(ofVec3f(1, 0, 0)); 72 | forward.normalize(); 73 | ofVec3f right = up.getCrossed(forward); 74 | //ofVec3f origin = floorplane.w * up; 75 | 76 | ofMatrix4x4 mymat = ofMatrix4x4( 77 | right.x, up.x, forward.x, 0, 78 | right.y, up.y, forward.y, 0, 79 | right.z, up.z, forward.z, 0, 80 | 0, floorplane.w, 0, 1); 81 | 82 | ofMatrix4x4 currenttranslation; 83 | currenttranslation.translate(ofVec3f(kinectcamxposin3dworld, kinectcamyposin3dworld, kinectcamzposin3dworld)); 84 | ofMatrix4x4 currentrotation; 85 | currentrotation.rotate(ofQuaternion(kinectyawin3dworld, ofVec3f(0, 1, 0))); 86 | ofMatrix4x4 currentscale; 87 | currentscale.makeScaleMatrix(-1, 1, 1); 88 | 89 | if (mapKinectto3DWorld) { 90 | realworldkinecttransformmatrix = mymat*currentrotation*currenttranslation*currentscale; 91 | } 92 | else { 93 | realworldkinecttransformmatrix = currentrotation*currenttranslation*currentscale; 94 | } 95 | 96 | } 97 | 98 | void nCKinectCamera::drawGUI() { 99 | //gui.setPosition(ofGetWidth() - gui.getWidth() - 30, 10); 100 | gui.draw(); 101 | 102 | float deg = ofWrapDegrees(getKinectCameraRotation().getEuler().x, -90, 90); 103 | 104 | ofDrawBitmapStringHighlight("height in real world: "+ofToString(getKinectCameraPosition().y), gui.getPosition().x+5, gui.getHeight()+ gui.getPosition().y+20); 105 | ofDrawBitmapStringHighlight("pitch in real world: " + ofToString(deg), gui.getPosition().x+5, gui.getHeight() + gui.getPosition().y + 40); 106 | } 107 | 108 | ofVec4f nCKinectCamera::getFloorPlane() { 109 | return floorplane; 110 | } 111 | 112 | ofVec3f nCKinectCamera::getKinectCameraPosition() { 113 | ofVec3f trans; 114 | ofQuaternion rot; 115 | ofVec3f scale; 116 | ofQuaternion scaleor; 117 | realworldkinecttransformmatrix.decompose(trans, rot, scale, scaleor); 118 | 119 | return trans; 120 | 121 | } 122 | 123 | ofQuaternion nCKinectCamera::getKinectCameraRotation() { 124 | ofVec3f trans; 125 | ofQuaternion rot; 126 | ofVec3f scale; 127 | ofQuaternion scaleor; 128 | realworldkinecttransformmatrix.decompose(trans, rot, scale, scaleor); 129 | 130 | return rot; 131 | } 132 | 133 | void nCKinectCamera::begin() { 134 | transformGL(); 135 | setTransformMatrix(realworldkinecttransformmatrix); 136 | if (drawCamera) { 137 | draw(); 138 | } 139 | } 140 | 141 | void nCKinectCamera::end() { 142 | restoreTransformGL(); 143 | } 144 | 145 | void nCKinectCamera::draw() { 146 | ofDrawAxis(0.5); 147 | model.drawWireframe(); 148 | } 149 | 150 | 151 | void nCKinectCamera::setTransformMatrix(const ofMatrix4x4 &m44) { 152 | ofVec3f position; 153 | ofQuaternion orientation; 154 | ofVec3f scale; 155 | ofQuaternion so; 156 | m44.decompose(position, orientation, scale, so); 157 | setPosition(position); 158 | setOrientation(orientation); 159 | setScale(scale); 160 | updateAxis(); 161 | onPositionChanged(); 162 | onOrientationChanged(); 163 | onScaleChanged(); 164 | } 165 | 166 | 167 | /* 168 | //---------------------------------------- 169 | void ofNode::setTransformMatrix(const ofMatrix4x4 &m44) { 170 | localTransformMatrix = m44; 171 | 172 | ofVec3f position; 173 | ofQuaternion orientation; 174 | ofVec3f scale; 175 | ofQuaternion so; 176 | localTransformMatrix.decompose(position, orientation, scale, so); 177 | this->position = position; 178 | this->orientation = orientation; 179 | this->scale = scale; 180 | updateAxis(); 181 | 182 | onPositionChanged(); 183 | onOrientationChanged(); 184 | onScaleChanged(); 185 | } 186 | */ 187 | -------------------------------------------------------------------------------- /src/core/ncKinectCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGui.h" 5 | 6 | 7 | class nCKinectCamera : public ofNode { 8 | 9 | private: 10 | 11 | void draw(); 12 | ofVec4f floorplane; 13 | 14 | //GUI 15 | ofxPanel gui; 16 | ofParameter kinectcamxposin3dworld; 17 | ofParameter kinectcamyposin3dworld; 18 | ofParameter kinectcamzposin3dworld; 19 | ofParameter kinectyawin3dworld; 20 | ofParameter freezeFloorplane; 21 | ofParameter drawCamera; 22 | ofParameter mapKinectto3DWorld; 23 | void setupGUI(); 24 | int loadcounter; 25 | int freezefloorplanecounter; 26 | bool floorplaneshouldbein; 27 | public: 28 | 29 | ~nCKinectCamera(); 30 | nCKinectCamera(); 31 | 32 | ofBoxPrimitive model; 33 | ofMatrix4x4 realworldkinecttransformmatrix; 34 | 35 | void setup(); 36 | 37 | void begin(); 38 | 39 | void end(); 40 | 41 | void update(ofVec4f _floorplane); 42 | 43 | void drawGUI(); 44 | 45 | ofVec4f getFloorPlane(); 46 | 47 | ofVec3f getKinectCameraPosition(); 48 | ofQuaternion getKinectCameraRotation(); 49 | 50 | void setTransformMatrix(const ofMatrix4x4 &m44); 51 | 52 | 53 | }; -------------------------------------------------------------------------------- /src/core/ncKinectEventDispatcher.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectEventDispatcher.h" 2 | 3 | ncKinectEventDispatcher ncKinectEventDispatcher::NCEVENTDISPATCHER; 4 | 5 | ncKinectEventDispatcher::~ncKinectEventDispatcher() { 6 | 7 | } 8 | 9 | ncKinectEventDispatcher::ncKinectEventDispatcher() { 10 | ncKinectEventDispatcher::NCEVENTDISPATCHER = *this; 11 | } 12 | 13 | void ncKinectEventDispatcher::dispatchDiscreteGesture(NCGenericEventArg &arg) { 14 | ofNotifyEvent(DISCRETE_GESTURE, arg, this); 15 | } 16 | 17 | void ncKinectEventDispatcher::dispatchContinuousGesture(NCGenericEventArg &arg) { 18 | ofNotifyEvent(CONTINUOUS_GESTURE, arg, this); 19 | } 20 | 21 | void ncKinectEventDispatcher::dispatchClosetUserChanged(NCGenericEventArg & arg) { 22 | ofNotifyEvent(CLOSEST_USER_CHANGED, arg, this); 23 | } 24 | 25 | void ncKinectEventDispatcher::dispatchNewUser(NCGenericEventArg & arg) { 26 | ofNotifyEvent(NEW_USER, arg, this); 27 | } 28 | 29 | void ncKinectEventDispatcher::dispatchLostUser(NCGenericEventArg & arg) { 30 | ofNotifyEvent(LOST_USER, arg, this); 31 | } 32 | -------------------------------------------------------------------------------- /src/core/ncKinectEventDispatcher.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ofMain.h" 3 | 4 | 5 | class NCAbstractEventBaseObject { 6 | 7 | public: 8 | 9 | 10 | NCAbstractEventBaseObject() { 11 | 12 | }; 13 | 14 | ~NCAbstractEventBaseObject() { 15 | 16 | } 17 | 18 | virtual void iamHereForTheShowSoThatThisWillCompile() { 19 | 20 | } 21 | }; 22 | 23 | class NCGenericEventArg : public ofEventArgs { 24 | 25 | public: 26 | NCAbstractEventBaseObject *pointertosender; 27 | string message; 28 | float value; 29 | int userid; 30 | }; 31 | 32 | class ncKinectEventDispatcher { 33 | 34 | public: 35 | 36 | static ncKinectEventDispatcher NCEVENTDISPATCHER; 37 | 38 | ~ncKinectEventDispatcher(); 39 | ncKinectEventDispatcher(); 40 | 41 | ofEvent DISCRETE_GESTURE; 42 | void dispatchDiscreteGesture(NCGenericEventArg &arg); 43 | 44 | ofEvent CONTINUOUS_GESTURE; 45 | void dispatchContinuousGesture(NCGenericEventArg &arg); 46 | 47 | ofEvent CLOSEST_USER_CHANGED; 48 | void dispatchClosetUserChanged(NCGenericEventArg &arg); 49 | 50 | ofEvent NEW_USER; 51 | void dispatchNewUser(NCGenericEventArg &arg); 52 | 53 | ofEvent LOST_USER; 54 | void dispatchLostUser(NCGenericEventArg &arg); 55 | }; -------------------------------------------------------------------------------- /src/core/ncKinectUser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | //https://vvvv.org/sites/default/files/images/kinectskeleton-map2.png 5 | 6 | //http://peted.azurewebsites.net/wp-content/uploads/2015/04/hierarchy_thumb.png 7 | enum _ncJointType 8 | { 9 | ncJointType_SpineBase = 0, 10 | ncJointType_SpineMid = 1, 11 | ncJointType_Neck = 2, 12 | ncJointType_Head = 3, 13 | ncJointType_ShoulderLeft = 4, 14 | ncJointType_ElbowLeft = 5, 15 | ncJointType_WristLeft = 6, 16 | ncJointType_HandLeft = 7, 17 | ncJointType_ShoulderRight = 8, 18 | ncJointType_ElbowRight = 9, 19 | ncJointType_WristRight = 10, 20 | ncJointType_HandRight = 11, 21 | ncJointType_HipLeft = 12, 22 | ncJointType_KneeLeft = 13, 23 | ncJointType_AnkleLeft = 14, 24 | ncJointType_FootLeft = 15, 25 | ncJointType_HipRight = 16, 26 | ncJointType_KneeRight = 17, 27 | ncJointType_AnkleRight = 18, 28 | ncJointType_FootRight = 19, 29 | ncJointType_SpineShoulder = 20, 30 | ncJointType_HandTipLeft = 21, 31 | ncJointType_ThumbLeft = 22, 32 | ncJointType_HandTipRight = 23, 33 | ncJointType_ThumbRight = 24, 34 | ncJointType_Count = (ncJointType_ThumbRight + 1) 35 | }; 36 | 37 | class nc3DBone :public ofNode { 38 | public: 39 | 40 | ofBoxPrimitive bonecube; 41 | ofSpherePrimitive bonejoint; 42 | bool bInverse; 43 | 44 | ofColor bonecolor; 45 | ofColor bonejointcolor; 46 | 47 | nc3DBone() { 48 | bonecolor = ofColor(190, 190, 190); 49 | bonejointcolor = ofColor(74, 245, 254); 50 | bonecube.set(0.1, 0.1, 0.1); 51 | bonejoint.set(0.01, 10); 52 | } 53 | 54 | void setBoneDimension(ofVec2f _dimensions) { 55 | bonecube.setWidth(_dimensions.x); 56 | bonecube.setDepth(_dimensions.y); 57 | } 58 | 59 | void setJointDimension(float _radius) { 60 | bonejoint.setRadius(_radius); 61 | } 62 | 63 | 64 | void update(ofVec3f _startpos, ofVec3f _endpos) { 65 | setGlobalPosition(_startpos); 66 | ofQuaternion rotation; 67 | rotation.makeRotate(ofVec3f(0, 1, 0), (_startpos - _endpos).getNormalized()); 68 | setGlobalOrientation(rotation); 69 | 70 | if (_endpos.distance(ofVec3f(0, 0, 0)) != 0) { 71 | float distance = _startpos.distance(_endpos); 72 | bonecube.setGlobalPosition(0, -distance*0.5, 0); 73 | bonecube.setHeight(distance); 74 | } 75 | 76 | } 77 | 78 | void draw() { 79 | if (getGlobalPosition() != glm::vec3(0)) { 80 | transformGL(); 81 | ofSetColor(bonecolor); 82 | bonecube.drawWireframe(); 83 | ofSetColor(bonejointcolor); 84 | bonejoint.draw(); 85 | ofSetColor(255); 86 | restoreTransformGL(); 87 | } 88 | } 89 | }; 90 | 91 | class ncKinectUser { 92 | 93 | public: 94 | 95 | bool tracked; 96 | int id; 97 | UINT64 kinectid; 98 | ofColor color; 99 | vector joints3dposition; 100 | vector joints3drotation; 101 | vector joints2dposition; 102 | vector bones3D; 103 | vector bonesVanity3D; 104 | ofPixels userpixels; 105 | ncKinectUser() { 106 | 107 | userpixels.allocate(512, 424, OF_IMAGE_GRAYSCALE); 108 | 109 | framestorecord = 30; 110 | threshold = 0.01; 111 | 112 | for (size_t i = 0; i < ncJointType_Count; i++) { 113 | bones3D.push_back(nc3DBone()); 114 | } 115 | for (size_t i = 0; i < 4; i++) { 116 | bonesVanity3D.push_back(nc3DBone()); 117 | } 118 | } 119 | 120 | void recordPositions() { 121 | if (joints3dposition.size() > 0) { 122 | if (recordedpositions.size() == 30) { 123 | recordedpositions.erase(recordedpositions.begin()); 124 | } 125 | recordedpositions.push_back(joints3dposition[ncJointType_SpineBase]); 126 | } 127 | } 128 | 129 | void generate3DSkeleton() { 130 | 131 | if (joints3dposition.size() > 0) { 132 | 133 | bones3D[ncJointType_Head].update(joints3dposition[ncJointType_Head], joints3dposition[ncJointType_Neck]); 134 | bones3D[ncJointType_Neck].update(joints3dposition[ncJointType_Neck], joints3dposition[ncJointType_SpineShoulder]); 135 | bones3D[ncJointType_SpineShoulder].update(joints3dposition[ncJointType_SpineShoulder], joints3dposition[ncJointType_SpineMid]); 136 | 137 | bones3D[ncJointType_SpineMid].update(joints3dposition[ncJointType_SpineMid], joints3dposition[ncJointType_SpineBase]); 138 | 139 | bones3D[ncJointType_ShoulderLeft].update(joints3dposition[ncJointType_ShoulderLeft], joints3dposition[ncJointType_SpineShoulder]); 140 | bones3D[ncJointType_ElbowLeft].update(joints3dposition[ncJointType_ElbowLeft], joints3dposition[ncJointType_ShoulderLeft]); 141 | bones3D[ncJointType_WristLeft].update(joints3dposition[ncJointType_WristLeft], joints3dposition[ncJointType_ElbowLeft]); 142 | 143 | bones3D[ncJointType_HandLeft].update(joints3dposition[ncJointType_HandLeft], joints3dposition[ncJointType_WristLeft]); 144 | bones3D[ncJointType_HandTipLeft].update(joints3dposition[ncJointType_HandTipLeft], joints3dposition[ncJointType_HandLeft]); 145 | bones3D[ncJointType_ThumbLeft].update(joints3dposition[ncJointType_ThumbLeft], joints3dposition[ncJointType_WristLeft]); 146 | 147 | bones3D[ncJointType_ShoulderRight].update(joints3dposition[ncJointType_ShoulderRight], joints3dposition[ncJointType_SpineShoulder]); 148 | bones3D[ncJointType_ElbowRight].update(joints3dposition[ncJointType_ElbowRight], joints3dposition[ncJointType_ShoulderRight]); 149 | bones3D[ncJointType_WristRight].update(joints3dposition[ncJointType_WristRight], joints3dposition[ncJointType_ElbowRight]); 150 | 151 | bones3D[ncJointType_HandRight].update(joints3dposition[ncJointType_HandRight], joints3dposition[ncJointType_WristRight]); 152 | bones3D[ncJointType_HandTipRight].update(joints3dposition[ncJointType_HandTipRight], joints3dposition[ncJointType_HandRight]); 153 | bones3D[ncJointType_ThumbRight].update(joints3dposition[ncJointType_ThumbRight], joints3dposition[ncJointType_WristRight]); 154 | 155 | bones3D[ncJointType_HipLeft].update(joints3dposition[ncJointType_HipLeft], joints3dposition[ncJointType_SpineBase]); 156 | bones3D[ncJointType_KneeLeft].update(joints3dposition[ncJointType_KneeLeft], joints3dposition[ncJointType_HipLeft]); 157 | bones3D[ncJointType_AnkleLeft].update(joints3dposition[ncJointType_AnkleLeft], joints3dposition[ncJointType_KneeLeft]); 158 | 159 | bones3D[ncJointType_FootLeft].update(joints3dposition[ncJointType_FootLeft], joints3dposition[ncJointType_AnkleLeft]); 160 | 161 | bones3D[ncJointType_HipRight].update(joints3dposition[ncJointType_HipRight], joints3dposition[ncJointType_SpineBase]); 162 | bones3D[ncJointType_KneeRight].update(joints3dposition[ncJointType_KneeRight], joints3dposition[ncJointType_HipRight]); 163 | bones3D[ncJointType_AnkleRight].update(joints3dposition[ncJointType_AnkleRight], joints3dposition[ncJointType_KneeRight]); 164 | bones3D[ncJointType_FootRight].update(joints3dposition[ncJointType_FootRight], joints3dposition[ncJointType_AnkleRight]); 165 | 166 | bonesVanity3D[0].update(joints3dposition[ncJointType_ShoulderLeft], joints3dposition[ncJointType_SpineMid]); 167 | bonesVanity3D[1].update(joints3dposition[ncJointType_ShoulderRight], joints3dposition[ncJointType_SpineMid]); 168 | bonesVanity3D[2].update(joints3dposition[ncJointType_HipLeft], joints3dposition[ncJointType_SpineMid]); 169 | bonesVanity3D[3].update(joints3dposition[ncJointType_HipRight], joints3dposition[ncJointType_SpineMid]); 170 | 171 | } 172 | } 173 | 174 | bool isUserMoving() { 175 | 176 | //USE STANDARD DEVIATION 177 | glm::vec3 sum = glm::vec3(0, 0, 0), mean = glm::vec3(0, 0, 0), standardDeviation = glm::vec3(0, 0, 0); 178 | 179 | for (int i = 0; i < recordedpositions.size(); ++i) 180 | { 181 | sum += recordedpositions[i]; 182 | } 183 | 184 | mean = sum / recordedpositions.size(); 185 | 186 | for (int i = 0; i < recordedpositions.size(); ++i) { 187 | 188 | glm::vec3 dev = glm::vec3(pow(recordedpositions[i].x - mean.x, 2), pow(recordedpositions[i].y - mean.y, 2), pow(recordedpositions[i].z - mean.z, 2)); 189 | standardDeviation += dev; 190 | } 191 | 192 | standardDeviation = standardDeviation / recordedpositions.size(); 193 | 194 | glm::vec3 stddev = glm::vec3(sqrt(standardDeviation.x), sqrt(standardDeviation.y), sqrt(standardDeviation.z)); 195 | 196 | glm::vec3 normal = glm::vec3(0, 0, 0); 197 | 198 | float distance = glm::distance(stddev, normal);//stddev.distance(normal); 199 | 200 | if (distance > threshold) { 201 | return true; 202 | } 203 | else { 204 | return false; 205 | } 206 | } 207 | 208 | void setBoneDimensions(glm::vec2 _dimensions) { 209 | for (size_t i = 0; i < bones3D.size(); i++) { 210 | bones3D[i].setBoneDimension(_dimensions); 211 | } 212 | 213 | for (size_t i = 0; i < bonesVanity3D.size(); i++) { 214 | bonesVanity3D[i].setBoneDimension(_dimensions); 215 | } 216 | } 217 | 218 | void setJointDimensions(float _radius) { 219 | for (size_t i = 0; i < bones3D.size(); i++) { 220 | bones3D[i].setJointDimension(_radius); 221 | } 222 | 223 | for (size_t i = 0; i < bonesVanity3D.size(); i++) { 224 | bonesVanity3D[i].setJointDimension(_radius); 225 | } 226 | } 227 | 228 | void setJointColor(ofColor _color) { 229 | for (size_t i = 0; i < bones3D.size(); i++) { 230 | bones3D[i].bonejointcolor = _color; 231 | } 232 | 233 | for (size_t i = 0; i < bonesVanity3D.size(); i++) { 234 | bonesVanity3D[i].bonejointcolor = _color; 235 | } 236 | } 237 | 238 | void setBoneColor(ofColor _color) { 239 | for (size_t i = 0; i < bones3D.size(); i++) { 240 | bones3D[i].bonecolor = _color; 241 | } 242 | 243 | for (size_t i = 0; i < bonesVanity3D.size(); i++) { 244 | bonesVanity3D[i].bonecolor = _color; 245 | } 246 | } 247 | 248 | private: 249 | int framestorecord; 250 | float threshold; 251 | vector recordedpositions; 252 | }; -------------------------------------------------------------------------------- /src/core/ncKinectUserManager.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectUserManager.h" 2 | 3 | ncKinectUserManager::~ncKinectUserManager() { 4 | 5 | } 6 | 7 | ncKinectUserManager::ncKinectUserManager() { 8 | 9 | } 10 | 11 | void ncKinectUserManager::setup(vector& _users, nCKinectCamera &_camera) { 12 | originalusers = &_users; 13 | kinectcamera = &_camera; 14 | //USER MANAGEMENT 15 | trackedusers.push_back(false); 16 | trackedusers.push_back(false); 17 | trackedusers.push_back(false); 18 | trackedusers.push_back(false); 19 | trackedusers.push_back(false); 20 | trackedusers.push_back(false); 21 | 22 | closestuserid = -1; 23 | } 24 | 25 | void ncKinectUserManager::setup(vector& _users) { 26 | originalusers = &_users; 27 | //USER MANAGEMENT 28 | trackedusers.push_back(false); 29 | trackedusers.push_back(false); 30 | trackedusers.push_back(false); 31 | trackedusers.push_back(false); 32 | trackedusers.push_back(false); 33 | trackedusers.push_back(false); 34 | 35 | closestuserid = -1; 36 | } 37 | 38 | vector& ncKinectUserManager::getUsers() { 39 | return usersforoutput; 40 | } 41 | 42 | vector ncKinectUserManager::getUsersRemapped3dposition() { 43 | vector myusers; 44 | for (size_t i = 0; i < usersforoutput.size(); i++) { 45 | 46 | ncKinectUser user = *usersforoutput[i]; 47 | for (size_t k = 0; k < user.joints3dposition.size(); k++) { 48 | ofVec3f oldpoint = user.joints3dposition[k]; 49 | ofVec3f newpoint = oldpoint*kinectcamera->realworldkinecttransformmatrix; 50 | user.joints3dposition[k] = newpoint; 51 | } 52 | myusers.push_back(user); 53 | } 54 | 55 | return myusers; 56 | } 57 | 58 | ncKinectUser ncKinectUserManager::getRemapped3dPositionForUser(int _id) { 59 | 60 | ncKinectUser *user = getUserById(_id); 61 | 62 | if (user != nullptr) { 63 | 64 | ncKinectUser usernew = *user; 65 | 66 | for (size_t k = 0; k < user->joints3dposition.size(); k++) { 67 | ofVec3f oldpoint = user->joints3dposition[k]; 68 | ofVec3f newpoint = oldpoint*kinectcamera->realworldkinecttransformmatrix; 69 | usernew.joints3dposition[k] = newpoint; 70 | } 71 | 72 | return usernew; 73 | } 74 | 75 | return ncKinectUser(); 76 | } 77 | 78 | ncKinectUser * ncKinectUserManager::getClosestUser() { 79 | 80 | vector < vector > users; 81 | for (size_t i = 0; i < usersforoutput.size(); i++) { 82 | vector user; 83 | user.push_back(usersforoutput[i]->id); 84 | user.push_back(usersforoutput[i]->joints3dposition[ncJointType_SpineBase].z); 85 | users.push_back(user); 86 | } 87 | 88 | std::sort(users.begin(), users.end(), 89 | [](const std::vector& a, const std::vector& b) { 90 | return a[1] < b[1]; 91 | }); 92 | 93 | if (users.size() > 0) { 94 | return getUserById(users[0][0]); 95 | } 96 | 97 | return nullptr; 98 | } 99 | 100 | int ncKinectUserManager::getClosestUserId() { 101 | ncKinectUser *user = getClosestUser(); 102 | if (user != nullptr) { 103 | return user->id; 104 | } 105 | return -1; 106 | } 107 | 108 | ncKinectUser * ncKinectUserManager::getUserById(int _id) { 109 | for (size_t i = 0; i < usersforoutput.size(); i++) { 110 | if (usersforoutput[i]->id == _id) { 111 | return usersforoutput[i]; 112 | } 113 | } 114 | return nullptr; 115 | } 116 | 117 | void ncKinectUserManager::update() { 118 | 119 | vector totrack; 120 | for (size_t i = 0; i < originalusers->size(); i++) { 121 | 122 | bool tracked = (*originalusers)[i].tracked; 123 | if ((bool)tracked) { 124 | 125 | (*originalusers)[i].recordPositions(); 126 | (*originalusers)[i].generate3DSkeleton(); 127 | 128 | totrack.push_back(true); 129 | } 130 | else { 131 | totrack.push_back(false); 132 | } 133 | } 134 | doUserManagement(totrack); 135 | 136 | if (getClosestUserId() != closestuserid) { 137 | closestuserid = getClosestUserId(); 138 | NCGenericEventArg arg; 139 | arg.userid = closestuserid; 140 | ncKinectEventDispatcher::NCEVENTDISPATCHER.dispatchClosetUserChanged(arg); 141 | } 142 | } 143 | 144 | 145 | void ncKinectUserManager::doUserManagement(vector compare) { 146 | for (int i = 0; i < compare.size(); i++) { 147 | 148 | bool incomingvalue = compare[i]; 149 | bool currentvalue = trackedusers[i]; 150 | 151 | if (incomingvalue != currentvalue) { 152 | 153 | if (incomingvalue) { 154 | 155 | usersforoutput.push_back(&(*originalusers)[i]); 156 | NCGenericEventArg arg; 157 | arg.userid = i; 158 | ncKinectEventDispatcher::NCEVENTDISPATCHER.dispatchNewUser(arg); 159 | } 160 | else { 161 | //USER LOST 162 | for (int j = 0; j < usersforoutput.size(); j++) { 163 | if (usersforoutput[j]->id == i) { 164 | NCGenericEventArg arg; 165 | arg.userid = i; 166 | ncKinectEventDispatcher::NCEVENTDISPATCHER.dispatchLostUser(arg); 167 | usersforoutput.erase(usersforoutput.begin() + j); 168 | //do not delete this pointer because the data is tied to a memry spot that is still in use 169 | } 170 | } 171 | } 172 | } 173 | } 174 | trackedusers = compare; 175 | } 176 | -------------------------------------------------------------------------------- /src/core/ncKinectUserManager.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "ofMain.h" 5 | #include "ncKinectUser.h" 6 | #include "ncKinectCamera.h" 7 | #include "ncKinectEventDispatcher.h" 8 | 9 | class ncKinectUserManager { 10 | 11 | private: 12 | 13 | vector usersforoutput; 14 | vector * originalusers; 15 | 16 | nCKinectCamera *kinectcamera; 17 | 18 | void doUserManagement(vector compare); 19 | 20 | vector trackedusers; 21 | 22 | int closestuserid; 23 | 24 | public: 25 | ~ncKinectUserManager(); 26 | ncKinectUserManager(); 27 | 28 | void setup(vector &_users, nCKinectCamera &_camera); 29 | void setup(vector &_users); 30 | 31 | vector & getUsers(); 32 | vector getUsersRemapped3dposition(); 33 | ncKinectUser getRemapped3dPositionForUser(int _id); 34 | 35 | ncKinectUser * getClosestUser(); 36 | int getClosestUserId(); 37 | ncKinectUser * getUserById(int _id); 38 | 39 | void update(); 40 | }; -------------------------------------------------------------------------------- /src/core/ncKinectv2Core.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectv2Core.h" 2 | 3 | ncKinectv2Core::~ncKinectv2Core() { 4 | SafeRelease(sensor); 5 | SafeRelease(reader); 6 | SafeRelease(mapper); 7 | stopThread(); 8 | } 9 | 10 | ncKinectv2Core::ncKinectv2Core() { 11 | 12 | } 13 | 14 | 15 | /******************************/ 16 | /*SETUP FUNCTIONS */ 17 | /******************************/ 18 | 19 | #ifdef GESTURES 20 | void ncKinectv2Core::setup(string database, bool _usecolor) { 21 | bUseColor = _usecolor; 22 | prepareData(); 23 | if (bUseColor) { 24 | initKinectGestures(FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Body | FrameSourceTypes::FrameSourceTypes_BodyIndex | FrameSourceTypes::FrameSourceTypes_Color, database); 25 | } 26 | else { 27 | initKinectGestures(FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Body | FrameSourceTypes::FrameSourceTypes_BodyIndex, database); 28 | } 29 | 30 | } 31 | void ncKinectv2Core::turnOffGestureDectors() { 32 | for (int i = 0; i < BODY_COUNT; i++) { 33 | gesturedetectors[i]->setTrackingId(0); 34 | gesturedetectors[i]->setPaused(true); 35 | } 36 | } 37 | 38 | void ncKinectv2Core::turnOnGestureDetectorForUser(int userid, UINT64 kinectid) { 39 | gesturedetectors[userid]->setTrackingId(kinectid); 40 | gesturedetectors[userid]->setPaused(false); 41 | } 42 | #endif 43 | 44 | void ncKinectv2Core::setup(bool _usecolor) { 45 | 46 | bUseColor = _usecolor; 47 | prepareData(); 48 | if (bUseColor) { 49 | initKinect(FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Body | FrameSourceTypes::FrameSourceTypes_BodyIndex | FrameSourceTypes::FrameSourceTypes_Color); 50 | } 51 | else { 52 | initKinect(FrameSourceTypes::FrameSourceTypes_Depth | FrameSourceTypes::FrameSourceTypes_Body | FrameSourceTypes::FrameSourceTypes_BodyIndex); 53 | } 54 | } 55 | 56 | 57 | void ncKinectv2Core::prepareData() { 58 | 59 | //DEPTHMAP 60 | depthmap = new UINT16[512 * 424]; 61 | depthpixels.allocate(512, 424, OF_IMAGE_GRAYSCALE); 62 | 63 | //POINTCLOUD 64 | pointcloud.setMode(OF_PRIMITIVE_POINTS); 65 | pointcloud.getVertices().resize(512 * 424); 66 | pointcloud.getTexCoords().resize(512 * 424); 67 | pointcloud.getColors().resize(512 * 424); 68 | 69 | userpointcloudmesh.setMode(OF_PRIMITIVE_POINTS); 70 | 71 | //BODYINDEX MAP 72 | bodyindexmap = new BYTE[512 * 424]; 73 | for (size_t i = 0; i < 512 * 424; i++) { 74 | bodyindexmap[i] = 255; 75 | } 76 | 77 | bodyindexmappixels.allocate(512, 424, OF_IMAGE_GRAYSCALE); 78 | for (int i = 0; i < 512 * 424; i++) { 79 | bodyindexmappixels[i] = 0; 80 | } 81 | 82 | //COLOR STUFF 83 | if (bUseColor) { 84 | bodyindexmappixelscolormapped.allocate(512, 424, OF_IMAGE_COLOR_ALPHA); 85 | colorpixels.allocate(1920, 1080, OF_IMAGE_COLOR_ALPHA); 86 | } 87 | 88 | //USER MANAGEMENT 89 | usercolors.push_back(ofColor::darkGrey); 90 | usercolors.push_back(ofColor::darkRed); 91 | usercolors.push_back(ofColor::darkBlue); 92 | usercolors.push_back(ofColor::darkGoldenRod); 93 | usercolors.push_back(ofColor::darkKhaki); 94 | usercolors.push_back(ofColor::darkOrchid); 95 | 96 | for (size_t i = 0; i < BODY_COUNT; i++) { 97 | ncKinectUser user; 98 | user.id = i; 99 | user.tracked = false; 100 | user.color = usercolors[i]; 101 | users.push_back(user); 102 | } 103 | 104 | #ifdef USETHREAD 105 | startThread(); 106 | #endif 107 | 108 | } 109 | 110 | 111 | /******************************/ 112 | /*KINECT INIT FUNCTIONS */ 113 | /******************************/ 114 | 115 | #ifdef GESTURES 116 | //----------------------------------------- 117 | bool ncKinectv2Core::initKinectGestures(DWORD enabledFrameSourceTypes, string database) { 118 | 119 | if (FAILED(GetDefaultKinectSensor(&sensor))) { 120 | cout << "FAILED TO GET KINECT" << endl; 121 | return false; 122 | } 123 | 124 | if (sensor) { 125 | sensor->Open(); 126 | HRESULT hResult = S_OK; 127 | hResult = sensor->get_CoordinateMapper(&mapper); 128 | if (FAILED(hResult)) { 129 | std::cout << "Error : IKinectSensor::get_CoordinateMapper()" << std::endl; 130 | } 131 | hResult = sensor->OpenMultiSourceFrameReader(enabledFrameSourceTypes, &reader); 132 | if (FAILED(hResult)) { 133 | std::cout << "Error : IKinectSensor::OpenMultiSourceFrameReader()" << std::endl; 134 | } 135 | 136 | for (int i = 0; i < BODY_COUNT; ++i) { 137 | ncKinectv2GestureDetector * detector = new ncKinectv2GestureDetector(sensor, i, database); 138 | gesturedetectors.push_back(detector); 139 | 140 | 141 | } 142 | return true; 143 | } 144 | else { 145 | return false; 146 | } 147 | } 148 | #endif 149 | 150 | 151 | //----------------------------------------- 152 | bool ncKinectv2Core::initKinect(DWORD enabledFrameSourceTypes) { 153 | 154 | if (FAILED(GetDefaultKinectSensor(&sensor))) { 155 | cout << "FAILED TO GET KINECT" << endl; 156 | return false; 157 | } 158 | 159 | if (sensor) { 160 | sensor->Open(); 161 | HRESULT hResult = S_OK; 162 | hResult = sensor->get_CoordinateMapper(&mapper); 163 | if (FAILED(hResult)) { 164 | std::cout << "Error : IKinectSensor::get_CoordinateMapper()" << std::endl; 165 | } 166 | hResult = sensor->OpenMultiSourceFrameReader(enabledFrameSourceTypes, &reader); 167 | if (FAILED(hResult)) { 168 | std::cout << "Error : IKinectSensor::OpenMultiSourceFrameReader()" << std::endl; 169 | } 170 | return true; 171 | } 172 | else { 173 | return false; 174 | } 175 | } 176 | 177 | /******************************/ 178 | /*KINECT DATA FUNCTIONS */ 179 | /******************************/ 180 | 181 | //-------------------------------------------------------------- 182 | void ncKinectv2Core::getDepthData(IMultiSourceFrame* frame) { 183 | 184 | IDepthFrame* depthframe; 185 | IDepthFrameReference* frameref = NULL; 186 | frame->get_DepthFrameReference(&frameref); 187 | frameref->AcquireFrame(&depthframe); 188 | if (frameref) frameref->Release(); 189 | if (!depthframe) { 190 | //cout << "skipped depthframe " << " " << ofToString(ofGetFrameNum()) << endl; 191 | return; 192 | } 193 | IFrameDescription * frameDescription = NULL; 194 | depthframe->get_FrameDescription(&frameDescription); 195 | int width; 196 | int height; 197 | frameDescription->get_Width(&width); 198 | frameDescription->get_Height(&height); 199 | 200 | depthframe->CopyFrameDataToArray(width*height, depthmap); 201 | 202 | SafeRelease(frameDescription); 203 | 204 | if (depthframe) depthframe->Release(); 205 | } 206 | 207 | void ncKinectv2Core::getColorData(IMultiSourceFrame * frame) { 208 | IColorFrame* colorframe; 209 | IColorFrameReference* frameref = NULL; 210 | frame->get_ColorFrameReference(&frameref); 211 | frameref->AcquireFrame(&colorframe); 212 | 213 | if (frameref)SafeRelease(frameref); 214 | 215 | if (!colorframe) { 216 | //cout << "skipped colorframe " << " " << ofToString(ofGetFrameNum()) << endl; 217 | return; 218 | } 219 | colorframe->CopyConvertedFrameDataToArray(colorpixels.size(), colorpixels.getData(), ColorImageFormat_Rgba); 220 | 221 | if (colorframe) colorframe->Release(); 222 | } 223 | 224 | //-------------------------------------------------------------- 225 | void ncKinectv2Core::getBodyData(IMultiSourceFrame* frame) { 226 | IBodyFrame* bodyframe; 227 | IBodyFrameReference* frameref = NULL; 228 | frame->get_BodyFrameReference(&frameref); 229 | frameref->AcquireFrame(&bodyframe); 230 | if (frameref) SafeRelease(frameref); 231 | 232 | if (!bodyframe) { 233 | //cout << "skipped bodyframe " << " " << ofToString(ofGetFrameNum()) << endl; 234 | return; 235 | } 236 | //SET FLOORPLANE 237 | Vector4 _floorplane; 238 | bodyframe->get_FloorClipPlane(&_floorplane); 239 | floorplane.x = _floorplane.x; 240 | floorplane.y = _floorplane.y; 241 | floorplane.z = _floorplane.z; 242 | floorplane.w = _floorplane.w; 243 | 244 | //GET JOINT DATA 245 | IBody* bodies[BODY_COUNT] = { 0 }; 246 | 247 | if (SUCCEEDED(bodyframe->GetAndRefreshBodyData(BODY_COUNT, bodies))) { 248 | 249 | //FIRST LOOP THROUGH TRACKED USER AND DO USER MANAGEMENT 250 | vector totrack; 251 | for (int i = 0; i < BODY_COUNT; i++) { 252 | 253 | #ifdef GESTURES 254 | gesturedetectors[i]->update(); 255 | #endif 256 | 257 | BOOLEAN tracked; 258 | UINT64 trackingId; 259 | bodies[i]->get_TrackingId(&trackingId); 260 | bodies[i]->get_IsTracked(&tracked); 261 | users[i].tracked = (bool)tracked; 262 | users[i].joints2dposition.clear(); 263 | users[i].joints3dposition.clear(); 264 | users[i].joints3drotation.clear(); 265 | users[i].kinectid = trackingId; 266 | 267 | if ((bool)tracked) { 268 | Joint joints[JointType::JointType_Count]; 269 | JointOrientation jointsOrient[JointType_Count]; 270 | if (SUCCEEDED(bodies[i]->GetJoints(JointType::JointType_Count, joints))) { 271 | if (SUCCEEDED(bodies[i]->GetJointOrientations(JointType_Count, jointsOrient))) { 272 | for (int k = 0; k < JointType::JointType_Count; k++) { 273 | users[i].joints3dposition.push_back(ofVec3f(joints[k].Position.X, joints[k].Position.Y, joints[k].Position.Z)); 274 | users[i].joints3drotation.push_back(ofVec4f(jointsOrient[k].Orientation.x, jointsOrient[k].Orientation.y, jointsOrient[k].Orientation.z, jointsOrient[k].Orientation.w)); 275 | DepthSpacePoint depthPoint = { 0 }; 276 | mapper->MapCameraPointToDepthSpace(joints[k].Position, &depthPoint); 277 | users[i].joints2dposition.push_back(ofVec2f(depthPoint.X, depthPoint.Y)); 278 | } 279 | } 280 | } 281 | } 282 | } 283 | 284 | //After body processing is done, we're done with our bodies so release them. 285 | for (unsigned int bodyIndex = 0; bodyIndex < _countof(bodies); bodyIndex++) { 286 | SafeRelease(bodies[bodyIndex]); 287 | } 288 | 289 | } 290 | 291 | SafeRelease(bodyframe); 292 | } 293 | 294 | //-------------------------------------------------------------- 295 | void ncKinectv2Core::getBodyIndexData(IMultiSourceFrame* frame) { 296 | IBodyIndexFrame* bodyframe; 297 | IBodyIndexFrameReference* frameref = NULL; 298 | frame->get_BodyIndexFrameReference(&frameref); 299 | frameref->AcquireFrame(&bodyframe); 300 | if (frameref) SafeRelease(frameref); 301 | 302 | if (!bodyframe) { 303 | //cout << "skipped bodyindex data " << " " << ofToString(ofGetFrameNum()) << endl; 304 | return; 305 | } 306 | IFrameDescription * frameDescription = NULL; 307 | bodyframe->get_FrameDescription(&frameDescription); 308 | int width; 309 | int height; 310 | frameDescription->get_Width(&width); 311 | frameDescription->get_Height(&height); 312 | 313 | bodyframe->CopyFrameDataToArray(width*height, bodyindexmap); 314 | 315 | SafeRelease(bodyframe); 316 | } 317 | 318 | 319 | /******************************/ 320 | /*UPDATE FUNCTIONS */ 321 | /******************************/ 322 | 323 | #ifdef USETHREAD 324 | void ncKinectv2Core::threadedFunction() { 325 | 326 | while (isThreadRunning()) { 327 | if (reader) { 328 | locker.lock(); 329 | IMultiSourceFrame* frame = NULL; 330 | if (SUCCEEDED(reader->AcquireLatestFrame(&frame))) { 331 | getDepthData(frame); 332 | if (bUseColor) { 333 | getColorData(frame); 334 | } 335 | getBodyData(frame); 336 | getBodyIndexData(frame); 337 | } 338 | SafeRelease(frame); 339 | locker.unlock(); 340 | } 341 | } 342 | } 343 | #endif 344 | 345 | 346 | void ncKinectv2Core::update(bool _colorpointcloud , bool _coloruserpointcloud , bool _colorbodyindexmap) { 347 | 348 | #ifndef USETHREAD 349 | 350 | if (reader) { 351 | IMultiSourceFrame* frame = NULL; 352 | if (SUCCEEDED(reader->AcquireLatestFrame(&frame))) { 353 | getDepthData(frame); 354 | if (bUseColor) { 355 | getColorData(frame); 356 | } 357 | getBodyData(frame); 358 | getBodyIndexData(frame); 359 | } 360 | SafeRelease(frame); 361 | } 362 | #endif 363 | if (bUseColor) { 364 | if (_colorpointcloud || _coloruserpointcloud || _colorbodyindexmap) { 365 | mapper->MapDepthFrameToColorSpace(512 * 424, depthmap, 512 * 424, (ColorSpacePoint*)pointcloud.getTexCoordsPointer()); 366 | } 367 | } 368 | 369 | mapper->MapDepthFrameToCameraSpace(512 * 424, depthmap, 512 * 424, (CameraSpacePoint*)pointcloud.getVerticesPointer()); 370 | 371 | if (bUseColor) { 372 | if (_colorpointcloud) { 373 | colortexture.loadData(colorpixels); 374 | } 375 | } 376 | 377 | //POINTCLOUD AND BODYINDEXMAP IN ONE 378 | userpointcloudmesh.clear(); 379 | for (int y = 0; y < 424; y++) { 380 | for (int x = 0; x < 512; x++) { 381 | int index = (y * 512) + x; 382 | 383 | //depthmap 384 | depthpixels[index] = 65536 - (depthmap[index] * 65536 / 7999); 385 | 386 | //indexbodymap 387 | int uBodyIdx = bodyindexmap[index]; 388 | 389 | if (uBodyIdx > -1 && uBodyIdx < 6) { 390 | 391 | if (!_coloruserpointcloud) { 392 | userpointcloudmesh.addVertex(pointcloud.getVertex(index)); 393 | } 394 | if (bUseColor) { 395 | if (_colorbodyindexmap || _coloruserpointcloud) { 396 | ofVec2f mappedCoord = pointcloud.getTexCoord(index); 397 | mappedCoord.x = floor(mappedCoord.x); 398 | mappedCoord.y = floor(mappedCoord.y); 399 | if ((0 <= mappedCoord.x) && (mappedCoord.x < 1920) && (0 <= mappedCoord.y) && (mappedCoord.y < 1080)) { 400 | 401 | if (_colorbodyindexmap) { 402 | bodyindexmappixelscolormapped.setColor(x, y, colorpixels.getColor(mappedCoord.x, mappedCoord.y)); 403 | } 404 | 405 | if (_coloruserpointcloud) { 406 | userpointcloudmesh.addVertex(pointcloud.getVertex(index)); 407 | userpointcloudmesh.addColor(colorpixels.getColor(mappedCoord.x, mappedCoord.y)); 408 | } 409 | } 410 | } else if(!_coloruserpointcloud) { 411 | bodyindexmappixels[index] = 255; 412 | } 413 | } else { 414 | bodyindexmappixels[index] = 255; 415 | } 416 | } 417 | else { 418 | bodyindexmappixels[index] = 0; 419 | if (bUseColor) { 420 | if (_colorbodyindexmap) { 421 | bodyindexmappixelscolormapped.setColor(x, y, ofColor(0, 0, 0, 255)); 422 | } 423 | } 424 | } 425 | } 426 | } 427 | } 428 | 429 | void ncKinectv2Core::updatesepbodyindexmap(bool _colorpointcloud, bool _coloruserpointcloud) { 430 | #ifndef USETHREAD 431 | 432 | if (reader) { 433 | IMultiSourceFrame* frame = NULL; 434 | if (SUCCEEDED(reader->AcquireLatestFrame(&frame))) { 435 | getDepthData(frame); 436 | if (bUseColor) { 437 | getColorData(frame); 438 | } 439 | getBodyData(frame); 440 | getBodyIndexData(frame); 441 | } 442 | SafeRelease(frame); 443 | } 444 | #endif 445 | 446 | if (bUseColor) { 447 | if (_colorpointcloud || _coloruserpointcloud) { 448 | mapper->MapDepthFrameToColorSpace(512 * 424, depthmap, 512 * 424, (ColorSpacePoint*)pointcloud.getTexCoordsPointer()); 449 | } 450 | } 451 | 452 | mapper->MapDepthFrameToCameraSpace(512 * 424, depthmap, 512 * 424, (CameraSpacePoint*)pointcloud.getVerticesPointer()); 453 | 454 | if (bUseColor) { 455 | if (_colorpointcloud) { 456 | colortexture.loadData(colorpixels); 457 | } 458 | } 459 | 460 | //POINTCLOUD AND BODYINDEXMAP IN ONE 461 | userpointcloudmesh.clear(); 462 | for (int y = 0; y < 424; y++) { 463 | for (int x = 0; x < 512; x++) { 464 | int index = (y * 512) + x; 465 | 466 | //depthmap has value between 0 and 7999, so 8000 values. We map it to 16-bit integer here. 467 | depthpixels[index] = 65536 - (depthmap[index] * 65536 / 7999); 468 | 469 | //indexbodymap 470 | int uBodyIdx = bodyindexmap[index]; 471 | 472 | if (uBodyIdx > -1 && uBodyIdx < 6) { 473 | users[uBodyIdx].userpixels[index] = 255; 474 | 475 | if (!_coloruserpointcloud) { 476 | userpointcloudmesh.addVertex(pointcloud.getVertex(index)); 477 | } 478 | 479 | if (bUseColor) { 480 | 481 | if ( _coloruserpointcloud) { 482 | ofVec2f mappedCoord = pointcloud.getTexCoord(index); 483 | mappedCoord.x = floor(mappedCoord.x); 484 | mappedCoord.y = floor(mappedCoord.y); 485 | if ((0 <= mappedCoord.x) && (mappedCoord.x < 1920) && (0 <= mappedCoord.y) && (mappedCoord.y < 1080)) { 486 | userpointcloudmesh.addVertex(pointcloud.getVertex(index)); 487 | userpointcloudmesh.addColor(colorpixels.getColor(mappedCoord.x, mappedCoord.y)); 488 | } 489 | 490 | } 491 | } 492 | 493 | 494 | } else { 495 | for (size_t i = 0; i < users.size(); i++) { 496 | users[i].userpixels[index] = 0; 497 | } 498 | } 499 | } 500 | } 501 | } 502 | 503 | 504 | /******************************/ 505 | /*GETTERS */ 506 | /******************************/ 507 | 508 | ofVec4f ncKinectv2Core::getFloorPlane() 509 | { 510 | return floorplane; 511 | } 512 | 513 | vector & ncKinectv2Core::getUsers() { 514 | return users; 515 | } 516 | 517 | ofPixels_ & ncKinectv2Core::getDepthMap2D() { 518 | return depthpixels; 519 | } 520 | 521 | ofPixels & ncKinectv2Core::getBodyIndexPixels() { 522 | return bodyindexmappixels; 523 | } 524 | 525 | ofPixels & ncKinectv2Core::getBodyIndexPixelsColored() 526 | { 527 | return bodyindexmappixelscolormapped; 528 | } 529 | 530 | ofPixels & ncKinectv2Core::getColorPixels() { 531 | return colorpixels; 532 | } 533 | 534 | ofTexture & ncKinectv2Core::getColorTexture() 535 | { 536 | return colortexture; 537 | } 538 | 539 | 540 | 541 | ofMesh & ncKinectv2Core::getPointCloud3D() { 542 | return pointcloud; 543 | } 544 | 545 | ofMesh & ncKinectv2Core::getUserPointCloud3D() { 546 | return userpointcloudmesh; 547 | } 548 | 549 | ofVec3f ncKinectv2Core::convert2dPointToSpacePoint(ofVec2f _point) { 550 | 551 | ofVec2f intpoint = ofVec2f((int)_point.x, (int)_point.y); 552 | 553 | int pos = intpoint.x + 512 * intpoint.y; 554 | UINT16 depth = depthmap[pos]; 555 | 556 | DepthSpacePoint d; 557 | d.X = intpoint.x; 558 | d.Y = intpoint.y; 559 | 560 | CameraSpacePoint *p = new CameraSpacePoint(); 561 | mapper->MapDepthPointToCameraSpace(d, depth, p); 562 | 563 | ofVec3f pp = ofVec3f(p->X, p->Y, p->Z); 564 | 565 | delete p; 566 | 567 | return pp; 568 | } 569 | 570 | ofVec2f ncKinectv2Core::convert2dPointToColorSpacePoint(ofVec2f _point) { 571 | 572 | ofVec2f intpoint = ofVec2f((int)_point.x, (int)_point.y); 573 | int pos = intpoint.x + 512 * intpoint.y; 574 | UINT16 depth = depthmap[pos]; 575 | 576 | DepthSpacePoint d; 577 | d.X = intpoint.x; 578 | d.Y = intpoint.y; 579 | 580 | ColorSpacePoint *p = new ColorSpacePoint(); 581 | mapper->MapDepthPointToColorSpace(d, depth, p); 582 | 583 | ofVec2f pp = ofVec3f(p->X, p->Y); 584 | 585 | delete p; 586 | 587 | return pp; 588 | 589 | } 590 | 591 | 592 | /* 593 | @description: Filter to create a custom depth map image (grayscale, 8-bit). This method maps all values between frontPlaneDepth and backPlaneDepth to values between 0 and 255 594 | so these can be written to a PNG file to use as a heightmap in other applications like Unity. 595 | @author: Jan Vantomme 596 | @param cropRectangle: detail to crop out of the original depth image (max dimensions: 512 x 424 pixels) 597 | @param frontPlaneDepth: value between 0 and 7999 (maximum of kinect depth data 598 | @param backPlaneDepth: value between 0 and 7999 (maximum of kinect depth data 599 | 600 | */ 601 | 602 | ofPixels & ncKinectv2Core::getCustomDepthMap(ofRectangle cropRectangle, int frontPlaneDepth, int backPlaneDepth) 603 | { 604 | customDepthPixels.allocate(512, 424, OF_IMAGE_GRAYSCALE); 605 | 606 | // depthmap = new UINT16[512 * 424]; 607 | // filter depthmap data based on backplane + frontplane 608 | for (int j = 0; j < 424; j++) { 609 | for (int i = 0; i < 512; i++) { 610 | 611 | int index = (j * 512) + i; 612 | 613 | // Default pixel color is black 614 | int value = 0; 615 | 616 | // Change color of the pixel when the depth value is between front & backplane. 617 | if (depthmap[index] > frontPlaneDepth && depthmap[index] < backPlaneDepth) { 618 | value = ofMap(depthmap[index], frontPlaneDepth, backPlaneDepth, 0, 255, true); 619 | } 620 | 621 | customDepthPixels[index] = value; 622 | 623 | } 624 | } 625 | 626 | // crop pixels based on rectangle 627 | customDepthPixels.crop( cropRectangle.getX(), cropRectangle.getY(), cropRectangle.getWidth(), cropRectangle.getHeight()); 628 | 629 | return customDepthPixels; 630 | } -------------------------------------------------------------------------------- /src/core/ncKinectv2Core.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "Kinect.h" 5 | #include "ncKinectUser.h" 6 | 7 | 8 | //#define GESTURES 9 | #ifdef GESTURES 10 | #include "ncKinectv2GestureDetector.h" 11 | #endif 12 | 13 | //#define USETHREAD 14 | 15 | class ncKinectv2Core: public ofThread { 16 | 17 | public: 18 | ~ncKinectv2Core(); 19 | ncKinectv2Core(); 20 | 21 | #ifdef GESTURES 22 | void setup(string database, bool _usecolor = false); 23 | void turnOffGestureDectors(); 24 | void turnOnGestureDetectorForUser(int userid, UINT64 kinectid); 25 | #endif 26 | 27 | void setup(bool _usecolor = false); 28 | void update(bool _colorpointcloud = false, bool _coloruserpointcloud=false, bool _colorbodyindexmap=false); 29 | void updatesepbodyindexmap(bool _colorpointcloud = false, bool _coloruserpointcloud = false); 30 | 31 | 32 | //GETTERS 33 | ofVec4f getFloorPlane(); 34 | vector & getUsers(); 35 | ofPixels_ & getDepthMap2D(); 36 | ofPixels & getBodyIndexPixels(); 37 | ofPixels & getBodyIndexPixelsColored(); 38 | ofPixels & getColorPixels(); 39 | ofTexture & getColorTexture(); 40 | ofMesh & getPointCloud3D(); 41 | ofMesh & getUserPointCloud3D(); 42 | ofVec3f convert2dPointToSpacePoint(ofVec2f _point); 43 | ofVec2f convert2dPointToColorSpacePoint(ofVec2f _point); 44 | 45 | // Added by JAN 46 | ofPixels & getCustomDepthMap( ofRectangle cropRectangle, int frontPlaneDepth, int backPlaneDepth ); 47 | 48 | 49 | private: 50 | IKinectSensor* sensor; // Kinect sensor 51 | IMultiSourceFrameReader* reader; // Kinect data source 52 | ICoordinateMapper* mapper; // Converts between depth, color, and 3d coordinates 53 | 54 | #ifdef GESTURES 55 | vector gesturedetectors; 56 | bool initKinectGestures(DWORD enabledFrameSourceTypes,string database); 57 | #endif 58 | 59 | void prepareData(); 60 | 61 | bool initKinect(DWORD enabledFrameSourceTypes); 62 | 63 | void getDepthData(IMultiSourceFrame* frame); 64 | void getColorData(IMultiSourceFrame* frame); 65 | void getBodyData(IMultiSourceFrame* frame); 66 | void getBodyIndexData(IMultiSourceFrame* frame); 67 | 68 | //DEPTH MAP 69 | UINT16* depthmap; 70 | ofPixels_ depthpixels; // pixels with a depth of 16-bit 71 | 72 | // ADDED BY JAN 73 | ofPixels customDepthPixels; 74 | 75 | //BODY INDEX MAP 76 | BYTE* bodyindexmap; 77 | ofPixels bodyindexmappixels; 78 | ofPixels bodyindexmappixelscolormapped; 79 | 80 | //COLOR MAP 81 | ofPixels colorpixels; 82 | ofTexture colortexture; 83 | bool bUseColor; 84 | 85 | //FLOORPLANE 86 | ofVec4f floorplane; 87 | 88 | //POINTCLOUD 89 | ofMesh pointcloud; 90 | ofMesh userpointcloudmesh; 91 | 92 | vector users; 93 | vector usercolors; 94 | 95 | #ifdef USETHREAD 96 | void threadedFunction(); 97 | ofMutex locker; 98 | #endif 99 | }; 100 | 101 | // Safe release for interfaces 102 | template 103 | inline void SafeRelease(Interface *& pInterfaceToRelease) { 104 | if (pInterfaceToRelease != NULL) { 105 | pInterfaceToRelease->Release(); 106 | pInterfaceToRelease = NULL; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/utils/ncKinect2dScene.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinect2dScene.h" 2 | 3 | 4 | 5 | ofPath ncKinect2dScene::polysToPath(vector _polylines) { 6 | 7 | ofPath path; 8 | 9 | for (int i = 0; i<_polylines.size(); i++) { 10 | vector vertices = _polylines[i].getVertices(); 11 | 12 | for (int v = 0; v& _users, int _id) { 45 | id = _id; 46 | users = &_users; 47 | contourimage.allocate(512, 424); 48 | setupGUI(); 49 | loadcounter = 0; 50 | } 51 | 52 | void ncKinect2dScene::setup() { 53 | contourimage.allocate(512, 424); 54 | setupGUI(); 55 | } 56 | 57 | void ncKinect2dScene::update() { 58 | //BUG IN OFXGUIPLUS LOADING VALUES 59 | //RELOAD IT HERE THREE TIMES AS FAST AS POSSIBLE 60 | if (loadcounter < 3) { 61 | if (ofGetFrameNum() % 1 == 0) { 62 | loadcounter++; 63 | gui.loadFromFile("_settings/kinect2dscene" + ofToString(id) + ".xml"); 64 | } 65 | } 66 | } 67 | 68 | void ncKinect2dScene::drawDepthMap2d(ofPixels_ &_depthmap, int x, int y, float scale) { 69 | depthmap.setFromPixels(_depthmap); 70 | depthmap.draw(x, y, 512 * scale, 424 * scale); 71 | } 72 | 73 | void ncKinect2dScene::drawUserMap2d(ofPixels & _usermap, int x, int y) { 74 | usermap.setFromPixels(_usermap); 75 | usermap.draw(x, y); 76 | } 77 | 78 | void ncKinect2dScene::drawColorImage(ofPixels & _colorpixels, int x, int y, float scale) { 79 | colorimage.setFromPixels(_colorpixels); 80 | colorimage.draw(x, y, 1920 * scale, 1080* scale); 81 | } 82 | 83 | void ncKinect2dScene::drawContourImage(int x, int y) { 84 | contourimage.draw(x, y); 85 | } 86 | 87 | void ncKinect2dScene::drawSkeletons(int x, int y, float scale) { 88 | 89 | ofPushMatrix(); 90 | ofTranslate(x, y); 91 | ofScale(scale, scale); 92 | for (size_t i = 0; i < users->size(); i++) { 93 | 94 | ofSetColor((*users)[i]->color); 95 | for (size_t k = 0; k < (*users)[i]->joints2dposition.size(); k++) { 96 | ofDrawCircle((*users)[i]->joints2dposition[k], 5); 97 | } 98 | ofSetColor(255); 99 | } 100 | ofPopMatrix(); 101 | } 102 | 103 | void ncKinect2dScene::drawContourLines(ofPixels & _usermap, int x, int y) { 104 | ofSetLineWidth(3); 105 | ofSetColor(ofColor::chartreuse); 106 | vector cont = getContours(_usermap); 107 | for (size_t i = 0; i < cont.size(); i++) { 108 | cont[i].draw(); 109 | ofDrawCircle(cont[i].getCentroid2D(), 5); 110 | } 111 | ofSetLineWidth(1); 112 | ofSetColor(255); 113 | } 114 | 115 | void ncKinect2dScene::drawFilledContours(ofPixels & _usermap, int x, int y, float scale) { 116 | 117 | ofPushMatrix(); 118 | ofTranslate(x, y); 119 | ofScale(scale, scale); 120 | ncKinect2dScene::polysToPath(getContours(_usermap)).draw(0, 0); 121 | ofPopMatrix(); 122 | } 123 | 124 | void ncKinect2dScene::drawGUI() { 125 | gui.draw(); 126 | } 127 | 128 | vector ncKinect2dScene::getContours(ofPixels & _usermap) { 129 | contourimage.setFromPixels(_usermap); 130 | if (bDoBlur) { 131 | contourimage.blurGaussian(bluramount); 132 | } 133 | 134 | if (dilatefirst) { 135 | 136 | for (size_t i = 0; i < dilatecount; i++) { 137 | contourimage.dilate(); 138 | } 139 | 140 | for (size_t i = 0; i < erodecount; i++) { 141 | contourimage.erode(); 142 | } 143 | } 144 | else { 145 | 146 | for (size_t i = 0; i < erodecount; i++) { 147 | contourimage.erode(); 148 | } 149 | 150 | for (size_t i = 0; i < dilatecount; i++) { 151 | contourimage.dilate(); 152 | } 153 | } 154 | 155 | contourfinder.findContours(contourimage, 1000, (_usermap.getWidth() * _usermap.getHeight()) / 2, 6, false); 156 | 157 | vector contourlines; 158 | contourlines.clear(); 159 | 160 | for (int i = 0; i < contourfinder.nBlobs; ++i) { 161 | 162 | ofPolyline cline; 163 | for (int j = 0; j < contourfinder.blobs[i].pts.size(); ++j) { 164 | cline.addVertex(contourfinder.blobs[i].pts[j]); 165 | } 166 | cline.close(); 167 | 168 | if (bDoResample) { 169 | ofPolyline c = cline.getResampledByCount(resamplecount); 170 | contourlines.push_back(c); 171 | } 172 | else { 173 | contourlines.push_back(cline); 174 | } 175 | } 176 | 177 | for (int i = 0; i<(int)contourlines.size(); i++) { 178 | glm::vec2 center = contourlines[i].getCentroid2D(); 179 | ofPoint centerdd = contourlines[i].getCentroid2D(); 180 | ofPoint centerd = centerdd *scalecontour; 181 | 182 | glm::vec2 diff = center - centerd; 183 | for (int j = 0; j<(int)contourlines[i].size(); j++) { 184 | contourlines[i][j].x *= scalecontour; 185 | contourlines[i][j].y *= scalecontour; 186 | contourlines[i][j].x += diff.x; 187 | contourlines[i][j].y += diff.y; 188 | } 189 | } 190 | return contourlines; 191 | } 192 | 193 | vector ncKinect2dScene::getBoundingBoxes(ofPixels & _usermap) 194 | { 195 | 196 | contourimage.setFromPixels(_usermap); 197 | if (bDoBlur) { 198 | contourimage.blurGaussian(bluramount); 199 | } 200 | 201 | if (dilatefirst) { 202 | 203 | for (size_t i = 0; i < dilatecount; i++) { 204 | contourimage.dilate(); 205 | } 206 | 207 | for (size_t i = 0; i < erodecount; i++) { 208 | contourimage.erode(); 209 | } 210 | } 211 | else { 212 | 213 | for (size_t i = 0; i < erodecount; i++) { 214 | contourimage.erode(); 215 | } 216 | 217 | for (size_t i = 0; i < dilatecount; i++) { 218 | contourimage.dilate(); 219 | } 220 | } 221 | 222 | contourfinder.findContours(contourimage, 1000, (_usermap.getWidth() * _usermap.getHeight()) / 2, 6, false); 223 | vector rectangles; 224 | for (int i = 0; i < contourfinder.nBlobs; ++i) { 225 | rectangles.push_back(contourfinder.blobs[i].boundingRect); 226 | } 227 | 228 | return rectangles; 229 | } 230 | 231 | vector ncKinect2dScene::getBoundingBoxesSeparateBodyIndex() 232 | { 233 | vector rectangles; 234 | 235 | for (size_t i = 0; i < users->size(); i++) { 236 | contourimage.setFromPixels((*users)[i]->userpixels); 237 | contourfinder.findContours(contourimage, 5000, ((*users)[i]->userpixels.getWidth() * (*users)[i]->userpixels.getHeight()) / 2, 6, false); 238 | 239 | for (int i = 0; i < contourfinder.nBlobs; ++i) { 240 | rectangles.push_back(contourfinder.blobs[i].boundingRect); 241 | } 242 | 243 | } 244 | return rectangles; 245 | } 246 | ofPath ncKinect2dScene::getFilledContours(ofPixels & _usermap) { 247 | return ncKinect2dScene::polysToPath(getContours(_usermap)); 248 | } 249 | -------------------------------------------------------------------------------- /src/utils/ncKinect2dScene.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "ofMain.h" 5 | #include "ncKinectUser.h" 6 | #include "ncKinectCamera.h" 7 | #include "ofxOpenCv.h" 8 | #include "ofxGui.h" 9 | 10 | class ncKinect2dScene { 11 | 12 | private: 13 | vector * users; 14 | ofImage depthmap; 15 | ofImage usermap; 16 | ofImage colorimage; 17 | 18 | ofxCvContourFinder contourfinder; 19 | ofxCvGrayscaleImage contourimage; 20 | 21 | ofxPanel gui; 22 | ofParameter bDoBlur; 23 | ofParameter bluramount; 24 | ofParameter scalecontour; 25 | ofParameter bDoResample; 26 | ofParameter resamplecount; 27 | ofParameter erodecount; 28 | ofParameter dilatecount; 29 | ofParameter dilatefirst; 30 | void setupGUI(); 31 | int id; 32 | int loadcounter; 33 | 34 | public: 35 | ~ncKinect2dScene(); 36 | ncKinect2dScene(); 37 | 38 | static ofPath polysToPath(vector _polylines); 39 | 40 | void setup(vector &_users, int _id = 0); 41 | void setup(); 42 | void update(); 43 | void drawDepthMap2d(ofPixels_ &_depthmap, int x = 0, int y = 0, float scale = 1); 44 | void drawUserMap2d(ofPixels &_usermap, int x = 0, int y = 0); 45 | void drawColorImage(ofPixels &_colorpixels, int x = 0, int y = 0, float scale = 1); 46 | void drawContourImage(int x = 0, int y = 0); 47 | void drawSkeletons(int x = 0, int y = 0, float scale = 1); 48 | void drawContourLines(ofPixels &_usermap, int x = 0, int y = 0); 49 | void drawFilledContours(ofPixels &_usermap, int x = 0, int y = 0, float scale = 1); 50 | void drawGUI(); 51 | 52 | //GETTERS 53 | vector getContours(ofPixels & _usermap); 54 | vector getBoundingBoxes(ofPixels & _usermap); 55 | vector getBoundingBoxesSeparateBodyIndex(); 56 | ofPath getFilledContours(ofPixels & _usermap); 57 | 58 | 59 | }; -------------------------------------------------------------------------------- /src/utils/ncKinect3dScene.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinect3dScene.h" 2 | 3 | ncKinect3dScene ::~ncKinect3dScene() { 4 | 5 | } 6 | 7 | ncKinect3dScene::ncKinect3dScene() { 8 | 9 | } 10 | 11 | 12 | void ncKinect3dScene::setupGUI() { 13 | gui.setup("3d scene", "_settings/kinect3dscene.xml"); 14 | gui.add(bDrawGrid.set("draw grid", true)); 15 | gui.add(bDrawFullPointCloud.set("draw pointcloud", true)); 16 | gui.add(bDrawUsersPointCloud.set("draw users pointcloud", true)); 17 | gui.add(bDrawSkeletons.set("draw users skeletons", true)); 18 | 19 | gui.add(bFreeCam.set("set cam free", true)); 20 | gui.add(bLeft.set("set cam left", false)); 21 | gui.add(bRight.set("set cam right", false)); 22 | gui.add(bTop.set("set cam top", false)); 23 | gui.add(bBottom.set("set cam bottom", false)); 24 | gui.add(bFront.set("set cam front", false)); 25 | gui.add(bBack.set("set cam back", false)); 26 | 27 | gui.loadFromFile("_settings/kinect3dscene.xml"); 28 | 29 | bFreeCam.addListener(this, &ncKinect3dScene::freecamChanged); 30 | bLeft.addListener(this, &ncKinect3dScene::leftcamChanged); 31 | bRight.addListener(this, &ncKinect3dScene::rightcamChanged); 32 | bTop.addListener(this, &ncKinect3dScene::topcamChanged); 33 | bBottom.addListener(this, &ncKinect3dScene::bottomcamChanged); 34 | bFront.addListener(this, &ncKinect3dScene::frontcamChanged); 35 | bBack.addListener(this, &ncKinect3dScene::backcamChanged); 36 | 37 | 38 | } 39 | 40 | void ncKinect3dScene::setup(ncKinectv2Core & _core, ncKinectUserManager & _usermanager, nCKinectCamera & _camera) { 41 | 42 | kinectcore = &_core; 43 | kinectusermanager = &_usermanager; 44 | kinectcamera = &_camera; 45 | 46 | setupGUI(); 47 | 48 | cam.setDistance(1); 49 | cam.setNearClip(0.01); 50 | } 51 | 52 | 53 | void ncKinect3dScene::draw() { 54 | 55 | 56 | if (bFreeCam) { 57 | cam.begin(); 58 | } 59 | else { 60 | cam2d.begin(); 61 | } 62 | 63 | ofEnableDepthTest(); 64 | 65 | if (bDrawGrid) { 66 | ofSetColor(0, 0, 0, 100); 67 | drawGridOneColor(1, 5, true, true, true, false); 68 | ofSetColor(255); 69 | } 70 | 71 | kinectcamera->begin(); 72 | 73 | if (bDrawFullPointCloud) { 74 | 75 | if (kinectcore->getColorTexture().getWidth()>0) { 76 | kinectcore->getColorTexture().bind(); 77 | } 78 | kinectcore->getPointCloud3D().draw(); 79 | if (kinectcore->getColorTexture().getWidth()>0) { 80 | kinectcore->getColorTexture().unbind(); 81 | } 82 | 83 | } 84 | 85 | if (bDrawUsersPointCloud) { 86 | drawUserPointcloud(); 87 | } 88 | 89 | if (bDrawSkeletons) { 90 | drawUserSkeletons(); 91 | } 92 | 93 | kinectcamera->end(); 94 | 95 | ofDisableDepthTest(); 96 | 97 | if (bFreeCam) { 98 | cam.end(); 99 | } 100 | else { 101 | cam2d.end(); 102 | } 103 | 104 | } 105 | 106 | void ncKinect3dScene::drawGUI() { 107 | gui.draw(); 108 | kinectcamera->drawGUI(); 109 | } 110 | 111 | void ncKinect3dScene::drawUserPointcloud() { 112 | 113 | kinectcore->getUserPointCloud3D().draw(); 114 | } 115 | 116 | void ncKinect3dScene::drawUserSkeletons() 117 | { 118 | for (size_t i = 0; i getUsers().size(); i++) { 119 | 120 | kinectusermanager->getUsers()[i]->setBoneColor(kinectusermanager->getUsers()[i]->color); 121 | 122 | for (size_t k = 0; k getUsers()[i]->bones3D.size(); k++) { 123 | 124 | kinectusermanager->getUsers()[i]->bones3D[k].draw(); 125 | 126 | } 127 | 128 | for (size_t k = 0; k getUsers()[i]->bonesVanity3D.size(); k++) { 129 | 130 | kinectusermanager->getUsers()[i]->bonesVanity3D[k].draw(); 131 | 132 | } 133 | } 134 | } 135 | 136 | 137 | //-------------------------------------------------------------- 138 | void ncKinect3dScene::drawGridOneColor(float stepSize, size_t numberOfSteps, bool labels, bool x, bool y, bool z) { 139 | 140 | if (x) { 141 | ofDrawGridPlane(stepSize, numberOfSteps, labels); 142 | } 143 | if (y) { 144 | ofMatrix4x4 m; 145 | m.makeRotationMatrix(90, 0, 0, -1); 146 | ofPushMatrix(); 147 | ofMultMatrix(m); 148 | ofDrawGridPlane(stepSize, numberOfSteps, labels); 149 | ofPopMatrix(); 150 | } 151 | if (z) { 152 | ofMatrix4x4 m; 153 | m.makeRotationMatrix(90, 0, 1, 0); 154 | ofPushMatrix(); 155 | ofMultMatrix(m); 156 | ofDrawGridPlane(stepSize, numberOfSteps, labels); 157 | ofPopMatrix(); 158 | } 159 | 160 | if (labels) { 161 | float labelPos = stepSize * (numberOfSteps + 0.5); 162 | //ofSetBitmapTextMode(OF_BITMAPMODE_MODEL_BILLBOARD); 163 | ofDrawBitmapString("x", labelPos, 0, 0); 164 | ofDrawBitmapString("y", 0, labelPos, 0); 165 | ofDrawBitmapString("z", 0, 0, labelPos); 166 | } 167 | } 168 | 169 | void ncKinect3dScene::freecamChanged(bool & val) { 170 | if (val) { 171 | bFront = false; 172 | bBack = false; 173 | bLeft = false; 174 | bRight = false; 175 | bBottom = false; 176 | bTop = false; 177 | } 178 | } 179 | 180 | void ncKinect3dScene::topcamChanged(bool & val) 181 | { 182 | if (val) { 183 | bFreeCam = false; 184 | bFront = false; 185 | bBack = false; 186 | bLeft = false; 187 | bRight = false; 188 | bBottom = false; 189 | 190 | cam2d.setFlipY(true); 191 | cam2d.setLookAt(ofxInfiniteCanvas::OFX2DCAM_TOP); 192 | cam2d.setScale(200); 193 | cam2d.setTranslation(ofVec3f(ofGetWidth() / 2, ofGetHeight() / 2, 0)); 194 | } 195 | } 196 | 197 | void ncKinect3dScene::bottomcamChanged(bool & val) 198 | { 199 | if (val) { 200 | bFreeCam = false; 201 | bFront = false; 202 | bBack = false; 203 | bLeft = false; 204 | bRight = false; 205 | bTop = false; 206 | cam2d.setFlipY(true); 207 | cam2d.setLookAt(ofxInfiniteCanvas::OFX2DCAM_BOTTOM); 208 | cam2d.setScale(200); 209 | cam2d.setTranslation(ofVec3f(ofGetWidth() / 2, ofGetHeight() / 2, 0)); 210 | } 211 | } 212 | 213 | void ncKinect3dScene::leftcamChanged(bool & val) 214 | { 215 | if (val) { 216 | bFreeCam = false; 217 | bFront = false; 218 | bBack = false; 219 | bRight = false; 220 | bBottom = false; 221 | bTop = false; 222 | cam2d.setFlipY(true); 223 | cam2d.setLookAt(ofxInfiniteCanvas::OFX2DCAM_LEFT); 224 | cam2d.setScale(200); 225 | cam2d.setTranslation(ofVec3f(ofGetWidth() / 2, ofGetHeight() / 2, 0)); 226 | } 227 | } 228 | 229 | void ncKinect3dScene::rightcamChanged(bool & val) 230 | { 231 | if (val) { 232 | bFreeCam = false; 233 | bFront = false; 234 | bBack = false; 235 | bLeft = false; 236 | bBottom = false; 237 | bTop = false; 238 | cam2d.setFlipY(true); 239 | cam2d.setLookAt(ofxInfiniteCanvas::OFX2DCAM_RIGHT); 240 | cam2d.setScale(200); 241 | cam2d.setTranslation(ofVec3f(ofGetWidth() / 2, ofGetHeight() / 2, 0)); 242 | } 243 | } 244 | 245 | void ncKinect3dScene::frontcamChanged(bool & val) 246 | { 247 | if (val) { 248 | bFreeCam = false; 249 | bBack = false; 250 | bLeft = false; 251 | bRight = false; 252 | bBottom = false; 253 | bTop = false; 254 | cam2d.setFlipY(true); 255 | cam2d.setLookAt(ofxInfiniteCanvas::OFX2DCAM_FRONT); 256 | cam2d.setScale(200); 257 | cam2d.setTranslation(ofVec3f(ofGetWidth() / 2, ofGetHeight() / 2, 0)); 258 | } 259 | } 260 | 261 | void ncKinect3dScene::backcamChanged(bool & val) { 262 | if (val) { 263 | bFreeCam = false; 264 | bFront = false; 265 | bLeft = false; 266 | bRight = false; 267 | bBottom = false; 268 | bTop = false; 269 | cam2d.setFlipY(true); 270 | cam2d.setLookAt(ofxInfiniteCanvas::OFX2DCAM_BACK); 271 | cam2d.setScale(200); 272 | cam2d.setTranslation(ofVec3f(ofGetWidth() / 2, ofGetHeight() / 2, 0)); 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /src/utils/ncKinect3dScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxInfiniteCanvas.h" 5 | #include "ncKinectv2Core.h" 6 | #include "ncKinectCamera.h" 7 | #include "ncKinectUserManager.h" 8 | #include "ofxGui.h" 9 | 10 | class ncKinect3dScene :public ofNode { 11 | 12 | private: 13 | 14 | ofxPanel gui; 15 | ofParameter bDrawGrid; 16 | ofParameter bDrawFullPointCloud; 17 | ofParameter bDrawUsersPointCloud; 18 | ofParameter bDrawSkeletons; 19 | 20 | ofParameter bFreeCam; 21 | ofParameter bFront; 22 | ofParameter bBack; 23 | ofParameter bLeft; 24 | ofParameter bRight; 25 | ofParameter bBottom; 26 | ofParameter bTop; 27 | 28 | void freecamChanged(bool &val); 29 | void topcamChanged(bool &val); 30 | void bottomcamChanged(bool &val); 31 | void leftcamChanged(bool &val); 32 | void rightcamChanged(bool &val); 33 | void frontcamChanged(bool &val); 34 | void backcamChanged(bool &val); 35 | 36 | void setupGUI(); 37 | 38 | ofEasyCam cam; 39 | ofxInfiniteCanvas cam2d; 40 | void drawGridOneColor(float stepSize, size_t numberOfSteps, bool labels, bool x = true, bool y = true, bool z = true); 41 | 42 | ncKinectv2Core *kinectcore; 43 | ncKinectUserManager *kinectusermanager; 44 | nCKinectCamera *kinectcamera; 45 | 46 | 47 | public: 48 | 49 | ~ncKinect3dScene(); 50 | ncKinect3dScene(); 51 | 52 | void setup(ncKinectv2Core &_core, ncKinectUserManager &_usermanager, nCKinectCamera &_camera); 53 | void draw(); 54 | void drawGUI(); 55 | 56 | void drawUserPointcloud(); 57 | void drawUserSkeletons(); 58 | }; -------------------------------------------------------------------------------- /src/utils/ncKinectAreaManager.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectAreaManager.h" 2 | 3 | 4 | 5 | ncKinectAreaManager::~ncKinectAreaManager() { 6 | 7 | } 8 | 9 | ncKinectAreaManager::ncKinectAreaManager() { 10 | 11 | } 12 | 13 | void ncKinectAreaManager::setup() { 14 | loadcounter = 0; 15 | setupGUI(); 16 | setKinectFrustrum(); 17 | setInteractionSpace(); 18 | floorplane.set(10, 10); 19 | 20 | for (size_t i = 0; i < floorplane.getMesh().getNumVertices(); i++) { 21 | floorplane.getMesh().addColor(ofFloatColor(0,1,0,1)); 22 | } 23 | } 24 | 25 | void ncKinectAreaManager::update() { 26 | 27 | if (loadcounter < 3) { 28 | if (ofGetFrameNum() % 15 == 0) { 29 | loadcounter++; 30 | gui.loadFromFile("_settings/area.xml"); 31 | } 32 | } 33 | 34 | } 35 | 36 | void ncKinectAreaManager::updatePositionRotation(glm::vec3 _pos, ofQuaternion _rot) { 37 | 38 | kinectdepthfrustrum.setPosition(_pos); 39 | kinectdepthfrustrum.setOrientation(_rot); 40 | interactionspace.setPosition(glm::vec3(_pos.x, interactionspace.getPosition().y, _pos.z)); 41 | 42 | } 43 | 44 | void ncKinectAreaManager::setupGUI() { 45 | gui.setup("Kinect Area", "_settings/area.xml"); 46 | gui.add(kinectspacedepth.set("kinect depth", 4.5, 0.5, 8)); 47 | gui.add(interactionspacewidth.set("interac width", 1.5, 0, 10)); 48 | gui.add(interactionspacedepth.set("interac depth", 2, 0, 10)); 49 | gui.add(bDrawDepthFrustrum.set("draw depth fr", true)); 50 | gui.add(bDrawInteractionSpace.set("draw inter sp", true)); 51 | kinectspacedepth.addListener(this, &ncKinectAreaManager::kinectSpaceDepthChanged); 52 | interactionspacewidth.addListener(this, &ncKinectAreaManager::interactionSpaceWidthChanged); 53 | interactionspacedepth.addListener(this, &ncKinectAreaManager::interactionSpaceDepthChanged); 54 | 55 | 56 | gui.loadFromFile("_settings/area.xml"); 57 | 58 | gui.setPosition(10, 350); 59 | } 60 | 61 | void ncKinectAreaManager::setKinectFrustrum() { 62 | kinectdepthfrustrum.create(60, 512.0f / 424.0f, kinectspacedepth); 63 | } 64 | 65 | void ncKinectAreaManager::setInteractionSpace() { 66 | interactionspace.create(ofVec2f(interactionspacewidth*2, interactionspacedepth)); 67 | } 68 | 69 | void ncKinectAreaManager::kinectSpaceDepthChanged(float & arg) { 70 | setKinectFrustrum(); 71 | } 72 | 73 | void ncKinectAreaManager::interactionSpaceDepthChanged(float & arg) { 74 | setInteractionSpace(); 75 | } 76 | 77 | void ncKinectAreaManager::interactionSpaceWidthChanged(float & arg) { 78 | setInteractionSpace(); 79 | } 80 | 81 | void ncKinectAreaManager::draw() { 82 | 83 | if (bDrawDepthFrustrum) { 84 | kinectdepthfrustrum.draw(); 85 | } 86 | 87 | if (bDrawInteractionSpace) { 88 | interactionspace.draw(); 89 | } 90 | 91 | ofPushMatrix(); 92 | ofRotate(90, 1, 0, 0); 93 | ///floorplane.draw(); 94 | ofRotate(90, 0, 1, 0); 95 | ofSetColor(ofColor::lawnGreen); 96 | ofDrawGridPlane(1, 5); 97 | ofSetColor(255); 98 | ofPopMatrix(); 99 | } 100 | 101 | void ncKinectAreaManager::drawGUI() { 102 | gui.draw(); 103 | } 104 | 105 | bool ncKinectAreaManager::isUserInInteractionSpace(glm::vec3 _pos) { 106 | return interactionspace.isPointInsideInteractionSpace(_pos); 107 | } 108 | 109 | bool ncKinectAreaManager::isUserInInteractionSpace(ncKinectUser _user) { 110 | return isUserInInteractionSpace(_user.joints3dposition[ncJointType_SpineBase]); 111 | } 112 | 113 | bool ncKinectAreaManager::isThereAUserInInteractiveSpace(vector _users) { 114 | 115 | for (size_t i = 0; i < _users.size(); i++) { 116 | if (isUserInInteractionSpace(_users[i])) { 117 | return true; 118 | } 119 | } 120 | 121 | return false; 122 | } 123 | 124 | vector ncKinectAreaManager::returnUsersInInteractionspace(vector _users) { 125 | vector userstoreturn; 126 | for (size_t i = 0; i < _users.size(); i++) { 127 | if (isUserInInteractionSpace(_users[i])) { 128 | userstoreturn.push_back(_users[i]); 129 | } 130 | } 131 | return userstoreturn; 132 | } 133 | 134 | int ncKinectAreaManager::returnClosestUserInInteractionSpace(vector _users) { 135 | vector usersfor = returnUsersInInteractionspace(_users); 136 | 137 | vector < vector > userst; 138 | 139 | 140 | for (size_t i = 0; i < usersfor.size(); i++) { 141 | vector user; 142 | user.push_back(usersfor[i].id); 143 | user.push_back(usersfor[i].joints3dposition[ncJointType_SpineBase].z); 144 | userst.push_back(user); 145 | } 146 | 147 | 148 | std::sort(userst.begin(), userst.end(), 149 | [](const std::vector& a, const std::vector& b) { 150 | return a[1] < b[1]; 151 | }); 152 | 153 | if (userst.size() > 0) { 154 | return userst[0][0]; 155 | } 156 | 157 | return -1; 158 | } 159 | -------------------------------------------------------------------------------- /src/utils/ncKinectAreaManager.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "ofMain.h" 5 | #include "ofxGui.h" 6 | #include "ncKinectUser.h" 7 | 8 | class ncKinectInteractionSpace :public ofNode { 9 | 10 | public: 11 | 12 | ofMesh mesh; 13 | 14 | ofMesh userselectmesh; 15 | 16 | glm::vec3 uppercorner; 17 | glm::vec3 lowercorner; 18 | 19 | bool isPointInsideInteractionSpace(glm::vec3 &_point) { 20 | 21 | glm::vec3 newlower = lowercorner + getPosition(); 22 | glm::vec3 newhigher = uppercorner + getPosition(); 23 | 24 | if (_point.x > newlower.x && _point.x < newhigher.x && 25 | _point.y > newlower.y && _point.y newlower.z && _point.z distanceabovezero) { 77 | uppercorner = vertex; 78 | distanceabovezero = distance; 79 | } 80 | //check higestdistance below 0 81 | if (distance < distanceunderzero) { 82 | lowercorner = vertex; 83 | distanceunderzero = distance; 84 | } 85 | } 86 | 87 | } 88 | 89 | void draw() { 90 | transformGL(); 91 | mesh.drawWireframe(); 92 | restoreTransformGL(); 93 | } 94 | 95 | }; 96 | 97 | 98 | class ncKinectDepthFrustrum :public ofNode { 99 | 100 | public: 101 | 102 | ofPlanePrimitive plane; 103 | ofMesh mesh; 104 | void create(float fov, float aspectratio, float throwdistance) { 105 | 106 | mesh.clear(); 107 | 108 | float frustumHeight = 2.0f * throwdistance* tan(fov * 0.5f * (PI / 180)); 109 | float frustrumWidth = frustumHeight * (aspectratio); 110 | 111 | plane.set(frustrumWidth, frustumHeight); 112 | plane.setPosition(0, 0, -throwdistance); 113 | 114 | 115 | glm::vec3 v0 = glm::vec3(0, 0, 0); 116 | glm::vec3 v1 = glm::vec3(plane.getWidth() / 2.0f, plane.getHeight() / 2.0f, -throwdistance); 117 | glm::vec3 v2 = glm::vec3(-plane.getWidth() / 2.0f, plane.getHeight() / 2.0f, -throwdistance); 118 | glm::vec3 v3 = glm::vec3(plane.getWidth() / 2.0f, -plane.getHeight() / 2.0f, -throwdistance); 119 | glm::vec3 v4 = glm::vec3(-plane.getWidth() / 2.0f, -plane.getHeight() / 2.0f, -throwdistance); 120 | 121 | ofFloatColor color = ofFloatColor(1.0,0.0,0.0,1); 122 | vector vertices; 123 | vector colors; 124 | vertices.push_back(v0); 125 | colors.push_back(color); 126 | vertices.push_back(v1); 127 | colors.push_back(color); 128 | vertices.push_back(v2); 129 | colors.push_back(color); 130 | vertices.push_back(v3); 131 | colors.push_back(color); 132 | vertices.push_back(v4); 133 | colors.push_back(color); 134 | vertices.push_back(v0); 135 | colors.push_back(color); 136 | vertices.push_back(v1); 137 | colors.push_back(color); 138 | vertices.push_back(v2); 139 | colors.push_back(color); 140 | vertices.push_back(v3); 141 | colors.push_back(color); 142 | vertices.push_back(v4); 143 | colors.push_back(color); 144 | 145 | mesh.addVertices(vertices); 146 | mesh.addColors(colors); 147 | 148 | mesh.addTriangle(0, 1, 2); 149 | mesh.addTriangle(0, 1, 3); 150 | mesh.addTriangle(0, 2, 4); 151 | mesh.addTriangle(0, 3, 4); 152 | mesh.addTriangle(1, 2, 4); 153 | mesh.addTriangle(4, 1, 3); 154 | 155 | mesh.addTriangle(0, 1, 2); 156 | mesh.addTriangle(0, 1, 3); 157 | mesh.addTriangle(0, 2, 4); 158 | mesh.addTriangle(0, 3, 4); 159 | mesh.addTriangle(1, 2, 4); 160 | mesh.addTriangle(4, 1, 3); 161 | 162 | 163 | glm::vec3 n0 = glm::vec3(0, 0, 1); 164 | glm::vec3 n1 = glm::vec3(0, 0, 1); 165 | glm::vec3 n2 = glm::vec3(0, 0, 1); 166 | glm::vec3 n3 = glm::vec3(0, 0, 1); 167 | glm::vec3 n4 = glm::vec3(0, 0, 1); 168 | 169 | glm::vec3 n5 = glm::vec3(0, 0, -1); 170 | glm::vec3 n6 = glm::vec3(0, 0, -1); 171 | glm::vec3 n7 = glm::vec3(0, 0, -1); 172 | glm::vec3 n8 = glm::vec3(0, 0, -1); 173 | glm::vec3 n9 = glm::vec3(0, 0, -1); 174 | 175 | 176 | vector normals; 177 | normals.push_back(n0); 178 | normals.push_back(n1); 179 | normals.push_back(n2); 180 | normals.push_back(n3); 181 | normals.push_back(n4); 182 | normals.push_back(n5); 183 | normals.push_back(n6); 184 | normals.push_back(n7); 185 | normals.push_back(n8); 186 | normals.push_back(n9); 187 | 188 | mesh.addNormals(normals); 189 | 190 | } 191 | 192 | void draw() { 193 | transformGL(); 194 | mesh.drawWireframe(); 195 | restoreTransformGL(); 196 | 197 | } 198 | }; 199 | 200 | 201 | class ncKinectAreaManager { 202 | 203 | private: 204 | //GUI 205 | ofxPanel gui; 206 | ofParameter kinectspacedepth; 207 | ofParameter interactionspacewidth; 208 | ofParameter interactionspacedepth; 209 | ofParameter bDrawDepthFrustrum; 210 | ofParameter bDrawInteractionSpace; 211 | 212 | void setupGUI(); 213 | 214 | void setKinectFrustrum(); 215 | void setInteractionSpace(); 216 | 217 | ncKinectDepthFrustrum kinectdepthfrustrum; 218 | ncKinectInteractionSpace interactionspace; 219 | 220 | void kinectSpaceDepthChanged(float &arg); 221 | void interactionSpaceDepthChanged(float &arg); 222 | void interactionSpaceWidthChanged(float &arg); 223 | 224 | ofPlanePrimitive floorplane; 225 | 226 | int loadcounter; 227 | 228 | public: 229 | ~ncKinectAreaManager(); 230 | ncKinectAreaManager(); 231 | 232 | 233 | void setup(); 234 | void update(); 235 | void updatePositionRotation(glm::vec3 _pos, ofQuaternion _rot); 236 | 237 | void draw(); 238 | void drawGUI(); 239 | 240 | bool isUserInInteractionSpace(glm::vec3 _pos); 241 | bool isUserInInteractionSpace(ncKinectUser _user); 242 | bool isThereAUserInInteractiveSpace(vector _users); 243 | vector returnUsersInInteractionspace(vector _users); 244 | int returnClosestUserInInteractionSpace(vector _users); 245 | 246 | 247 | }; -------------------------------------------------------------------------------- /src/utils/ncKinectPCTriangulator.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectPCTriangulator.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ncKinectPCTriangulator::setup(vector &_users, ncKinectv2Core &_core,nCKinectCamera &_camera, ofPixels &_usermap, ofMesh & _pointcloud,int _id) { 5 | 6 | id = _id; 7 | users = &_users; 8 | kinectcamera = &_camera; 9 | usermap = &_usermap; 10 | pointcloud = &_pointcloud; 11 | core = &_core; 12 | 13 | kinect2sscene.setup(*users,id); 14 | 15 | cam.setDistance(5); 16 | cam.setNearClip(0.01); 17 | 18 | gui.setup("Mesh Triangulator"+ofToString(_id), "_settings/triangulator"+ofToString(_id)+".xml"); 19 | gui.add(bDrawGrid.set("draw grid", true)); 20 | gui.add(bRotate.set("rotate", true)); 21 | gui.add(bClampPosition.set("clamp position", true)); 22 | gui.add(colorblend.set("color blend", 0.5,0,1)); 23 | gui.add(bDoPointCloud.set("point cloud", false)); 24 | gui.add(pointSize.set("point size",1,1,10)); 25 | gui.add(bDrawContours.set("draw debug contours", true)); 26 | 27 | gui.setPosition(250, 10); 28 | 29 | gui.loadFromFile("_settings/triangulator"+ofToString(id)+".xml"); 30 | 31 | //MESH STUFF 32 | sampleSize = 2; 33 | 34 | depthWidth = 512; 35 | depthHeight = 424; 36 | 37 | sampledWidth = depthWidth / sampleSize; 38 | sampledHeight = depthHeight / sampleSize; 39 | 40 | 41 | ofFbo::Settings settings; 42 | settings.internalformat = GL_LUMINANCE; 43 | settings.useDepth = false; 44 | settings.width = 512; 45 | settings.height = 424; 46 | 47 | silhouettebuffer.allocate(settings); 48 | silhouettespixels.allocate(512, 424, OF_IMAGE_GRAYSCALE); 49 | 50 | vCount = 0; 51 | tCount = 0; 52 | //startThread(); 53 | } 54 | 55 | //-------------------------------------------------------------- 56 | void ncKinectPCTriangulator::update() { 57 | kinect2sscene.update(); 58 | silhouettebuffer.begin(); 59 | ofClear(0, 0, 0, 255); 60 | kinect2sscene.drawFilledContours(*usermap); 61 | silhouettebuffer.end(); 62 | silhouettebuffer.readToPixels(silhouettespixels); 63 | 64 | estimateUserVertices(vCount, tCount); 65 | 66 | usermesh.clear(); 67 | 68 | 69 | int index = 0, vIndex = 0, tIndex = 0, xyIndex = 0; 70 | 71 | vertices.resize(vCount); 72 | triangles.resize(6 * tCount); 73 | uvs.resize(vCount); 74 | vector colors; 75 | colors.resize(vCount); 76 | 77 | for (int y = 0; y < depthHeight; y += sampleSize) { 78 | int xyStartIndex = xyIndex; 79 | 80 | for (int x = 0; x < depthWidth; x += sampleSize) { 81 | 82 | glm::vec3 vSpacePos = pointcloud->getVertex(xyIndex); 83 | 84 | if (vertexType[index] != 0 && !isinf(vSpacePos.x) && !isinf(vSpacePos.y) && !isinf(vSpacePos.z)) { 85 | 86 | ofVec2f colorPoint = core->convert2dPointToColorSpacePoint(glm::vec2(x, y)); 87 | // Set Color to Point 88 | int colorX = static_cast(colorPoint.x + 0.5f); 89 | int colorY = static_cast(colorPoint.y + 0.5f); 90 | 91 | ofColor col; 92 | 93 | if ((0 <= colorX) && (colorX < 1920) && (0 <= colorY) && (colorY < 1080)) { 94 | col = core->getColorPixels().getColor(colorX, colorY); 95 | ofColor bcolor(ofColor::blueSteel); 96 | col.lerp(bcolor, colorblend); 97 | colors[vIndex] = col; 98 | } 99 | 100 | 101 | vertices[vIndex] = vSpacePos; 102 | uvs[vIndex] = ofVec2f((float)x / depthWidth, (float)y / depthHeight); 103 | vIndex++; 104 | 105 | if (vertexType[index] == 3) { 106 | 107 | triangles[tIndex++] = vertexIndex[index]; // top left 108 | triangles[tIndex++] = vertexIndex[index + 1]; // top right 109 | triangles[tIndex++] = vertexIndex[index + sampledWidth]; // bottom left 110 | 111 | triangles[tIndex++] = vertexIndex[index + sampledWidth]; // bottom left 112 | triangles[tIndex++] = vertexIndex[index + 1]; // top right 113 | triangles[tIndex++] = vertexIndex[index + sampledWidth + 1]; // bottom right 114 | 115 | } 116 | } 117 | 118 | index++; 119 | xyIndex += sampleSize; 120 | } 121 | xyIndex = xyStartIndex + sampleSize * depthWidth; 122 | 123 | } 124 | usermesh.addTexCoords(uvs); 125 | usermesh.addVertices(vertices); 126 | usermesh.addIndices(triangles); 127 | usermesh.addColors(colors); 128 | ofxMeshUtils::calcNormals(usermesh); 129 | } 130 | 131 | //-------------------------------------------------------------- 132 | void ncKinectPCTriangulator::draw() { 133 | if (bDrawContours) { 134 | kinect2sscene.drawUserMap2d(*usermap, 0, 0); 135 | kinect2sscene.drawContourLines(*usermap, 512, 0); 136 | 137 | silhouetteimage.setFromPixels(silhouettespixels); 138 | silhouetteimage.draw(512, 0); 139 | } 140 | cam.begin(); 141 | ofEnableDepthTest(); 142 | 143 | if (bDrawGrid) { 144 | if (bRotate) { 145 | ofPushMatrix(); 146 | ofRotate(ofGetFrameNum()*0.3, 0, 1, 0); 147 | } 148 | ofSetColor(ofColor::pink, 150); 149 | drawGridOneColor(0.5, 10, false, false, true, false); 150 | ofSetColor(255); 151 | if (bRotate) { 152 | ofPopMatrix(); 153 | } 154 | } 155 | 156 | kinectcamera->begin(); 157 | 158 | if (bDoPointCloud) { 159 | glPointSize(pointSize); 160 | usermesh.drawVertices(); 161 | glPointSize(1); 162 | } 163 | else { 164 | //usermesh.draw(); 165 | usermesh.drawWireframe(); 166 | } 167 | kinectcamera->end(); 168 | 169 | ofDisableDepthTest(); 170 | cam.end(); 171 | 172 | 173 | } 174 | 175 | //-------------------------------------------------------------- 176 | void ncKinectPCTriangulator::drawGUI() { 177 | gui.draw(); 178 | kinect2sscene.drawGUI(); 179 | } 180 | 181 | ofMesh & ncKinectPCTriangulator::getUserMesh() { 182 | return usermesh; 183 | } 184 | 185 | void ncKinectPCTriangulator::threadedFunction() { 186 | while (isThreadRunning()) { 187 | 188 | estimateUserVertices(vCount, tCount); 189 | 190 | 191 | } 192 | } 193 | 194 | void ncKinectPCTriangulator::estimateUserVertices(int & vCount, int & tCount) { 195 | 196 | vertexType.clear(); 197 | vertexType.resize(sampledWidth * sampledHeight); 198 | 199 | vertexIndex.clear(); 200 | vertexIndex.resize(sampledWidth * sampledHeight); 201 | 202 | vector vSpacePos; 203 | vSpacePos.assign(4, glm::vec3(0)); 204 | 205 | int rowIndex = 0; 206 | 207 | int counter = 0; 208 | 209 | for (int y = 0; y < sampledHeight - 1; y++) { 210 | 211 | int pixIndex = rowIndex; 212 | 213 | for (int x = 0; x < sampledWidth - 1; x++) { 214 | 215 | if (isUserSampleValid(x, y, vSpacePos[0]) && isUserSampleValid(x + 1, y, vSpacePos[1]) && isUserSampleValid(x, y + 1, vSpacePos[2]) && isUserSampleValid(x + 1, y + 1, vSpacePos[3])) { 216 | 217 | if (isSpacePointsClose(vSpacePos, 0.1f)) { 218 | vertexType[pixIndex] = 3; 219 | vertexType[pixIndex + 1] = 1; 220 | vertexType[pixIndex + sampledWidth] = 1; 221 | vertexType[pixIndex + sampledWidth + 1] = 1; 222 | } 223 | } 224 | pixIndex++; 225 | } 226 | rowIndex += sampledWidth; 227 | } 228 | 229 | // estimate counts 230 | vCount = 0; 231 | tCount = 0; 232 | 233 | for (int i = 0; i < vertexType.size(); i++) { 234 | if (vertexType[i] != 0) { 235 | vertexIndex[i] = vCount; 236 | vCount++; 237 | } 238 | else 239 | { 240 | vertexIndex[i] = 0; 241 | } 242 | 243 | if (vertexType[i] == 3) 244 | { 245 | tCount++; 246 | } 247 | } 248 | } 249 | 250 | bool ncKinectPCTriangulator::isUserSampleValid(int x, int y, glm::vec3 & vSpacePos) { 251 | int startIndex = y * sampleSize * depthWidth + x * sampleSize; 252 | 253 | int pixelIndex = startIndex; 254 | 255 | vSpacePos = pointcloud->getVertex(pixelIndex); 256 | 257 | if (silhouettespixels[pixelIndex] != 0 && !isinf(vSpacePos.x) && !isinf(vSpacePos.y) && !isinf(vSpacePos.z)) { 258 | return true; 259 | } 260 | 261 | pixelIndex++; 262 | 263 | startIndex += depthWidth; 264 | 265 | return false; 266 | 267 | } 268 | 269 | bool ncKinectPCTriangulator::isSpacePointsClose(vector < glm::vec3 > vSpacePos, float fMinDistSquared) { 270 | int iPosLength = vSpacePos.size(); 271 | 272 | for (int i = 0; i < iPosLength; i++) 273 | { 274 | for (int j = i + 1; j < iPosLength; j++) 275 | { 276 | glm::vec3 vDist = vSpacePos[j] - vSpacePos[i]; 277 | 278 | float sqrMag = vDist.x * vDist.x + vDist.y * vDist.y + vDist.z * vDist.z; 279 | 280 | if (sqrMag > fMinDistSquared) { 281 | return false; 282 | } 283 | } 284 | } 285 | return true; 286 | } 287 | 288 | //-------------------------------------------------------------- 289 | void ncKinectPCTriangulator::drawGridOneColor(float stepSize, size_t numberOfSteps, bool labels, bool x, bool y, bool z) { 290 | 291 | if (x) { 292 | ofDrawGridPlane(stepSize, numberOfSteps, labels); 293 | } 294 | if (y) { 295 | ofMatrix4x4 m; 296 | m.makeRotationMatrix(90, 0, 0, -1); 297 | ofPushMatrix(); 298 | ofMultMatrix(m); 299 | ofDrawGridPlane(stepSize, numberOfSteps, labels); 300 | ofPopMatrix(); 301 | } 302 | if (z) { 303 | ofMatrix4x4 m; 304 | m.makeRotationMatrix(90, 0, 1, 0); 305 | ofPushMatrix(); 306 | ofMultMatrix(m); 307 | ofDrawGridPlane(stepSize, numberOfSteps, labels); 308 | ofPopMatrix(); 309 | } 310 | 311 | if (labels) { 312 | float labelPos = stepSize * (numberOfSteps + 0.5); 313 | ofDrawBitmapString("x", labelPos, 0, 0); 314 | ofDrawBitmapString("y", 0, labelPos, 0); 315 | ofDrawBitmapString("z", 0, 0, labelPos); 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /src/utils/ncKinectPCTriangulator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGui.h" 5 | #include "ncKinectUser.h" 6 | #include "ncKinectv2Core.h" 7 | #include "ncKinectCamera.h" 8 | #include "ncKinect2dScene.h" 9 | #include "ncKinectEventDispatcher.h" 10 | #include "ofxMeshUtils.h" 11 | 12 | 13 | class ncKinectPCTriangulator :ofThread { 14 | 15 | public: 16 | void setup(vector &_users, ncKinectv2Core &_core,nCKinectCamera &_camera, ofPixels &_usermap, ofMesh & _pointcloud, int _id); 17 | int id; 18 | void update(); 19 | void draw(); 20 | void drawGUI(); 21 | ofMesh & getUserMesh(); 22 | void threadedFunction(); 23 | 24 | private: 25 | 26 | ofMesh usermesh; 27 | vector * users; 28 | nCKinectCamera *kinectcamera; 29 | ncKinect2dScene kinect2sscene; 30 | ncKinectv2Core *core; 31 | ofPixels *usermap; 32 | ofMesh *pointcloud; 33 | ofEasyCam cam; 34 | 35 | ofFbo silhouettebuffer; 36 | ofPixels silhouettespixels; 37 | 38 | ofxPanel gui; 39 | ofParameter bDrawGrid; 40 | ofParameter bClampPosition; 41 | ofParameter bRotate; 42 | ofParameter bDoPointCloud; 43 | ofParameter pointSize; 44 | ofParameter bDrawContours; 45 | ofParameter colorblend; 46 | 47 | void drawGridOneColor(float stepSize, size_t numberOfSteps, bool labels, bool x = true, bool y = true, bool z = true); 48 | 49 | //MESH STUFF 50 | int sampleSize; 51 | int depthWidth; 52 | int depthHeight; 53 | 54 | int sampledWidth; 55 | int sampledHeight; 56 | 57 | int vCount; 58 | int tCount; 59 | 60 | vector vertexType; 61 | vector vertexIndex; 62 | 63 | vector < glm::vec3 > vertices; 64 | vector < glm::vec2 > uvs; 65 | vector triangles; 66 | 67 | void estimateUserVertices(int &vCount, int &tCount); 68 | bool isUserSampleValid(int x, int y, glm::vec3 &vSpacePos); 69 | bool isSpacePointsClose(vector vSpacePos, float fMinDistSquared); 70 | 71 | ofImage silhouetteimage; 72 | 73 | }; 74 | -------------------------------------------------------------------------------- /src/utils/ncKinectSeDeserializer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ofMain.h" 3 | #include "ncKinectUser.h" 4 | 5 | class ncKinectSeDeSerObject { 6 | 7 | public: 8 | ofVec4f floorplane; 9 | vector < glm::vec3 > vertices; 10 | vector users; 11 | }; 12 | 13 | 14 | class ncKinectSeDeserializer 15 | { 16 | 17 | public: 18 | 19 | const string FLOORPLANEBEGIN = "[floor]"; 20 | const string FLOORPLANEEND = "[/floor]"; 21 | const string VERTS_BEGIN = "[verts]"; 22 | const string VERTS_END = "[/verts]"; 23 | const string NUM_VERTS_BEGIN = "[numverts]"; 24 | const string NUM_VERTS_END = "[/numverts]"; 25 | 26 | const string NUM_SKEL_BEGIN = "[numskeletons]"; 27 | const string NUM_SKEL_END = "[/numskeletons]"; 28 | 29 | const string SKELS_BEGIN = "[skels]"; 30 | const string SKELS_END = "[/skels]"; 31 | 32 | ncKinectSeDeserializer(){ 33 | } 34 | 35 | 36 | int getValue(ofBuffer buffer, string openTag, string closeTag) 37 | { 38 | unsigned char * data = (unsigned char *)buffer.getData(); 39 | int start = findDelimiter(buffer, openTag); 40 | if (start < 0) 41 | { 42 | ofLogError() << openTag << " NOT FOUND"; 43 | return start; 44 | } 45 | 46 | int end = findDelimiter(buffer, closeTag); 47 | if (end < 0) 48 | { 49 | ofLogError() << closeTag << " NOT FOUND"; 50 | return end; 51 | } 52 | 53 | int startPos = start + openTag.length(); 54 | 55 | data += startPos; 56 | 57 | int counter = startPos; 58 | stringstream ss; 59 | while (counter != end) 60 | { 61 | ss << data[0]; 62 | data++; 63 | counter++; 64 | } 65 | int result = ofToInt(ss.str()); 66 | return result; 67 | 68 | } 69 | 70 | int findDelimiter(ofBuffer inputBuffer, string delimiter) 71 | { 72 | char * data = (char *)inputBuffer.getData(); 73 | int size = inputBuffer.size(); 74 | 75 | unsigned int posInDelimiter = 0; 76 | for (int i = 0; i < size; i++) 77 | { 78 | if (data[i] == delimiter[posInDelimiter]) 79 | { 80 | posInDelimiter++; 81 | if (posInDelimiter == delimiter.size()) 82 | { 83 | return i - delimiter.size() + 1; 84 | } 85 | } 86 | else 87 | { 88 | posInDelimiter = 0; 89 | } 90 | } 91 | return -1; 92 | } 93 | 94 | void internal_deserialize(ncKinectSeDeSerObject& object, ofBuffer buffer) { 95 | unsigned char * data = (unsigned char *)buffer.getData(); 96 | 97 | //GET FLOORPLAN 98 | int startfloorplan = findDelimiter(buffer, FLOORPLANEBEGIN); 99 | int endfloorplan = findDelimiter(buffer, FLOORPLANEEND); 100 | 101 | int startPosFloorPlan = startfloorplan + FLOORPLANEBEGIN.length(); 102 | data += startPosFloorPlan; 103 | memcpy(&object.floorplane, data, sizeof(glm::vec4)); 104 | 105 | //GET NUM VERTICES 106 | int numVerts = getValue(buffer, NUM_VERTS_BEGIN, NUM_VERTS_END); 107 | 108 | //GET VERTICES 109 | unsigned char * datavertices = (unsigned char *)buffer.getData(); 110 | int startvertices = findDelimiter(buffer, VERTS_BEGIN); 111 | //int endvertices = findDelimiter(buffer, VERTS_END); 112 | int startPosVertices = startvertices + VERTS_BEGIN.length(); 113 | datavertices += startPosVertices; 114 | int stepSize = sizeof(glm::vec3); 115 | for (int i = 0; i < numVerts; i++) { 116 | glm::vec3 value; 117 | memcpy(&value, datavertices, stepSize); 118 | datavertices += stepSize; 119 | object.vertices.push_back(value); 120 | } 121 | 122 | //GET NUM SKELETONS 123 | int numSkeletons = getValue(buffer, NUM_SKEL_BEGIN, NUM_SKEL_END); 124 | 125 | if (numSkeletons > 0) { 126 | 127 | //GET SKELETONS 128 | for (int i = 0; i < numSkeletons; i++) { 129 | //GET THE VALUE OF THIS SKELETON ID 130 | 131 | //find skelidvalue 132 | int skelid = getValue(buffer, "[SKEL_ID" + ofToString(i) + "_START]", "[SKEL_ID" + ofToString(i) + "_END]"); 133 | 134 | 135 | //create the user 136 | ncKinectUser user; 137 | 138 | object.users.push_back(user); 139 | object.users[i].id= skelid; 140 | object.users[i].joints2dposition.resize(_ncJointType::ncJointType_Count); 141 | object.users[i].joints3dposition.resize(_ncJointType::ncJointType_Count); 142 | object.users[i].joints3drotation.resize(_ncJointType::ncJointType_Count); 143 | 144 | string tofind = "[SKEL_JOINTS" + ofToString(i) + "_START]"; 145 | unsigned char * jointsdata = (unsigned char *)buffer.getData(); 146 | int startjoints = findDelimiter(buffer, tofind); 147 | int startPosJoints = startjoints + tofind.length(); 148 | jointsdata += startPosJoints; 149 | int stepSizeJoints = sizeof(glm::vec3); 150 | //find joints 151 | for (int j = 0; j < _ncJointType::ncJointType_Count; j++) { 152 | glm::vec3 jvalue; 153 | memcpy(&jvalue, jointsdata, stepSize); 154 | jointsdata += stepSize; 155 | object.users[i].joints3dposition[j] = jvalue; 156 | } 157 | 158 | 159 | //find the joints rotation data 160 | string tofindrot = "[SKEL_JOINTS_ROTATION_" + ofToString(i) + "_START]"; 161 | int delimeterrotbegin = findDelimiter(buffer, tofindrot); 162 | int delimeterrotend = delimeterrotbegin + tofindrot.length(); 163 | unsigned char * jointsrotdata = (unsigned char *)buffer.getData(); 164 | jointsrotdata += delimeterrotend; 165 | int stepSizeJointsRot = sizeof(ofQuaternion); 166 | 167 | for (int j = 0; j < ncJointType_Count; j++) { 168 | ofQuaternion kvalue; 169 | memcpy(&kvalue, jointsrotdata, stepSizeJointsRot); 170 | jointsrotdata += stepSizeJointsRot; 171 | object.users[i].joints3drotation[j] = kvalue; 172 | } 173 | 174 | //find the joints position data 2d 175 | string tofindpos2d = "[SKEL_JOINTS_POSITION_2D" + ofToString(i) + "_START]"; 176 | int delimeterpos2dbegin = findDelimiter(buffer, tofindpos2d); 177 | int delimeterpos2dend = delimeterpos2dbegin + tofindpos2d.length(); 178 | unsigned char * jointspos2ddata = (unsigned char *)buffer.getData(); 179 | jointspos2ddata += delimeterpos2dend; 180 | int stepSizeJointsPos2d = sizeof(glm::vec2); 181 | 182 | for (int j = 0; j < ncJointType_Count; j++) { 183 | glm::vec3 zvalue; 184 | memcpy(&zvalue, jointspos2ddata, stepSizeJointsPos2d); 185 | jointspos2ddata += stepSizeJointsPos2d; 186 | object.users[i].joints2dposition[j] = zvalue; 187 | } 188 | } 189 | } 190 | } 191 | 192 | 193 | void internal_serialize(ncKinectSeDeSerObject& source, ofBuffer& buffer) { 194 | 195 | //FLOORPLANE 196 | buffer.append(FLOORPLANEBEGIN); 197 | char sendData[sizeof(glm::vec4)]; 198 | memcpy(sendData, &source.floorplane, sizeof(glm::vec4)); 199 | buffer.append(sendData,sizeof(glm::vec4)); 200 | buffer.append(FLOORPLANEEND); 201 | 202 | //VERTICES 203 | //FIRST ADD NUMBER OF VERTICES 204 | buffer.append(NUM_VERTS_BEGIN); 205 | buffer.append(ofToString(source.vertices.size())); 206 | buffer.append(NUM_VERTS_END); 207 | if (source.vertices.size() > 0) { 208 | //SECOND ADD THE VERTICES 209 | buffer.append(VERTS_BEGIN); 210 | glm::vec3 *data = &source.vertices[0]; 211 | int dataSize = sizeof(glm::vec3)*source.vertices.size(); 212 | buffer.append((const char *)data, dataSize); 213 | buffer.append(VERTS_END); 214 | } 215 | 216 | //SKELETONS 217 | buffer.append(NUM_SKEL_BEGIN); 218 | buffer.append(ofToString(source.users.size())); 219 | buffer.append(NUM_SKEL_END); 220 | 221 | if (source.users.size() > 0) { 222 | 223 | for (int i = 0; i < source.users.size(); ++i) { 224 | 225 | string idstart = "[SKEL_ID" + ofToString(i) + "_START]"; 226 | buffer.append(idstart); 227 | buffer.append(ofToString(source.users[i].id)); 228 | string idend = "[SKEL_ID" + ofToString(i) + "_END]"; 229 | buffer.append(idend); 230 | 231 | string jointsstart = "[SKEL_JOINTS" + ofToString(i) + "_START]"; 232 | buffer.append(jointsstart); 233 | glm::vec3 *jdata = &source.users[i].joints3dposition[0]; 234 | int jdataSize = sizeof(glm::vec3)*source.users[i].joints3dposition.size(); 235 | buffer.append((const char *)jdata, jdataSize); 236 | 237 | string jointsstartor = "[SKEL_JOINTS_ROTATION_" + ofToString(i) + "_START]"; 238 | buffer.append(jointsstartor); 239 | ofQuaternion *jdataor = &source.users[i].joints3drotation[0]; 240 | int jdataSizeor = sizeof(ofQuaternion)*source.users[i].joints3drotation.size(); 241 | buffer.append((const char *)jdataor, jdataSizeor); 242 | 243 | string jointsstart2d = "[SKEL_JOINTS_POSITION_2D" + ofToString(i) + "_START]"; 244 | buffer.append(jointsstart2d); 245 | glm::vec2 *jdata2d = &source.users[i].joints2dposition[0]; 246 | int jdataSize2d = sizeof(glm::vec2)*source.users[i].joints2dposition.size(); 247 | buffer.append((const char *)jdata2d, jdataSize2d); 248 | } 249 | } 250 | } 251 | 252 | ofBuffer serialize(ncKinectSeDeSerObject& object) { 253 | ofBuffer buffer; 254 | internal_serialize(object, buffer); 255 | return buffer; 256 | } 257 | 258 | ncKinectSeDeSerObject deserialize(ofBuffer buffer) { 259 | ncKinectSeDeSerObject obj; 260 | internal_deserialize(obj, buffer); 261 | return obj; 262 | } 263 | 264 | }; 265 | -------------------------------------------------------------------------------- /src/utils/ncKinectv2GestureDetector.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectv2GestureDetector.h" 2 | 3 | ncKinectv2GestureDetector::~ncKinectv2GestureDetector() { 4 | SafeReleaseGDT(frameReader); 5 | SafeReleaseGDT(frameSource); 6 | SafeReleaseGDT(dataBase); 7 | } 8 | 9 | ncKinectv2GestureDetector::ncKinectv2GestureDetector(IKinectSensor* _sensor, int _id, string _database) { 10 | id = _id; 11 | sensor = _sensor; 12 | 13 | //create frame source 14 | CreateVisualGestureBuilderFrameSource(sensor, 0, &frameSource); 15 | 16 | //create reader with source 17 | frameSource->OpenReader(&frameReader); 18 | frameReader->put_IsPaused(TRUE); 19 | 20 | //load the database 21 | std::wstring stow(+_database.length(), L' '); // Make room for characters 22 | std::copy(_database.begin(), _database.end(), stow.begin()); 23 | wstring sDatabaseFile = L"data/"+stow; 24 | 25 | if (CreateVisualGestureBuilderDatabaseInstanceFromFile(sDatabaseFile.c_str(), &dataBase) != S_OK) { 26 | wcerr << L"Can't read database file " << sDatabaseFile << endl; 27 | } 28 | 29 | //set the number of gestures 30 | dataBase->get_AvailableGesturesCount(&numberofgestures); 31 | gestures.resize(numberofgestures); 32 | //get the gestures 33 | dataBase->get_AvailableGestures(numberofgestures, &gestures[0]); 34 | 35 | GestureType gType; 36 | const UINT uTextLength = 260; // magic number, if value smaller than 260, can't get name 37 | wchar_t sName[uTextLength]; 38 | 39 | //loop through the gestures 40 | for (int i = 0; i < numberofgestures; ++i) { 41 | 42 | if (frameSource->AddGesture(gestures[i]) != S_OK) { 43 | cout << "gesture not added to sourceframe" << endl; 44 | } 45 | 46 | const UINT uTextLength = 260; 47 | wchar_t sName[uTextLength]; 48 | gestures[i]->get_Name(uTextLength, sName); 49 | wcout << "loaded gesture: "<CalculateAndAcquireLatestFrame(&gestureFrame) != S_OK) { 59 | SafeReleaseGDT(gestureFrame); 60 | return; 61 | } 62 | 63 | BOOLEAN bvalid; 64 | gestureFrame->get_IsTrackingIdValid(&bvalid); 65 | 66 | if ((bool)bvalid) { 67 | GestureType mType; 68 | const UINT uTextLength = 260; 69 | wchar_t sName[uTextLength]; 70 | for (size_t g = 0; g < gestures.size(); g++) { 71 | // get gesture information 72 | gestures[g]->get_GestureType(&mType); 73 | gestures[g]->get_Name(uTextLength, sName); 74 | if (mType == GestureType_Discrete) { 75 | IDiscreteGestureResult* pGestureResult = nullptr; 76 | if (gestureFrame->get_DiscreteGestureResult(gestures[g], &pGestureResult) == S_OK) { 77 | 78 | BOOLEAN bDetected; 79 | pGestureResult->get_Detected(&bDetected); 80 | if (bDetected) { 81 | float fConfidence = 0.0f; 82 | pGestureResult->get_Confidence(&fConfidence); 83 | //wcout << "Detected Gesture " << sName << " - " << fConfidence << endl; 84 | 85 | wstring ws(sName); 86 | string str(ws.begin(), ws.end()); 87 | 88 | NCGenericEventArg arg; 89 | arg.message = str; 90 | arg.value = fConfidence; 91 | arg.userid = id; 92 | ncKinectEventDispatcher::NCEVENTDISPATCHER.dispatchDiscreteGesture(arg); 93 | 94 | } 95 | } 96 | SafeReleaseGDT(pGestureResult); 97 | } 98 | else if (mType == GestureType_Continuous) { 99 | 100 | IContinuousGestureResult* pGestureResult = nullptr; 101 | 102 | if (gestureFrame->get_ContinuousGestureResult(gestures[g], &pGestureResult) == S_OK) { 103 | 104 | float progress; 105 | pGestureResult->get_Progress(&progress); 106 | 107 | //wcout << "Detected Gesture " << sName << " - " << progress << endl; 108 | 109 | wstring ws(sName); 110 | string str(ws.begin(), ws.end()); 111 | NCGenericEventArg arg; 112 | arg.message = ofToString(str); 113 | arg.value = progress; 114 | arg.userid = id; 115 | ncKinectEventDispatcher::NCEVENTDISPATCHER.dispatchContinuousGesture(arg); 116 | 117 | } 118 | 119 | SafeReleaseGDT(pGestureResult); 120 | } 121 | } 122 | } 123 | SafeReleaseGDT(gestureFrame); 124 | } 125 | } 126 | 127 | UINT64 ncKinectv2GestureDetector::getTrackingId() { 128 | UINT64 idt; 129 | frameSource->get_TrackingId(&idt); 130 | return idt; 131 | } 132 | 133 | void ncKinectv2GestureDetector::setTrackingId(UINT64 _id) { 134 | 135 | UINT64 trid; 136 | frameSource->get_TrackingId(&trid); 137 | 138 | if (trid != _id) { 139 | frameSource->put_TrackingId(_id); 140 | } 141 | 142 | } 143 | 144 | bool ncKinectv2GestureDetector::getPaused() { 145 | BOOLEAN bpaused; 146 | frameReader->get_IsPaused(&bpaused); 147 | 148 | return (bool)bpaused; 149 | } 150 | 151 | void ncKinectv2GestureDetector::setPaused(bool _paused) { 152 | 153 | frameReader->put_IsPaused(_paused); 154 | } 155 | -------------------------------------------------------------------------------- /src/utils/ncKinectv2GestureDetector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "Kinect.h" 5 | #include "Kinect.VisualGestureBuilder.h" 6 | #include "ncKinectEventDispatcher.h" 7 | 8 | class ncKinectv2GestureDetector { 9 | 10 | public: 11 | ~ncKinectv2GestureDetector(); 12 | ncKinectv2GestureDetector(IKinectSensor* _sensor, int _id, string _database); 13 | 14 | void update(); 15 | 16 | UINT64 getTrackingId(); 17 | void setTrackingId(UINT64 _id); 18 | 19 | bool getPaused(); 20 | void setPaused(bool _paused); 21 | 22 | 23 | private: 24 | IKinectSensor* sensor; 25 | IVisualGestureBuilderDatabase * dataBase; 26 | IVisualGestureBuilderFrameReader * frameReader; 27 | IVisualGestureBuilderFrameSource * frameSource; 28 | vector gestures; 29 | UINT numberofgestures; 30 | int id; 31 | }; 32 | 33 | // Safe release for interfaces 34 | template 35 | inline void SafeReleaseGDT(Interface *& pInterfaceToRelease) { 36 | if (pInterfaceToRelease != NULL) { 37 | pInterfaceToRelease->Release(); 38 | pInterfaceToRelease = NULL; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/utils/ofxInfiniteCanvas.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ofxInfiniteCanvas.cpp 3 | // ofxInfiniteCanvas 4 | // 5 | // Created by Roy Macdonald on 27-06-15. 6 | // 7 | // 8 | 9 | #include "ofxInfiniteCanvas.h" 10 | 11 | 12 | ofMatrix4x4 ofxInfiniteCanvas::FM = ofMatrix4x4( 1, 0, 0, 0, 13 | 0, 1, 0, 0, 14 | 0, 0, 1, 0, 15 | 0, 0, 0, 1 ); 16 | ofMatrix4x4 ofxInfiniteCanvas::BM = ofMatrix4x4(-1, 0, 0, 0, 17 | 0, 1, 0, 0, 18 | 0, 0, 1, 0, 19 | 0, 0, 0, 1 ); 20 | ofMatrix4x4 ofxInfiniteCanvas::LM = ofMatrix4x4( 0, 0, 1, 0, 21 | 0, 1, 0, 0, 22 | 1, 0, 0, 0, 23 | 0, 0, 0, 1 ); 24 | ofMatrix4x4 ofxInfiniteCanvas::RM = ofMatrix4x4( 0, 0,-1, 0, 25 | 0, 1, 0, 0, 26 | 1, 0, 0, 0, 27 | 0, 0, 0, 1 ); 28 | ofMatrix4x4 ofxInfiniteCanvas::TM = ofMatrix4x4( 1, 0, 0, 0, 29 | 0, 0, 1, 0, 30 | 0, 1, 0, 0, 31 | 0, 0, 0, 1 ); 32 | ofMatrix4x4 ofxInfiniteCanvas::BoM = ofMatrix4x4( 1, 0, 0, 0, 33 | 0, 0,-1, 0, 34 | 0, 1, 0, 0, 35 | 0, 0, 0, 1 ); 36 | 37 | static const float minDifference = 0.1e-5f; 38 | 39 | static const unsigned long doubleclickTime = 300; 40 | 41 | //---------------------------------------- 42 | ofxInfiniteCanvas::ofxInfiniteCanvas(){ 43 | setLookAt(OFX2DCAM_FRONT); 44 | lastTap = 0; 45 | bMouseOverride = false; 46 | bApplyInertia =false; 47 | bDoTranslate = false; 48 | // bNotifyMouseDragged = false; 49 | // bNotifyMousePressed = false; 50 | // bNotifyMouseReleased = false; 51 | // bNotifyMouseScrolled = false; 52 | bMouseListenersEnabled = false; 53 | bDistanceSet = false; 54 | bDoScale = false; 55 | 56 | reset(); 57 | parameters.setName("ofxInfiniteCanvas"); 58 | parameters.add(bEnableMouse.set("Enable Mouse Input", false)); 59 | parameters.add(dragSensitivity.set("Drag Sensitivity", 1, 0, 3)); 60 | parameters.add(scrollSensitivity.set("Scroll Sensitivity", 10, 0, 30)); 61 | parameters.add(drag.set("Drag", 0.9, 0, 1)); 62 | parameters.add(farClip.set("Far Clip", 2000, 5000, 10000)); 63 | parameters.add(nearClip.set("Near Clip", -1000, -5000, 10000)); 64 | parameters.add(bFlipY.set("Flip Y axis", false)); 65 | 66 | bEnableMouse.addListener(this, &ofxInfiniteCanvas::enableMouseInputCB); 67 | enableMouseInput(); 68 | 69 | protectedParameters.setName("ofxInfiniteCanvasParams"); 70 | scale.setName("Scale"); 71 | protectedParameters.add(scale); 72 | translation.setName("translation"); 73 | protectedParameters.add(translation); 74 | lookAt.setName("Look At"); 75 | protectedParameters.add(lookAt); 76 | protectedParameters.add(parameters); 77 | cam.enableOrtho(); 78 | bUseOfCam = true; 79 | 80 | } 81 | //---------------------------------------- 82 | void ofxInfiniteCanvas::toggleOfCam(){ 83 | bUseOfCam ^= true; 84 | } 85 | //---------------------------------------- 86 | void ofxInfiniteCanvas::save(string path){ 87 | ofXml xml; 88 | xml.save(path); 89 | } 90 | //---------------------------------------- 91 | bool ofxInfiniteCanvas::load(string path){ 92 | ofFile f(path); 93 | if (f.exists()) { 94 | reset(); 95 | ofXml xml; 96 | xml.load(path); 97 | setLookAt(getLookAt()); 98 | return true; 99 | } 100 | return false; 101 | } 102 | //---------------------------------------- 103 | ofxInfiniteCanvas::~ofxInfiniteCanvas(){ 104 | disableMouseInput(); 105 | } 106 | //---------------------------------------- 107 | void ofxInfiniteCanvas::setOverrideMouse(bool b){ 108 | if(bMouseOverride != b){ 109 | enableMouseListeners(b); 110 | bMouseOverride = b; 111 | } 112 | } 113 | //---------------------------------------- 114 | void ofxInfiniteCanvas::reset(){ 115 | if (!viewport.isEmpty()) { 116 | translation = viewport.getCenter(); 117 | // translation = {viewport.width/2, viewport.height/2, 0.}; 118 | }else{ 119 | translation = {(ofGetWidth()/2.), (ofGetHeight()/2.), 0}; 120 | } 121 | offset = {0,0,0}; 122 | scale =1; 123 | move = {0,0,0}; 124 | bDoScale = false; 125 | bApplyInertia = false; 126 | bDoTranslate = false; 127 | } 128 | //---------------------------------------- 129 | void ofxInfiniteCanvas::begin(ofRectangle _viewport){ 130 | glm::vec3 t = glm::vec3(glm::vec4(translation.get() + offset,1.0) * orientationMatrix); 131 | viewport = _viewport; 132 | if(!bUseOfCam){ 133 | ofPushView(); 134 | ofViewport(viewport); 135 | ofSetupScreenOrtho(viewport.width, viewport.height, nearClip, farClip); 136 | ofPushMatrix(); 137 | ofRotateXDeg(orientation.x); 138 | ofRotateYDeg(orientation.y); 139 | 140 | ofTranslate(t); 141 | ofScale(scale,scale * (bFlipY?-1:1),scale); 142 | }else{ 143 | // cam.setOrientation(orientation); 144 | cam.setPosition(t.x * -1.0f, t.y * (bFlipY?-1:1), t.z * -1); 145 | cam.setScale(scale,scale * (bFlipY?-1:1),scale); 146 | cam.begin(); 147 | } 148 | } 149 | //---------------------------------------- 150 | ofxInfiniteCanvas::LookAt ofxInfiniteCanvas::getLookAt(){ 151 | return (LookAt)lookAt.get(); 152 | } 153 | //---------------------------------------- 154 | void ofxInfiniteCanvas::end(){ 155 | if(bUseOfCam){ 156 | cam.end(); 157 | }else{ 158 | ofPopMatrix(); 159 | ofPopView(); 160 | } 161 | } 162 | //---------------------------------------- 163 | void ofxInfiniteCanvas::setFarClip(float fc){ 164 | farClip = fc; 165 | } 166 | //---------------------------------------- 167 | void ofxInfiniteCanvas::setNearClip(float nc){ 168 | nearClip = nc; 169 | } 170 | //---------------------------------------- 171 | void ofxInfiniteCanvas::setDragSensitivity(float s){ 172 | dragSensitivity = s;} 173 | //---------------------------------------- 174 | void ofxInfiniteCanvas::setScrollSensitivity(float s){ 175 | scrollSensitivity = s; 176 | } 177 | //---------------------------------------- 178 | void ofxInfiniteCanvas::setLookAt(LookAt l){ 179 | bool bUpdateMatrix = false; 180 | lookAt = l; 181 | switch (l) { 182 | case OFX2DCAM_FRONT: 183 | orientationMatrix = FM; 184 | orientation={0,0,0};//.set(0); 185 | break; 186 | case OFX2DCAM_BACK: 187 | orientationMatrix = BM; 188 | orientation = {0,180,0};//.set(0,180,0); 189 | break; 190 | case OFX2DCAM_LEFT: 191 | orientationMatrix = LM; 192 | orientation = {0, 90,0};//.set(0, 90,0); 193 | break; 194 | case OFX2DCAM_RIGHT: 195 | orientationMatrix = RM; 196 | orientation = {0, -90, 0};//.set(0, -90, 0); 197 | break; 198 | case OFX2DCAM_TOP: 199 | orientationMatrix = TM; 200 | orientation = {-90, 0,0};//.set(-90, 0,0); 201 | break; 202 | case OFX2DCAM_BOTTOM: 203 | orientationMatrix = BoM; 204 | orientation = {90, 0, 0};//.set(90, 0, 0); 205 | break; 206 | default: 207 | break; 208 | } 209 | } 210 | //---------------------------------------- 211 | void ofxInfiniteCanvas::setFlipY(bool bFlipped){ 212 | bFlipY.set(bFlipped); 213 | } 214 | //---------------------------------------- 215 | void ofxInfiniteCanvas::setDrag(float drag){this->drag = drag;} 216 | //---------------------------------------- 217 | float ofxInfiniteCanvas::getDrag() const{return drag;} 218 | //---------------------------------------- 219 | void ofxInfiniteCanvas::setTranslation(glm::vec3 t){ 220 | translation = t; 221 | } 222 | //---------------------------------------- 223 | void ofxInfiniteCanvas::setScale(float s){ 224 | scale = s; 225 | } 226 | //---------------------------------------- 227 | void ofxInfiniteCanvas::setOffset(const glm::vec3& o){ 228 | offset = o; 229 | } 230 | //---------------------------------------- 231 | glm::vec3 ofxInfiniteCanvas::getOffset(){ 232 | return offset; 233 | } 234 | //---------------------------------------- 235 | void ofxInfiniteCanvas::enableMouseInputCB(bool &e){ 236 | enableMouseInput(e); 237 | } 238 | //---------------------------------------- 239 | void ofxInfiniteCanvas::enableMouseInput(bool e){ 240 | if(bMouseInputEnabled != e ){ 241 | if(e){ 242 | ofAddListener(ofEvents().update, this, &ofxInfiniteCanvas::update, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 243 | }else{ 244 | ofRemoveListener(ofEvents().update, this, &ofxInfiniteCanvas::update, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 245 | } 246 | if (!bMouseOverride) { 247 | enableMouseListeners(e); 248 | } 249 | bMouseInputEnabled = e; 250 | if (bEnableMouse != e) { 251 | bEnableMouse = e; 252 | } 253 | } 254 | } 255 | //---------------------------------------- 256 | void ofxInfiniteCanvas::enableMouseListeners(bool e){ 257 | if (bMouseListenersEnabled != e) { 258 | if (e) { 259 | ofAddListener(ofEvents().mouseDragged , this, &ofxInfiniteCanvas::mouseDragged, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 260 | ofAddListener(ofEvents().mousePressed, this, &ofxInfiniteCanvas::mousePressed, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 261 | ofAddListener(ofEvents().mouseReleased, this, &ofxInfiniteCanvas::mouseReleased, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 262 | ofAddListener(ofEvents().mouseScrolled, this, &ofxInfiniteCanvas::mouseScrolled, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 263 | }else{ 264 | ofRemoveListener(ofEvents().mouseDragged, this, &ofxInfiniteCanvas::mouseDragged, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 265 | ofRemoveListener(ofEvents().mousePressed, this, &ofxInfiniteCanvas::mousePressed, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 266 | ofRemoveListener(ofEvents().mouseReleased, this, &ofxInfiniteCanvas::mouseReleased, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 267 | ofRemoveListener(ofEvents().mouseScrolled, this, &ofxInfiniteCanvas::mouseScrolled, bMouseOverride?OF_EVENT_ORDER_BEFORE_APP:OF_EVENT_ORDER_AFTER_APP); 268 | } 269 | bMouseListenersEnabled = e; 270 | } 271 | } 272 | //---------------------------------------- 273 | void ofxInfiniteCanvas::disableMouseInput(){ 274 | enableMouseInput(false); 275 | } 276 | //---------------------------------------- 277 | bool ofxInfiniteCanvas::getMouseInputEnabled(){ 278 | return bMouseInputEnabled; 279 | } 280 | //---------------------------------------- 281 | void ofxInfiniteCanvas::mousePressed(ofMouseEventArgs & mouse){ 282 | 283 | if(viewport.inside(mouse.x, mouse.y)){ 284 | if (bMouseInputEnabled) { 285 | prevMouse = mouse; 286 | bDoTranslate =(mouse.button == OF_MOUSE_BUTTON_LEFT); 287 | bDoScale =(mouse.button == OF_MOUSE_BUTTON_RIGHT); 288 | bApplyInertia = false; 289 | clicPoint = mouse - translation.get() - viewport.getPosition(); 290 | clicPoint /= scale; 291 | 292 | //clicPoint = screenToWorld(mouse); 293 | clicTranslation = translation.get(); 294 | clicScale = scale; 295 | } 296 | if (bMouseOverride) { 297 | // mouse.set(screenToWorld((glm::vec3)mouse));//convertir a glm 298 | // lastMousePressed = mouse; 299 | // bNotifyMousePressed = true; 300 | } 301 | // return bMouseOverride; 302 | } 303 | // return false; 304 | } 305 | //---------------------------------------- 306 | //bool 307 | void ofxInfiniteCanvas::mouseReleased(ofMouseEventArgs & mouse){ 308 | if(viewport.inside(mouse.x, mouse.y)){ 309 | if (bMouseInputEnabled) { 310 | unsigned long curTap = ofGetElapsedTimeMillis(); 311 | if(lastTap != 0 && curTap - lastTap < doubleclickTime){ 312 | reset(); 313 | return; 314 | } 315 | lastTap = curTap; 316 | bApplyInertia = true; 317 | mouseVel = mouse - prevMouse; 318 | updateMouse(); 319 | prevMouse = mouse; 320 | } 321 | if (bMouseOverride) { 322 | //mouse.set(screenToWorld((glm::vec3)mouse));//convertir a glm 323 | // lastMouseReleased = mouse; 324 | // bNotifyMouseReleased = true; 325 | } 326 | } 327 | // 328 | // return bMouseOverride; 329 | } 330 | //---------------------------------------- 331 | //bool 332 | void ofxInfiniteCanvas::mouseDragged(ofMouseEventArgs & mouse){ 333 | if(viewport.inside(mouse.x, mouse.y)){ 334 | if (bMouseInputEnabled) { 335 | mouseVel = mouse - prevMouse; 336 | bApplyInertia = false; 337 | updateMouse(); 338 | prevMouse = mouse; 339 | } 340 | if (bMouseOverride) { 341 | // mouse.set(screenToWorld((glm::vec3)mouse));//convertir a glm 342 | // lastMouseDragged = mouse; 343 | // bNotifyMouseDragged = true; 344 | } 345 | } 346 | // 347 | // return bMouseOverride; 348 | } 349 | //---------------------------------------- 350 | //bool 351 | void ofxInfiniteCanvas::mouseScrolled(ofMouseEventArgs & mouse){ 352 | if(viewport.inside(mouse.x, mouse.y)){ 353 | if (bMouseInputEnabled) { 354 | move.z = scrollSensitivity * mouse.scrollY / ofGetHeight(); 355 | bDoTranslate = false; 356 | bDoScale = true; 357 | clicPoint = glm::vec2(ofGetMouseX(), ofGetMouseY()) - translation.get()- viewport.getPosition(); 358 | clicPoint /= scale; 359 | 360 | clicScale = scale; 361 | clicTranslation = translation.get(); 362 | } 363 | if (bMouseOverride) { 364 | // mouse.set(screenToWorld((glm::vec3)mouse));//convertir a glm 365 | // lastMouseScrolled = mouse; 366 | // bNotifyMouseScrolled = true; 367 | } 368 | } 369 | // 370 | // return bMouseOverride; 371 | } 372 | //---------------------------------------- 373 | void ofxInfiniteCanvas::updateMouse(){ 374 | move = {0,0,0}; 375 | if(bDoScale){ 376 | move.z = dragSensitivity * mouseVel.y /ofGetHeight(); 377 | }else if(bDoTranslate){ 378 | move.x = mouseVel.x ; 379 | move.y = mouseVel.y; 380 | } 381 | } 382 | //---------------------------------------- 383 | void ofxInfiniteCanvas::update(ofEventArgs & args){ 384 | update(); 385 | } 386 | //---------------------------------------- 387 | void ofxInfiniteCanvas::update(){ 388 | if(bMouseInputEnabled){ 389 | if(bApplyInertia){ 390 | move *= drag; 391 | if(ABS(move.x) <= minDifference && ABS(move.y) <= minDifference && ABS(move.z) <= minDifference){ 392 | bApplyInertia = false; 393 | bDoTranslate = false; 394 | bDoScale = false; 395 | } 396 | } 397 | if(bDoTranslate){ 398 | translation += glm::vec3(move.x , move.y, 0); 399 | }else if(bDoScale){ 400 | scale += move.z + move.z*scale; 401 | translation = clicTranslation - clicPoint*(scale - clicScale); 402 | } 403 | if(!bApplyInertia){ 404 | move = {0,0,0}; 405 | } 406 | // if (bMouseOverride) { 407 | // if (bNotifyMousePressed) { 408 | // lastMousePressed.set(screenToWorld((glm::vec3)lastMousePressed)); 409 | // ofNotifyEvent(ofEvents().mousePressed, lastMousePressed); 410 | // bNotifyMousePressed = false; 411 | // } 412 | // if (bNotifyMouseReleased) { 413 | // lastMouseReleased.set(screenToWorld((glm::vec3)lastMouseReleased)); 414 | // ofNotifyEvent(ofEvents().mouseReleased, lastMouseReleased); 415 | // bNotifyMouseReleased = false; 416 | // } 417 | // if (bNotifyMouseDragged) { 418 | // lastMouseDragged.set(screenToWorld((glm::vec3)lastMouseDragged)); 419 | // ofNotifyEvent(ofEvents().mouseDragged, lastMouseDragged); 420 | // bNotifyMouseDragged = false; 421 | // } 422 | // if (bNotifyMouseScrolled) { 423 | // lastMouseScrolled.set(screenToWorld((glm::vec3)lastMouseScrolled)); 424 | // ofNotifyEvent(ofEvents().mouseScrolled, lastMouseScrolled); 425 | // bNotifyMouseScrolled = false; 426 | // } 427 | // } 428 | } 429 | } 430 | //---------------------------------------- 431 | void ofxInfiniteCanvas::drawDebug(){ 432 | string m = "translation: " + ofToString(translation) + "\n"; 433 | m += "scale: " + ofToString(scale) + "\n"; 434 | m += "clic point: " + ofToString(clicPoint) + "\n"; 435 | ofDrawBitmapString(m, 0, 20); 436 | } 437 | //---------------------------------------- 438 | glm::vec3 ofxInfiniteCanvas::screenToWorld(glm::vec3 screen){ 439 | glm::vec3 s = screen - translation.get() - offset - viewport.getPosition(); 440 | s = glm::vec3(glm::vec4(s,1.) * orientationMatrix); 441 | s /= scale; 442 | if(bFlipY)s.y*=-1; 443 | return s; 444 | } 445 | 446 | glm::vec3 ofxInfiniteCanvas::worldToScreen(glm::vec3 world){ 447 | glm::vec3 s = world * scale.get(); 448 | s = glm::vec3(glm::vec4(s,1.) * glm::inverse(orientationMatrix)); 449 | // s = s * orientationMatrix.getInverse(); 450 | s = s + translation.get() + offset + viewport.getPosition(); 451 | return s; 452 | } 453 | -------------------------------------------------------------------------------- /src/utils/ofxInfiniteCanvas.h: -------------------------------------------------------------------------------- 1 | // 2 | // 2DCam.h 3 | // This addon is for navigating through a 3D scene using an orthographic projection, so that it looks like 2D, or any 2D scene. 4 | // This should be used instead of ofEasyCam when using an ortho projection or when drawing 2D, as ofEasyCam's controls are not well suited for such task. 5 | // The user can change the position from where the scene is being looked. TOP, BOTTOM, LEFT, RIGHT, FRONT (default), BACK. 6 | // 7 | // 8 | // Created by Roy Macdonald on 27-06-15. 9 | // 10 | // 11 | 12 | #pragma once 13 | #include "ofMain.h" 14 | 15 | 16 | class ofxInfiniteCanvas { 17 | public: 18 | 19 | enum LookAt{ 20 | OFX2DCAM_FRONT =0, 21 | OFX2DCAM_BACK, 22 | OFX2DCAM_LEFT, 23 | OFX2DCAM_RIGHT, 24 | OFX2DCAM_TOP, 25 | OFX2DCAM_BOTTOM 26 | }; 27 | ofxInfiniteCanvas(); 28 | ~ofxInfiniteCanvas(); 29 | 30 | virtual void begin(ofRectangle viewport = ofGetCurrentViewport()); 31 | virtual void end(); 32 | void reset(); 33 | //------- mouse 34 | void enableMouseInput(bool e = true); 35 | void disableMouseInput(); 36 | bool getMouseInputEnabled(); 37 | 38 | void mousePressed(ofMouseEventArgs & mouse); 39 | void mouseReleased(ofMouseEventArgs & mouse); 40 | void mouseDragged(ofMouseEventArgs & mouse); 41 | void mouseScrolled(ofMouseEventArgs & mouse); 42 | // bool mousePressed(ofMouseEventArgs & mouse); 43 | // bool mouseReleased(ofMouseEventArgs & mouse); 44 | // bool mouseDragged(ofMouseEventArgs & mouse); 45 | // bool mouseScrolled(ofMouseEventArgs & mouse); 46 | 47 | //------- getters/setters 48 | void setFlipY(bool bFlipped); 49 | bool getYFlipped(){return bFlipY;} 50 | glm::vec3 getTranslation(){return translation;} 51 | void setTranslation(glm::vec3 t); 52 | float getScale(){return scale;} 53 | void setScale(float s); 54 | 55 | void setLookAt(LookAt l); 56 | LookAt getLookAt(); 57 | 58 | void update(); 59 | void drawDebug(); 60 | 61 | void setDragSensitivity(float s); 62 | float getDragSensitivity(){return dragSensitivity;} 63 | 64 | void setScrollSensitivity(float s); 65 | float getScrollSensitivity(){return scrollSensitivity;} 66 | 67 | void setDrag(float drag); 68 | float getDrag() const; 69 | 70 | void setNearClip(float nc); 71 | float getNearClip(){return nearClip;} 72 | 73 | void setFarClip(float fc); 74 | float getFarClip(){return farClip;} 75 | 76 | void setOverrideMouse(bool b); 77 | bool isMouseOverride(){return bMouseOverride;} 78 | 79 | void setOffset(const glm::vec3& o); 80 | glm::vec3 getOffset(); 81 | //------- parameters 82 | ofParameterGroup parameters; 83 | 84 | //------- utils 85 | glm::vec3 screenToWorld(glm::vec3 screen); 86 | glm::vec3 worldToScreen(glm::vec3 world); 87 | 88 | void save(string path); 89 | bool load(string path); 90 | ofCamera cam; 91 | void toggleOfCam(); 92 | protected: 93 | 94 | bool bUseOfCam; 95 | glm::vec3 orientation; 96 | void enableMouseInputCB(bool &e); 97 | ofRectangle viewport; 98 | bool bApplyInertia; 99 | bool bDoTranslate; 100 | bool bDoScale; 101 | bool bDoScrollZoom; 102 | bool bMouseInputEnabled; 103 | bool bDistanceSet; 104 | bool bEventsSet; 105 | glm::vec3 move; 106 | ofParameter scale; 107 | float clicScale; 108 | 109 | ofParameterGroup protectedParameters; 110 | ofParametertranslation; 111 | glm::vec3 clicTranslation, offset; 112 | ofParameter bEnableMouse,bFlipY; 113 | ofParameter dragSensitivity, scrollSensitivity, drag, farClip, nearClip; 114 | 115 | bool bMouseOverride; 116 | ofMouseEventArgs lastMouseDragged, lastMousePressed, lastMouseReleased, lastMouseScrolled; 117 | bool bNotifyMouseDragged, bNotifyMousePressed, bNotifyMouseReleased, bNotifyMouseScrolled; 118 | 119 | 120 | void enableMouseListeners(bool e = true); 121 | bool bMouseListenersEnabled; 122 | glm::vec2 prevMouse, clicPoint; 123 | 124 | glm::vec2 mouseVel; 125 | 126 | void update(ofEventArgs & args); 127 | 128 | void updateMouse(); 129 | 130 | // ofMatrix4x4 131 | glm::mat4 orientationMatrix; 132 | 133 | unsigned long lastTap; 134 | 135 | ofParameter lookAt; 136 | 137 | static ofMatrix4x4 FM, BM, LM, RM, TM, BoM; 138 | 139 | private: 140 | 141 | 142 | }; 143 | -------------------------------------------------------------------------------- /src/utils/ofxMeshUtils.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ofxMeshUtils.h" 3 | 4 | 5 | //-------------------------------------------------------------------------- 6 | ofMesh ofxMeshUtils::getIndiciedMeshFromNonIndiciedMesh( ofMesh & mesh ){ 7 | 8 | ofMesh newMesh; 9 | vector < ofPoint > uniqueVertices; 10 | for (int i = 0; i < mesh.getVertices().size(); i++){ 11 | 12 | int id = -1; 13 | for (int j = 0; j < uniqueVertices.size(); j++){ 14 | if ( (uniqueVertices[j] - mesh.getVertices()[i]).length() < 0.1f){ 15 | id = j; 16 | } 17 | } 18 | 19 | if (id == -1){ 20 | uniqueVertices.push_back(mesh.getVertices()[i]); 21 | id = uniqueVertices.size() - 1; 22 | newMesh.addVertex(mesh.getVertices()[i]); 23 | } 24 | 25 | newMesh.addIndex(id); 26 | } 27 | return newMesh; 28 | } 29 | 30 | 31 | 32 | //-------------------------------------------------------------------------- 33 | void ofxMeshUtils::calcNormals( ofMesh & mesh, bool bNormalize ){ 34 | 35 | for( int i=0; i < mesh.getVertices().size(); i++ ) mesh.addNormal(ofPoint(0,0,0)); 36 | 37 | for( int i=0; i < mesh.getIndices().size(); i+=3 ){ 38 | const int ia = mesh.getIndices()[i]; 39 | const int ib = mesh.getIndices()[i+1]; 40 | const int ic = mesh.getIndices()[i+2]; 41 | 42 | glm::vec3 e1 = mesh.getVertices()[ia] - mesh.getVertices()[ib]; 43 | glm::vec3 e2 = mesh.getVertices()[ic] - mesh.getVertices()[ib]; 44 | glm::vec3 no = glm::cross(e1, e2);//e2.cross( e1 ); 45 | 46 | // depending on your clockwise / winding order, you might want to reverse the e2 / e1 above if your normals are flipped. 47 | 48 | mesh.getNormals()[ia] += no; 49 | mesh.getNormals()[ib] += no; 50 | mesh.getNormals()[ic] += no; 51 | } 52 | 53 | if (bNormalize) 54 | for(int i=0; i < mesh.getNormals().size(); i++ ) { 55 | glm::vec3 r = mesh.getNormals()[i]; 56 | mesh.getNormals()[i] = glm::normalize(r); 57 | } 58 | } 59 | 60 | 61 | //-------------------------------------------------------------------------- 62 | ofMesh ofxMeshUtils::loadObj(string filename) { 63 | ofMesh m; 64 | bool smooth = false; 65 | vector v; 66 | vector vt; 67 | ofFile f(filename); 68 | while(!f.eof()) { 69 | string c; 70 | f >> c; 71 | if(c.size()) { 72 | if(c == "v") { 73 | float x, y, z; 74 | f >> x >> y >> z; 75 | if(smooth) { 76 | m.addVertex(ofVec3f(x, y, z)); 77 | } else { 78 | v.push_back(ofVec3f(x, y, z)); 79 | } 80 | } else if(c == "vt") { 81 | float u, v; 82 | f >> u >> v; 83 | if(!smooth) { 84 | vt.push_back(ofVec2f(u, v)); 85 | } 86 | } else if(c == "f") { 87 | string l; 88 | getline(f, l); 89 | replace(l.begin(), l.end(), '/', ' '); 90 | istringstream ls(l); 91 | int vi1, vti1, vi2, vti2, vi3, vti3; 92 | ls >> vi1 >> vti1 >> vi2 >> vti2 >> vi3 >> vti3; 93 | if(smooth) { 94 | m.addIndex(vi1-1); 95 | m.addIndex(vi2-1); 96 | m.addIndex(vi3-1); 97 | } else { 98 | m.addVertex(v[vi1-1]); 99 | m.addVertex(v[vi2-1]); 100 | m.addVertex(v[vi3-1]); 101 | m.addTexCoord(vt[vti1-1]); 102 | m.addTexCoord(vt[vti2-1]); 103 | m.addTexCoord(vt[vti3-1]); 104 | } 105 | if(ls.peek() == ' ') { 106 | int vi4, vti4; 107 | ls >> vi4 >> vti4; 108 | if(smooth) { 109 | m.addIndex(vi1-1); 110 | m.addIndex(vi3-1); 111 | m.addIndex(vi4-1); 112 | } else { 113 | m.addVertex(v[vi1-1]); 114 | m.addVertex(v[vi3-1]); 115 | m.addVertex(v[vi4-1]); 116 | m.addTexCoord(vt[vti1-1]); 117 | m.addTexCoord(vt[vti2-1]); 118 | m.addTexCoord(vt[vti3-1]); 119 | } 120 | } 121 | } 122 | } 123 | } 124 | return m; 125 | 126 | } 127 | 128 | -------------------------------------------------------------------------------- /src/utils/ofxMeshUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | 5 | class ofxMeshUtils { 6 | 7 | public: 8 | 9 | // TODO: doesn't assume any texture coordinates or normals 10 | 11 | //-------------------------------------------------------------------------- 12 | static ofMesh getIndiciedMeshFromNonIndiciedMesh( ofMesh & mesh ); 13 | 14 | // this function expects a mesh of the type OF_PRIMITIVE_TRIANGLES 15 | // w/ indices (ie, getIndices().size() > 0) 16 | // if you can normalize in your shader, you can turn off bNormalize to help 17 | // see: http://www.iquilezles.org/www/articles/normals/normals.htm 18 | 19 | //-------------------------------------------------------------------------- 20 | static void calcNormals( ofMesh & mesh, bool bNormalize = true ); 21 | 22 | //-------------------------------------------------------------------------- 23 | static ofMesh loadObj(string filename); 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /src/utils/ofxTimer.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | 3 | Copyright (c) 2009, Todd Vanderlin, www.vanderlin.cc 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | ***********************************************************************/ 19 | 20 | #include "ofxTimer.h" 21 | 22 | ofxTimer::ofxTimer() { 23 | } 24 | 25 | ofxTimer::~ofxTimer() { 26 | ofRemoveListener(ofEvents().update, this, &ofxTimer::update); 27 | //printf("*** Timer Destroyed ***\n"); 28 | } 29 | 30 | // --------------------------------------- 31 | 32 | void ofxTimer::setup(float millSeconds, bool loopTimer) { 33 | 34 | count = 0; 35 | bLoop = loopTimer; 36 | bPauseTimer = false; 37 | 38 | //timer 39 | bStartTimer = true; 40 | bTimerFinished = false; 41 | delay = millSeconds; // mill seconds 42 | timer = 0; 43 | timerStart = 0; 44 | 45 | paused = false; 46 | resumed = false; 47 | 48 | //events 49 | ofAddListener(ofEvents().update, this, &ofxTimer::update); 50 | 51 | } 52 | 53 | // --------------------------------------- 54 | void ofxTimer::pauseTimer() { 55 | paused = true; 56 | pauseStartTime = ofGetElapsedTimef(); 57 | } 58 | 59 | // --------------------------------------- 60 | void ofxTimer::resumeTimer() { 61 | resumed = true; 62 | paused = false; 63 | pauseTime = ofGetElapsedTimef() - pauseStartTime; 64 | } 65 | 66 | // --------------------------------------- 67 | void ofxTimer::reset() { 68 | count = 0; 69 | timer = 0; 70 | timerStart = 0; 71 | bStartTimer = true; 72 | bTimerFinished = false; 73 | resumed = false; 74 | paused = false; 75 | } 76 | 77 | // --------------------------------------- 78 | void ofxTimer::loop(bool b) { 79 | bLoop = b; 80 | } 81 | 82 | // --------------------------------------- 83 | void ofxTimer::update(ofEventArgs &e) { 84 | 85 | if (paused) 86 | return; 87 | 88 | if (!bPauseTimer) { 89 | if (bStartTimer) { 90 | bStartTimer = false; 91 | timerStart = ofGetElapsedTimef(); 92 | } 93 | 94 | float time = ofGetElapsedTimef() - timerStart; 95 | 96 | if (resumed) { 97 | time -= pauseTime; 98 | } 99 | 100 | time *= 1000.0; 101 | if (time >= delay) { 102 | count++; 103 | if (!bLoop) { 104 | bPauseTimer = true; 105 | bTimerFinished = true; //TODO noch kein unterschied zu bPaused; 106 | } 107 | paused = false; 108 | resumed = false; 109 | 110 | bStartTimer = true; 111 | static ofEventArgs timerEventArgs; 112 | ofNotifyEvent(TIMER_REACHED, timerEventArgs, this); 113 | } 114 | } 115 | } 116 | 117 | float ofxTimer::getTimeLeftInSeconds() { 118 | 119 | if (bTimerFinished) 120 | return 0; 121 | 122 | if (bStartTimer) { 123 | return delay / 1000.f; 124 | } 125 | 126 | float time = ofGetElapsedTimef() - timerStart; 127 | 128 | if (resumed) { 129 | time = (ofGetElapsedTimef() - timerStart - pauseTime); 130 | } 131 | 132 | if (paused) { 133 | time = (ofGetElapsedTimef() - timerStart - ofGetElapsedTimef() 134 | + pauseStartTime); 135 | } 136 | 137 | return (delay / 1000.0) - time; 138 | } 139 | 140 | float ofxTimer::getTimeLeftInMillis() { 141 | 142 | if (bTimerFinished) 143 | return 0; 144 | 145 | if (bStartTimer) { 146 | return delay; 147 | } 148 | 149 | float time = ofGetElapsedTimef() - timerStart; 150 | 151 | if (resumed) { 152 | time = (ofGetElapsedTimef() - timerStart - pauseTime); 153 | } 154 | 155 | if (paused) { 156 | time = (ofGetElapsedTimef() - timerStart - ofGetElapsedTimef() 157 | + pauseStartTime); 158 | } 159 | 160 | return delay - (time * 1000.0); 161 | } 162 | 163 | // --------------------------------------- 164 | void ofxTimer::setTimer(float millSeconds) { 165 | delay = millSeconds; 166 | } 167 | 168 | void ofxTimer::startTimer() { 169 | bPauseTimer = false; 170 | } 171 | 172 | void ofxTimer::stopTimer() { 173 | bPauseTimer = true; 174 | } 175 | 176 | bool ofxTimer::isTimerFinished() { 177 | return bTimerFinished; 178 | } 179 | -------------------------------------------------------------------------------- /src/utils/ofxTimer.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | 3 | Copyright (c) 2009, Todd Vanderlin, www.vanderlin.cc 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | ***********************************************************************/ 19 | 20 | #pragma once 21 | #include "ofMain.h" 22 | 23 | class ofxTimer { 24 | 25 | private: 26 | 27 | 28 | // timer 29 | bool bLoop; 30 | bool bPauseTimer; 31 | bool bStartTimer; 32 | bool bTimerFinished; 33 | float delay; 34 | float timer; 35 | float timerStart; 36 | // Modifs 37 | float pauseStartTime; 38 | float pauseTime; 39 | bool paused; 40 | bool resumed; 41 | 42 | void update(ofEventArgs &e); 43 | 44 | public: 45 | 46 | int count; 47 | ofEvent TIMER_REACHED; 48 | 49 | ofxTimer(); 50 | ~ofxTimer(); 51 | 52 | // --------------------------------------- 53 | void reset(); 54 | void setup(float millSeconds, bool loopTimer); 55 | //void draw(); 56 | 57 | // --------------------------------------- 58 | void setTimer(float millSeconds); 59 | float getTimeLeftInSeconds(); 60 | float getTimeLeftInMillis(); 61 | void startTimer(); 62 | void stopTimer(); 63 | void pauseTimer(); 64 | void resumeTimer(); 65 | void loop(bool b); 66 | bool isTimerFinished(); 67 | }; 68 | -------------------------------------------------------------------------------- /src/utils/socketCS.cpp: -------------------------------------------------------------------------------- 1 | #define _WINSOCK_DEPRECATED_NO_WARNINGS 2 | 3 | #include "SocketCS.h" 4 | #pragma comment(lib, "ws2_32.lib") 5 | #include 6 | 7 | using namespace std; 8 | 9 | int NCSocket::nofSockets_= 0; 10 | 11 | void NCSocket::Start() { 12 | if (!nofSockets_) { 13 | WSADATA info; 14 | if (WSAStartup(MAKEWORD(2,0), &info)) { 15 | throw "Could not start WSA"; 16 | } 17 | } 18 | ++nofSockets_; 19 | //std::cout << "socket created"<< std::endl; 20 | } 21 | 22 | void NCSocket::End() { 23 | WSACleanup(); 24 | } 25 | 26 | NCSocket::NCSocket() : s_(0) { 27 | Start(); 28 | // UDP: use SOCK_DGRAM instead of SOCK_STREAM 29 | s_ = socket(AF_INET,SOCK_STREAM,0); 30 | 31 | if (s_ == INVALID_SOCKET) { 32 | throw "INVALID_SOCKET"; 33 | } 34 | 35 | refCounter_ = new int(1); 36 | } 37 | 38 | NCSocket::NCSocket(SOCKET s) : s_(s) { 39 | Start(); 40 | refCounter_ = new int(1); 41 | }; 42 | 43 | NCSocket::~NCSocket() { 44 | if (! --(*refCounter_)) { 45 | Close(); 46 | delete refCounter_; 47 | } 48 | 49 | --nofSockets_; 50 | if (!nofSockets_) End(); 51 | } 52 | 53 | NCSocket::NCSocket(const NCSocket& o) { 54 | refCounter_=o.refCounter_; 55 | (*refCounter_)++; 56 | s_ =o.s_; 57 | 58 | nofSockets_++; 59 | 60 | } 61 | 62 | NCSocket& NCSocket::operator=(NCSocket& o) { 63 | (*o.refCounter_)++; 64 | 65 | refCounter_=o.refCounter_; 66 | s_ =o.s_; 67 | 68 | nofSockets_++; 69 | 70 | return *this; 71 | } 72 | 73 | void NCSocket::Close() { 74 | closesocket(s_); 75 | } 76 | 77 | int NCSocket::ReceiveBytesInt() { 78 | int currentsizeone = 0; 79 | int rvone = 0; 80 | char buf[4]; 81 | rvone = recv(s_, buf, 4, 0); 82 | int value; 83 | memcpy(&value, buf, 4); 84 | return value; 85 | } 86 | 87 | ofBuffer NCSocket::ReceiveBytesofBuffer(int bytestoreceive) { 88 | 89 | int currentsize = 0; 90 | int rv = 0; 91 | 92 | ofBuffer buffer; 93 | 94 | do { 95 | char buftwo[1024]; 96 | rv = recv(s_, buftwo, 1024, 0); 97 | 98 | if (rv > 0) { 99 | //cout << "wim says: " << currentsize << " : " << bytestoreceive << " : " << rv << endl; 100 | currentsize = currentsize + rv; 101 | buffer.append(buftwo, rv); 102 | 103 | } 104 | else { 105 | //cout << "wim says ooh where is the client" << endl; 106 | //Close(); 107 | break; 108 | } 109 | } while (currentsize 1024) arg = 1024; 129 | 130 | int rv = recv (s_, buf, arg, 0); 131 | //cout << rv << endl; 132 | 133 | 134 | if (rv <= 0) break; 135 | 136 | std::string t; 137 | 138 | t.assign (buf, rv); 139 | ret += t; 140 | 141 | } 142 | 143 | return ret; 144 | } 145 | 146 | std::string NCSocket::ReceiveLine() { 147 | std::string ret; 148 | while (1) { 149 | char r; 150 | 151 | switch(recv(s_, &r, 1, 0)) { 152 | case 0: // not connected anymore; 153 | // ... but last line sent 154 | // might not end in \n, 155 | // so return ret anyway. 156 | return ret; 157 | case -1: 158 | return ""; 159 | // if (errno == EAGAIN) { 160 | // return ret; 161 | // } else { 162 | // // not connected anymore 163 | // return ""; 164 | // } 165 | } 166 | 167 | ret += r; 168 | if (r == '\n') return ret; 169 | } 170 | } 171 | 172 | void NCSocket::SendLine(std::string s) { 173 | s += '\n'; 174 | int r = send(s_,s.c_str(),s.length(),0); 175 | // cout << r << endl; 176 | } 177 | 178 | void NCSocket::SendBytes(const char *buf, int len) { 179 | send(s_,buf,len,0); 180 | } 181 | 182 | SocketServer::SocketServer(int port, int connections, TypeSocket type) { 183 | sockaddr_in sa; 184 | 185 | memset(&sa, 0, sizeof(sa)); 186 | 187 | sa.sin_family = PF_INET; 188 | sa.sin_port = htons(port); 189 | s_ = socket(AF_INET, SOCK_STREAM, 0); 190 | if (s_ == INVALID_SOCKET) { 191 | throw "INVALID_SOCKET"; 192 | } 193 | 194 | if(type==NonBlockingSocket) { 195 | u_long arg = 1; 196 | ioctlsocket(s_, FIONBIO, &arg); 197 | } 198 | 199 | /* bind the socket to the internet address */ 200 | if (::bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) { 201 | closesocket(s_); 202 | throw "INVALID_SOCKET"; 203 | } 204 | 205 | listen(s_, connections); 206 | 207 | } 208 | 209 | NCSocket* SocketServer::Accept() { 210 | SOCKET new_sock = accept(s_, 0, 0); 211 | if (new_sock == INVALID_SOCKET) { 212 | int rc = WSAGetLastError(); 213 | if(rc==WSAEWOULDBLOCK) { 214 | return 0; // non-blocking call, no request pending 215 | } 216 | else { 217 | throw "Invalid Socket"; 218 | } 219 | } 220 | 221 | NCSocket* r = new NCSocket(new_sock); 222 | return r; 223 | } 224 | 225 | SocketClient::SocketClient(const std::string& _host, int _port) : NCSocket() { 226 | host = _host; 227 | port = _port; 228 | } 229 | 230 | bool SocketClient::connect() { 231 | std::string error; 232 | hostent *he; 233 | if ((he = gethostbyname(host.c_str())) == 0) { 234 | error = strerror(errno); 235 | cout << "wrong host address" << endl; 236 | } 237 | sockaddr_in addr; 238 | addr.sin_family = AF_INET; 239 | addr.sin_port = htons(port); 240 | addr.sin_addr = *((in_addr *)he->h_addr); 241 | memset(&(addr.sin_zero), 0, 8); 242 | if (::connect(s_, (sockaddr *)&addr, sizeof(sockaddr))) { 243 | error = strerror(WSAGetLastError()); 244 | cout << "could not connect to server: " << error << endl; 245 | return false; 246 | } 247 | else { 248 | cout << "connected" << endl; 249 | return true; 250 | } 251 | 252 | return false; 253 | } 254 | SocketSelect::SocketSelect(NCSocket const * const s1, NCSocket const * const s2, TypeSocket type) { 255 | FD_ZERO(&fds_); 256 | FD_SET(const_cast(s1)->s_,&fds_); 257 | if(s2) { 258 | FD_SET(const_cast(s2)->s_,&fds_); 259 | } 260 | 261 | TIMEVAL tval; 262 | tval.tv_sec = 0; 263 | tval.tv_usec = 1; 264 | 265 | TIMEVAL *ptval; 266 | if(type==NonBlockingSocket) { 267 | ptval = &tval; 268 | } 269 | else { 270 | ptval = 0; 271 | } 272 | 273 | if (select (0, &fds_, (fd_set*) 0, (fd_set*) 0, ptval) == SOCKET_ERROR) 274 | throw "Error in select"; 275 | } 276 | 277 | bool SocketSelect::Readable(NCSocket const* const s) { 278 | if (FD_ISSET(s->s_,&fds_)) return true; 279 | return false; 280 | } -------------------------------------------------------------------------------- /src/utils/socketCS.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearenocomputer/ofxNCKinect/326e365324ba7494437c166f8cf1c17310014208/src/utils/socketCS.h -------------------------------------------------------------------------------- /src/utils/tcpClient/ncKinectSender.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectSender.h" 2 | 3 | 4 | //-------------------------------------------------------------- 5 | void ncKinectSender::setup(int _id, string _host, int _port){ 6 | 7 | id = _id; 8 | host = _host; 9 | port = _port; 10 | 11 | bisthreadrunning = false; 12 | bisconnected = false; 13 | 14 | gui.setup("TCP", "_settings/tcp_sender.xml"); 15 | gui.add(sleeptime.set("sleeptime", sleeptime, 1, 1000)); 16 | gui.add(bsendpointcloud.set("send pointcloud", true)); 17 | gui.loadFromFile("_settings/tcp_sender.xml"); 18 | 19 | start(); 20 | } 21 | 22 | void ncKinectSender::drawGUI() 23 | { 24 | gui.draw(); 25 | } 26 | 27 | 28 | //-------------------------------------------------------------- 29 | void ncKinectSender::start() { 30 | startThread(); 31 | } 32 | 33 | //-------------------------------------------------------------- 34 | void ncKinectSender::stop() { 35 | if (bisthreadrunning) { 36 | 37 | if (bisconnected) { 38 | client->Close(); 39 | } 40 | 41 | bisthreadrunning = false; 42 | waitForThread(); 43 | } 44 | } 45 | 46 | 47 | //-------------------------------------------------------------- 48 | void ncKinectSender::threadedFunction() { 49 | bisthreadrunning = true; 50 | 51 | //CREATE THE SERVER SOCKET 52 | 53 | while (bisthreadrunning) { 54 | 55 | int timeouts = 0; 56 | client = new SocketClient(host, port); 57 | bisconnected = client->connect(); 58 | 59 | if (bisconnected) { 60 | bool bWorkdone = false; 61 | while (!bWorkdone) { 62 | sleep(sleeptime); 63 | string t = client->ReceiveLine(); 64 | if (t.size() == 0) { 65 | timeouts++; 66 | if (timeouts == 20) { 67 | bWorkdone = true; 68 | client->Close(); 69 | bisconnected = false; 70 | } 71 | } 72 | //SEND DATA HERE 73 | mutex.lock(); 74 | int buffersize = buffer.size(); 75 | //cout << "wim says sending header with num bytes: " << buffersize << endl; 76 | client->SendBytes((char*)&buffersize, sizeof(int)); 77 | sleep(sleeptime); 78 | //cout << "wim says sending data : " << buffersize << endl; 79 | client->SendBytes((const char *)buffer.getData(), buffersize); 80 | mutex.unlock(); 81 | sleep(sleeptime); 82 | } 83 | 84 | } 85 | } 86 | bisconnected = false; 87 | bisthreadrunning = false; 88 | } 89 | 90 | void ncKinectSender::setBuffer(ofBuffer _buffer) 91 | { 92 | mutex.lock(); 93 | buffer = _buffer; 94 | mutex.unlock(); 95 | } 96 | -------------------------------------------------------------------------------- /src/utils/tcpClient/ncKinectSender.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGui.h" 5 | #include "socketCS.h" 6 | 7 | class ncKinectSender : public ofThread { 8 | 9 | public: 10 | void setup(int _id, string _host, int _port); 11 | void drawGUI(); 12 | 13 | void start(); 14 | void stop(); 15 | 16 | void threadedFunction(); 17 | 18 | bool bisthreadrunning; 19 | bool bisconnected; 20 | 21 | ofParameter bsendpointcloud; 22 | 23 | ofMutex mutex; 24 | 25 | void setBuffer(ofBuffer _buffer); 26 | 27 | private: 28 | 29 | int id; 30 | string host; 31 | int port; 32 | SocketClient *client; 33 | 34 | ofBuffer buffer; 35 | 36 | ofxPanel gui; 37 | ofParameter sleeptime; 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /src/utils/tcpServer/NCKinectV2Objects.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ofMain.h" 3 | 4 | 5 | 6 | class NCJoints :public ofNode { 7 | public: 8 | 9 | ofSpherePrimitive sphere; 10 | vector positions; 11 | 12 | virtual void setup() { 13 | sphere.set(0.05, 10); 14 | } 15 | 16 | virtual void customDraw() { 17 | 18 | for (int i = 0; i < positions.size(); ++i) { 19 | transformGL(); 20 | sphere.setGlobalPosition(positions[i]); 21 | sphere.drawWireframe(); 22 | restoreTransformGL(); 23 | } 24 | 25 | } 26 | }; 27 | 28 | 29 | class NCKinectPointcloud3DModel : public ofNode { 30 | 31 | public: 32 | 33 | ofMesh mesh; 34 | 35 | virtual void setup() { 36 | mesh.setMode(OF_PRIMITIVE_POINTS); 37 | mesh.getVertices().resize(512 * 424); 38 | } 39 | 40 | virtual void customDraw() { 41 | transformGL(); 42 | mesh.draw(); 43 | restoreTransformGL(); 44 | } 45 | 46 | }; 47 | 48 | 49 | class NCKinectCamera3DModel : public ofNode { 50 | 51 | public: 52 | 53 | ofBoxPrimitive model; 54 | 55 | virtual void setup() { 56 | model.set(0.3, 0.1, 0.1); 57 | } 58 | 59 | virtual void customDraw() { 60 | transformGL(); 61 | ofDrawAxis(0.5); 62 | model.drawWireframe(); 63 | restoreTransformGL(); 64 | } 65 | 66 | }; 67 | 68 | 69 | class NCKinectScene : public ofNode { 70 | 71 | public: 72 | 73 | NCKinectCamera3DModel camera; 74 | NCKinectPointcloud3DModel pointcloud; 75 | ofVec4f floorplane; 76 | vector heads; 77 | ofVec3f cameraposition; 78 | ofQuaternion camerarotation; 79 | 80 | bool bDoCameraToWorld; 81 | bool bDrawPointCloud; 82 | bool bDrawJoints; 83 | bool bDrawCamera; 84 | 85 | ofColor skeletoncolor; 86 | 87 | 88 | virtual void setup() { 89 | cameraposition = ofVec3f(0, 0, 0); 90 | camerarotation = ofQuaternion(0, ofVec3f(1, 0, 0), 0, ofVec3f(0, 1, 0), 0, ofVec3f(0, 0, 1)); 91 | bDoCameraToWorld = true; 92 | bDrawCamera = true; 93 | bDrawJoints = true; 94 | bDrawPointCloud = true; 95 | camera.setup(); 96 | pointcloud.setup(); 97 | srand(time(NULL)); 98 | skeletoncolor = ofColor(ofRandom(0, 255), ofRandom(0, 255), ofRandom(0, 255)); 99 | setGlobalPosition(cameraposition); 100 | } 101 | 102 | virtual void customDraw() { 103 | 104 | if (bDoCameraToWorld) { 105 | restoreTransformGL(); 106 | transformGL(); 107 | //http://blog.hackandi.com/inst/blog/2014/03/18/convert-kinect-cameraspace-to-worldspace-relative-to-floor/ 108 | ofVec3f up = ofVec3f(floorplane.x, floorplane.y, floorplane.z); 109 | ofVec3f forward = up.getCrossed(ofVec3f(1, 0, 0)); 110 | forward.normalize(); 111 | ofVec3f right = up.getCrossed(forward); 112 | ofMatrix4x4 mymat = ofMatrix4x4( 113 | right.x, up.x, forward.x, 0, 114 | right.y, up.y, forward.y, 0, 115 | right.z, up.z, forward.z, 0, 116 | 0, floorplane.w, 0, 1); 117 | 118 | ofMatrix4x4 currenttranslation; 119 | currenttranslation.translate(cameraposition); 120 | ofMatrix4x4 currentrotation; 121 | currentrotation.rotate(camerarotation); 122 | 123 | setTransformMatrix(mymat*currentrotation*currenttranslation); 124 | 125 | if (bDrawCamera) { 126 | camera.draw(); 127 | } 128 | 129 | if (bDrawPointCloud) { 130 | pointcloud.draw(); 131 | } 132 | 133 | if (bDrawJoints) { 134 | ofSetColor(skeletoncolor); 135 | for (int i = 0; i < heads.size(); i++) { 136 | heads[i].customDraw(); 137 | } 138 | ofSetColor(255); 139 | } 140 | restoreTransformGL(); 141 | } 142 | else { 143 | 144 | transformGL(); 145 | resetTransform(); 146 | ofMatrix4x4 currenttranslation; 147 | currenttranslation.translate(cameraposition); 148 | 149 | ofMatrix4x4 currentrotation; 150 | currentrotation.rotate(camerarotation); 151 | 152 | setTransformMatrix(currentrotation*currenttranslation); 153 | 154 | if (bDrawCamera) { 155 | camera.draw(); 156 | } 157 | 158 | if (bDrawPointCloud) { 159 | pointcloud.draw(); 160 | } 161 | 162 | if (bDrawJoints) { 163 | ofSetColor(skeletoncolor); 164 | for (int i = 0; i < heads.size(); i++) { 165 | heads[i].customDraw(); 166 | } 167 | ofSetColor(255); 168 | } 169 | 170 | restoreTransformGL(); 171 | } 172 | } 173 | 174 | virtual void setTransformMatrix(const ofMatrix4x4 &m44) { 175 | ofVec3f position; 176 | ofQuaternion orientation; 177 | ofVec3f scale; 178 | ofQuaternion so; 179 | m44.decompose(position, orientation, scale, so); 180 | setPosition(position); 181 | setOrientation(orientation); 182 | setScale(scale); 183 | updateAxis(); 184 | onPositionChanged(); 185 | onOrientationChanged(); 186 | onScaleChanged(); 187 | } 188 | }; -------------------------------------------------------------------------------- /src/utils/tcpServer/ncKinectReceiver.cpp: -------------------------------------------------------------------------------- 1 | #include "ncKinectReceiver.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ncKinectReceiver::setup(int _port, int _id) { 5 | 6 | port = _port; 7 | bisthreadrunning = false; 8 | bisconnected = false; 9 | sleeptime = 5; 10 | 11 | gui.setup("TCP", "_settings/tcp_receiver_"+ofToString(_id)+".xml"); 12 | gui.add(sleeptime.set("sleeptime", sleeptime, 1, 1000)); 13 | gui.add(kinectcamxpos.set("kinect x pos", 0, -5, 5)); 14 | gui.add(kinectcamypos.set("kinect y pos", 0, -5, 5)); 15 | gui.add(kinectcamzpos.set("kinect z pos", 0, -5, 5)); 16 | gui.add(kinectyrotation.set("kinect y rotation", 0, -90, 90)); 17 | gui.loadFromFile("_settings/tcp_receiver_" + ofToString(_id) + ".xml"); 18 | 19 | kinectscene.setup(); 20 | 21 | start(); 22 | } 23 | 24 | void ncKinectReceiver::update() { 25 | 26 | kinectscene.cameraposition = ofVec3f(kinectcamxpos, kinectcamypos, kinectcamzpos); 27 | kinectscene.camerarotation = ofQuaternion(kinectyrotation, ofVec3f(0, 1, 0)); 28 | } 29 | 30 | void ncKinectReceiver::draw() { 31 | kinectscene.customDraw(); 32 | } 33 | 34 | void ncKinectReceiver::drawGUI() { 35 | gui.draw(); 36 | } 37 | 38 | void ncKinectReceiver::start() { 39 | bisconnected = false; 40 | startThread(); 41 | } 42 | 43 | void ncKinectReceiver::stop() { 44 | if (bisthreadrunning) { 45 | receiver_one->Close(); 46 | delete receiver_one; 47 | receiver_one = NULL; 48 | bisthreadrunning = false; 49 | waitForThread(); 50 | } 51 | } 52 | 53 | //-------------------------------------------------------------- 54 | void ncKinectReceiver::threadedFunction() { 55 | cout << "START THREAD" << endl; 56 | receiver_one = new SocketServer(port, NonBlockingSocket); 57 | bisthreadrunning = true; 58 | 59 | while (bisthreadrunning) { 60 | cout << "WAIT FOR SENDER" << endl; 61 | 62 | NCSocket *s = receiver_one->Accept(); 63 | 64 | bool bWorkdone = false; 65 | bisconnected = true; 66 | 67 | cout << "SENDER CONNECTED" << endl; 68 | while (!bWorkdone) { 69 | 70 | s->SendLine("A"); 71 | sleep(sleeptime); 72 | 73 | int numofbytestoreceive = s->ReceiveBytesInt(); 74 | if (numofbytestoreceive == 0) { 75 | bWorkdone = true; 76 | bisconnected = false; 77 | s->Close(); 78 | } 79 | sleep(sleeptime); 80 | 81 | ofBuffer buffer = s->ReceiveBytesofBuffer(numofbytestoreceive); 82 | if (buffer.size() > 0) { 83 | mutex.lock(); 84 | ncKinectSeDeserializer tcpobject; 85 | data = tcpobject.deserialize(buffer); 86 | 87 | kinectscene.pointcloud.mesh.getVertices() = data.vertices; 88 | kinectscene.floorplane = data.floorplane; 89 | 90 | vector heads; 91 | for (int i = 0; i < data.users.size(); i++) { 92 | NCJoints head; 93 | head.setup(); 94 | head.positions = data.users[i].joints3dposition; 95 | heads.push_back(head); 96 | } 97 | kinectscene.heads = heads; 98 | mutex.unlock(); 99 | } 100 | else { 101 | bWorkdone = true; 102 | bisconnected = false; 103 | s->Close(); 104 | } 105 | 106 | sleep(sleeptime); 107 | 108 | 109 | } 110 | s->Close(); 111 | bisconnected = false; 112 | 113 | } 114 | bisconnected = false; 115 | bisthreadrunning = false; 116 | 117 | } 118 | 119 | ncKinectSeDeSerObject ncKinectReceiver::getData() 120 | { 121 | ncKinectSeDeSerObject tosend; 122 | if (bisconnected) { 123 | mutex.lock(); 124 | tosend = data; 125 | mutex.unlock(); 126 | } 127 | return tosend; 128 | } 129 | -------------------------------------------------------------------------------- /src/utils/tcpServer/ncKinectReceiver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ncKinectSeDeserializer.h" 5 | #include "NCKinectV2Objects.h" 6 | #include "ofxGui.h" 7 | #include "socketCS.h" 8 | 9 | class ncKinectReceiver : public ofThread { 10 | 11 | public: 12 | void setup(int _port, int _id); 13 | void update(); 14 | void draw(); 15 | 16 | void drawGUI(); 17 | 18 | 19 | void start(); 20 | void stop(); 21 | 22 | void threadedFunction(); 23 | 24 | bool bisthreadrunning; 25 | bool bisconnected; 26 | 27 | ncKinectSeDeSerObject getData(); 28 | ofMutex mutex; 29 | 30 | private: 31 | SocketServer *receiver_one; 32 | 33 | ncKinectSeDeSerObject data; 34 | 35 | ofxPanel gui; 36 | ofParameter sleeptime; 37 | ofParameter kinectcamxpos; 38 | ofParameter kinectcamypos; 39 | ofParameter kinectcamzpos; 40 | ofParameter kinectyrotation; 41 | 42 | int port; 43 | NCKinectScene kinectscene; 44 | 45 | 46 | }; 47 | --------------------------------------------------------------------------------