Skip to content

Commit a27686f

Browse files
authored
Merge pull request #25 from mitmedialab/telepresence-simple-kinect-v2
Simplified Kinect manager and Telepresence mode
2 parents 572a1ac + 56d2740 commit a27686f

21 files changed

+616
-161
lines changed

bin/data/SourceSans3-Regular.ttf

372 KB
Binary file not shown.

neoForm.xcodeproj/project.pbxproj

+12
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
B006626C26FF99AB717C7CD4 /* utf8_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = D1822FF66A31138F103D3C2F /* utf8_mosq.c */; };
7777
B266578FC55D23BFEBC042E7 /* ofxGuiGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ECF8674C7975F1063C5E30CA /* ofxGuiGroup.cpp */; };
7878
B56FE57CC35806596D38118C /* ofxSliderGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 802251BAF1B35B1D67B32FD0 /* ofxSliderGroup.cpp */; };
79+
B916F1112D1F503800BC378D /* kinectManagerSimple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B916F10F2D1F503800BC378D /* kinectManagerSimple.cpp */; };
80+
B916F1142D20C87A00BC378D /* Telepresence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B916F1132D20C87A00BC378D /* Telepresence.cpp */; };
7981
B917C91A2D0F882700F26C4C /* AmbientWave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B917C9182D0F882700F26C4C /* AmbientWave.cpp */; };
8082
B917C91D2D0F8E3400F26C4C /* TransitionApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B917C91B2D0F8E3300F26C4C /* TransitionApp.cpp */; };
8183
B951ED692CEA6F6E00C74190 /* WaveModeContours.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B951ED652CEA6F6E00C74190 /* WaveModeContours.cpp */; };
@@ -572,6 +574,10 @@
572574
B88A80AA34B79BD6DA9253DE /* sse_utils.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = sse_utils.hpp; path = ../../../addons/ofxOpenCv/libs/opencv/include/opencv4/opencv2/core/sse_utils.hpp; sourceTree = SOURCE_ROOT; };
573575
B8A2CBF3E24E6E5026B13A90 /* ofxBase3DVideo.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ofxBase3DVideo.h; path = ../../../addons/ofxKinect/src/ofxBase3DVideo.h; sourceTree = SOURCE_ROOT; };
574576
B8F39F6EBA0607ECB7D18D89 /* handle_disconnect.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 4; name = handle_disconnect.c; path = "../../../addons/ofxMQTT-1.5.0/libs/mosquitto/src/handle_disconnect.c"; sourceTree = SOURCE_ROOT; };
577+
B916F10F2D1F503800BC378D /* kinectManagerSimple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = kinectManagerSimple.cpp; path = KinectManager/kinectManagerSimple.cpp; sourceTree = "<group>"; };
578+
B916F1102D1F503800BC378D /* KinectManagerSimple.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = KinectManagerSimple.hpp; path = KinectManager/KinectManagerSimple.hpp; sourceTree = "<group>"; };
579+
B916F1122D20C87A00BC378D /* Telepresence.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Telepresence.hpp; path = Applications/Telepresence.hpp; sourceTree = "<group>"; };
580+
B916F1132D20C87A00BC378D /* Telepresence.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Telepresence.cpp; path = Applications/Telepresence.cpp; sourceTree = "<group>"; };
575581
B917C9182D0F882700F26C4C /* AmbientWave.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AmbientWave.cpp; path = Applications/AmbientWave.cpp; sourceTree = "<group>"; };
576582
B917C9192D0F882700F26C4C /* AmbientWave.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AmbientWave.hpp; path = Applications/AmbientWave.hpp; sourceTree = "<group>"; };
577583
B917C91B2D0F8E3300F26C4C /* TransitionApp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TransitionApp.cpp; path = Applications/TransitionApp.cpp; sourceTree = "<group>"; };
@@ -1711,6 +1717,8 @@
17111717
371A3F038DAEE97357696076 /* MqttTransmissionApp.cpp */,
17121718
9173510537C7D6FE1E419118 /* SinglePinDebug.hpp */,
17131719
1EBB8A7F45CEE5C6E85F5CCA /* SinglePinDebug.cpp */,
1720+
B916F1122D20C87A00BC378D /* Telepresence.hpp */,
1721+
B916F1132D20C87A00BC378D /* Telepresence.cpp */,
17141722
AE527AF4F7B13F64D57C5A79 /* VideoPlayerApp.hpp */,
17151723
F4FC5A5BDD199FB703850D0B /* VideoPlayerApp.cpp */,
17161724
B951ED662CEA6F6E00C74190 /* WaveModeContours.hpp */,
@@ -1855,6 +1863,8 @@
18551863
908777B64CF600EA529CC7B2 /* KinectManager */ = {
18561864
isa = PBXGroup;
18571865
children = (
1866+
B916F10F2D1F503800BC378D /* kinectManagerSimple.cpp */,
1867+
B916F1102D1F503800BC378D /* KinectManagerSimple.hpp */,
18581868
9539AAE52CF78FE5E2AF134B /* KinectManager.cpp */,
18591869
5193EDEA22E0D8246414432A /* KinectTracker.cpp */,
18601870
4A4E9C4F8DC15EE848455F2E /* KinectManager.hpp */,
@@ -2903,6 +2913,7 @@
29032913
1985F508DABADFBFD7EE6A21 /* thread_mosq.c in Sources */,
29042914
1F0F9FBF69381509F6969127 /* time_mosq.c in Sources */,
29052915
F527E399D8A82479A7082187 /* tls_mosq.c in Sources */,
2916+
B916F1142D20C87A00BC378D /* Telepresence.cpp in Sources */,
29062917
B006626C26FF99AB717C7CD4 /* utf8_mosq.c in Sources */,
29072918
549DA215810C4915DA94ED9F /* util_mosq.c in Sources */,
29082919
BCC0588F6EE7A6B94548C546 /* util_topic.c in Sources */,
@@ -2919,6 +2930,7 @@
29192930
169D3C72FDE6C5590A1616F5 /* ofxCvFloatImage.cpp in Sources */,
29202931
FB09C6B2A1DA0EA217240CB8 /* ofxCvGrayscaleImage.cpp in Sources */,
29212932
E212C821D1064B92DD953A42 /* ofxCvHaarFinder.cpp in Sources */,
2933+
B916F1112D1F503800BC378D /* kinectManagerSimple.cpp in Sources */,
29222934
63020F16C7E8DED980111241 /* ofxCvImage.cpp in Sources */,
29232935
D3301F6A0B43BB293ED97C1D /* ofxCvShortImage.cpp in Sources */,
29242936
933A2227713C720CEFF80FD9 /* tinyxml.cpp in Sources */,

src/AppManager.cpp

+104-30
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void AppManager::setup() {
2727
// kinectManager = new KinectManager();
2828
// Depth thresholds for the kinect are set here.
2929

30-
kinectManager = new KinectManager(255, 90, 20);
30+
kinectManager = new KinectManagerSimple();
3131

3232
// zero timeOfLastUpdate tracker
3333
timeOfLastUpdate = elapsedTimeInSeconds();
@@ -58,6 +58,11 @@ void AppManager::setup() {
5858

5959
kinectHandWavy = new KinectHandWavy(m_serialShapeIOManager, kinectManager);
6060
applications["kinectHandWavy"] = kinectHandWavy;
61+
62+
// Telepresence mode takes 16 bit thresholding values as parameters here.
63+
telepresence = new Telepresence(m_serialShapeIOManager, kinectManager,
64+
255 * 256, 140 * 256, cam);
65+
applications["telepresence"] = telepresence;
6166

6267
equationMode = new EquationMode(m_serialShapeIOManager);
6368
applications["equationMode"] = equationMode;
@@ -71,28 +76,61 @@ void AppManager::setup() {
7176
ambientWave = new AmbientWave(m_serialShapeIOManager);
7277
applications["AmbientWave"] = ambientWave;
7378

79+
// Set up the order of the applications in the order vector
80+
applicationOrder.push_back("videoPlayer");
81+
applicationOrder.push_back("waveModeContours");
82+
applicationOrder.push_back("equationMode");
83+
applicationOrder.push_back("telepresence");
84+
applicationOrder.push_back("kinectHandWavy");
85+
applicationOrder.push_back("AmbientWave");
86+
applicationOrder.push_back("singlePinDebug");
87+
applicationOrder.push_back("axisChecker");
88+
applicationOrder.push_back("mqttTransmission");
89+
7490
// innitialize GUI
7591
gui.setup("modes:");
76-
gui.setPosition(5, 35);
92+
gui.setPosition(5, 20);
7793

7894
// IMPORTANT: ofxGui uses raw pointers to ofxButton, so an automatic resize
7995
// of modeButtons will invalidate all existing pointers stored in gui.
8096
// DO NOT .push_back MORE THAN applications.size()!!!!
8197
modeButtons.reserve(applications.size());
82-
83-
for (map<string, Application *>::iterator iter = applications.begin(); iter != applications.end(); iter++) {
84-
Application *app = iter->second;
85-
86-
modeButtons.push_back(ofxButton());
87-
modeNames.push_back(iter->first);
88-
auto p_button = modeButtons.back().setup(app->getName());
89-
gui.add(p_button);
90-
91-
// shape display heights, if they are accessible
92-
}
98+
99+
int appIndex = 1; // Initialize an index for iteration
100+
101+
// Iterate over the applicationOrder vector and add the corresponding app to the GUI
102+
for (const auto& appName : applicationOrder) {
103+
Application *app = applications[appName];
104+
105+
modeButtons.push_back(ofxButton());
106+
modeNames.push_back(appName);
107+
108+
// Construct the new button name with the index prepended
109+
std::string buttonName = std::to_string(appIndex) + ": " + app->getName();
110+
auto p_button = modeButtons.back().setup(buttonName);
111+
gui.add(p_button);
112+
113+
appIndex++;
114+
}
115+
116+
// Collapse the GUI panel for now to make room for the new graphical buttons.
117+
gui.minimize();
93118

94119
// set default application
95120
setCurrentApplication("mqttTransmission");
121+
122+
// *** Rectangular button setup ***
123+
// Load a font for the button text.
124+
ofTrueTypeFont::setGlobalDpi(72);
125+
displayFont20.load("SourceSans3-Regular.ttf", 20);
126+
127+
// Set up the buttons by creating an ofRectangle for each application
128+
for (int i = 0; i < applicationOrder.size(); i++){
129+
ofRectangle button;
130+
button.set(20, 60 + 65*i, 240, 50);
131+
applicationButtons.push_back(button);
132+
}
133+
96134
}
97135

98136
// initialize the shape display and set up shape display helper objects
@@ -229,7 +267,7 @@ void AppManager::draw() {
229267

230268
// draw text
231269
int menuLeftCoordinate = 21;
232-
int menuHeight = 350;
270+
int menuHeight = 680;
233271
string title = currentApplication->getName() + (showDebugGui ? " - Debug" : "");
234272
ofDrawBitmapString(title, menuLeftCoordinate, menuHeight);
235273
menuHeight += 30;
@@ -245,12 +283,45 @@ void AppManager::draw() {
245283
menuHeight += 30;
246284

247285
// if there isn't already a debug gui, draw some more information
248-
if (!showDebugGui || currentApplication == applications["water"] || currentApplication == applications["stretchy"]) {
286+
if (!showDebugGui || currentApplication == applications["waveModeContours"] || currentApplication == applications["stretchy"]) {
249287
ofDrawBitmapString(currentApplication->appInstructionsText(),menuLeftCoordinate, menuHeight);
250288
menuHeight += 20;
251289
}
252290

253291
gui.draw();
292+
293+
// Draw the rectangular buttons for each application.
294+
for (int i = 0; i < applicationButtons.size(); i++){
295+
if (applications[applicationOrder[i]] == currentApplication){
296+
// Green for the current application
297+
ofSetColor(ofColor::seaGreen);
298+
} else if (applicationSwitchBlocked && applications[applicationOrder[i]] == applications[lastSelectedApplicationName]){
299+
// Dark green for the target application during the transition, so that there is immediate button feedback.
300+
ofSetColor(ofColor::darkGreen);
301+
} else {
302+
// Dark blue for the unselected applications.
303+
ofSetColor(ofColor::midnightBlue);
304+
}
305+
// Draw a rounded rectangle for the application button with a 20 pixel radius.
306+
ofDrawRectRounded(applicationButtons[i], 20);
307+
308+
// Make a stroke around the current application button
309+
if (applications[applicationOrder[i]] == currentApplication){
310+
ofSetColor(ofColor::white);
311+
ofNoFill();
312+
ofSetLineWidth(2);
313+
ofDrawRectRounded(applicationButtons[i], 20);
314+
ofFill();
315+
}
316+
317+
// Make a string with the name of the application with the loop index plus one prepended.
318+
Application *app = applications[applicationOrder[i]];
319+
string applicationOrderString = ofToString(i+1) + ": " + app->getName();
320+
321+
// Add label for application button
322+
ofSetColor(ofColor::white);
323+
displayFont20.drawString(applicationOrderString, applicationButtons[i].x + 25, applicationButtons[i].y + 30);
324+
}
254325

255326
// draw shape and color I/O images
256327

@@ -356,20 +427,13 @@ void AppManager::keyPressed(int key) {
356427
showDebugGui = !showDebugGui;
357428
} else if (key == ' ') {
358429
paused = !paused;
359-
} else if (key > '0' && key <= '9' && (key - '0') < applications.size()) {
360-
int num = key - '0';
361-
for (map<string, Application *>::iterator iter = applications.begin(); iter != applications.end(); iter++) {
362-
// skip over empty entries created by checks
363-
if (iter->second == nullptr)
364-
continue;
365-
num--;
366-
// num == 0 when iter gets to the Nth app
367-
if (num == 0) {
368-
setCurrentApplication(iter->first);
369-
break;
370-
}
371-
}
372-
}
430+
} else if (key > '0' && key <= '9') {
431+
int num = key - '0';
432+
if (num > 0 && num <= applicationOrder.size()) {
433+
setCurrentApplication(applicationOrder[num - 1]);
434+
lastSelectedApplicationName = applicationOrder[num - 1];
435+
}
436+
}
373437
/*else if (key == '1') {
374438
setCurrentApplication("mqttTransmission");
375439
} else if (key == '2') {
@@ -397,7 +461,17 @@ void AppManager::keyPressed(int key) {
397461
void AppManager::keyReleased(int key) {};
398462
void AppManager::mouseMoved(int x, int y) {};
399463
void AppManager::mouseDragged(int x, int y, int button) {};
400-
void AppManager::mousePressed(int x, int y, int button) {};
464+
void AppManager::mousePressed(int x, int y, int button) {
465+
// Check if any of the application buttons were clicked
466+
for (int i = 0; i < applicationButtons.size(); i++){
467+
if (applicationButtons[i].inside(x, y)){
468+
// Set the current application to the one that was clicked.
469+
setCurrentApplication(applicationOrder[i]);
470+
// Also set the last selected application, so that the button can be highlighted during the transition to the new application.
471+
lastSelectedApplicationName = applicationOrder[i];
472+
}
473+
}
474+
};
401475
void AppManager::mouseReleased(int x, int y, int button) {};
402476
void AppManager::windowResized(int w, int h) {};
403477
void AppManager::gotMessage(ofMessage msg) {};

src/AppManager.hpp

+19-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "TransformIOManager.hpp"
2424

2525
// External Device Managers
26-
#include "KinectManager.hpp"
26+
#include "KinectManagerSimple.hpp"
2727

2828
// major classes
2929
#include "Application.hpp"
@@ -43,6 +43,7 @@
4343
#include "DepthDebugApp.hpp"
4444

4545
#include "KinectHandWavy.hpp"
46+
#include "Telepresence.hpp"
4647

4748
#include "EquationMode.hpp"
4849

@@ -78,6 +79,9 @@ class AppManager : public ofBaseApp {
7879
shared_ptr<ofAppBaseWindow> displayWindow;
7980
shared_ptr<ofAppBaseWindow> projectorWindow;
8081

82+
// pointer to camera, lives in DisplayApp
83+
ofVideoGrabber *cam;
84+
8185
// lets settings window access main window stuff
8286
friend class DisplayApp;
8387
friend class ProjectorApp;
@@ -94,10 +98,19 @@ class AppManager : public ofBaseApp {
9498
SerialShapeIOManager *m_serialShapeIOManager;
9599

96100
// external devices
97-
KinectManager *kinectManager;
101+
KinectManagerSimple *kinectManager;
98102

99103
// applications
100-
map<string, Application *> applications;
104+
unordered_map<string, Application *> applications;
105+
std::vector<std::string> applicationOrder; // Vector to maintain insertion order of applications
106+
107+
// Graphical buttons, made of rectangles
108+
std::vector<ofRectangle> applicationButtons;
109+
ofTrueTypeFont displayFont20;
110+
// Track the last application that was selected, so we can give it a button status during the transition
111+
// because it won't be the active application until the transition is complete.
112+
std::string lastSelectedApplicationName;
113+
101114
Application *currentApplication;
102115

103116
// debugging applications
@@ -115,6 +128,9 @@ class AppManager : public ofBaseApp {
115128
// hand wavy application
116129
KinectHandWavy *kinectHandWavy;
117130

131+
// Telepresence
132+
Telepresence *telepresence;
133+
118134
EquationMode *equationMode;
119135

120136
WaveModeContours *waveModeContours;

0 commit comments

Comments
 (0)