Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 573 lines (452 sloc) 15.343 kb
eef6e4e Added licence, fixed of007 set root issue, fixed ofxHardwareDriver defin...
Matthew Gingold authored
1 /*
2 * ofxUserGenerator.cpp
3 *
4 * Copyright 2011 (c) Matthew Gingold http://gingold.com.au
5 * Originally forked from a project by roxlu http://www.roxlu.com/
6 *
7 * Permission is hereby granted, free of charge, to any person
8 * obtaining a copy of this software and associated documentation
9 * files (the "Software"), to deal in the Software without
10 * restriction, including without limitation the rights to use,
11 * copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following
14 * conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE.
27 *
28 */
29
c35f56e @roxlu Experimenting with easy to install ofxOpenNI
roxlu authored
30 #include "ofxUserGenerator.h"
31 #include "ofxOpenNIMacros.h"
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
32 #include "ofxTrackedUser.h"
c35f56e @roxlu Experimenting with easy to install ofxOpenNI
roxlu authored
33
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
34 // CALLBACKS
35 // =============================================================================
36 // Callback: New user was detected
37 void XN_CALLBACK_TYPE User_NewUser(
38 xn::UserGenerator& rGenerator
39 ,XnUserID nID
40 ,void* pCookie
41 )
42 {
43 printf("New User %d\n", nID);
44 ofxUserGenerator* user = static_cast<ofxUserGenerator*>(pCookie);
45 if(user->needsPoseForCalibration()) {
46 user->startPoseDetection(nID);
47 }
48 else {
49 user->requestCalibration(nID);
50 }
51 }
52
53 // Callback: An existing user was lost
54 void XN_CALLBACK_TYPE User_LostUser(
55 xn::UserGenerator& rGenerator
56 ,XnUserID nID
57 ,void* pCookie
58 )
59 {
60 printf("Lost user %d\n", nID);
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
61 rGenerator.GetSkeletonCap().Reset(nID);
62
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
63 }
64
65 // Callback: Detected a pose
66 void XN_CALLBACK_TYPE UserPose_PoseDetected(
67 xn::PoseDetectionCapability& rCapability
68 ,const XnChar* strPose
69 ,XnUserID nID
70 ,void* pCookie
71 )
72 {
73 ofxUserGenerator* user = static_cast<ofxUserGenerator*>(pCookie);
74 printf("Pose %s detected for user %d\n", strPose, nID);
75 user->stopPoseDetection(nID);
76 user->requestCalibration(nID);
77 }
78
79
80
81 void XN_CALLBACK_TYPE UserCalibration_CalibrationStart(
82 xn::SkeletonCapability& capability
83 ,XnUserID nID
84 ,void* pCookie
85 )
86 {
87 printf("Calibration started for user %d\n", nID);
88 }
89
90
91 void XN_CALLBACK_TYPE UserCalibration_CalibrationEnd(
92 xn::SkeletonCapability& rCapability
93 ,XnUserID nID
94 ,XnBool bSuccess
95 ,void* pCookie
96 )
97 {
98 ofxUserGenerator* user = static_cast<ofxUserGenerator*>(pCookie);
99 if(bSuccess) {
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
100 printf("+++++++++++++++++++++++ Succesfully tracked user: %d\n", nID);
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
101 user->startTracking(nID);
102 }
103 else {
104 if(user->needsPoseForCalibration()) {
105 user->startPoseDetection(nID);
106 }
107 else {
108 user->requestCalibration(nID);
109 }
110 }
111 }
112
113 // OFXUSERGENERATOR
114 // =============================================================================
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
115 ofxUserGenerator::ofxUserGenerator() {
116 needs_pose = false;
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
117 }
118
935ca48 @jvcleave refactoring/leaks
authored
119 ofxUserGenerator::~ofxUserGenerator()
120 {
121 cout << "~ofxUserGenerator DELETED" << endl;
122 for(int i=0; i<maskPixels.size(); i++)
123 {
124 delete maskPixels[i];
125 maskPixels[i] = NULL;
126 }
127 maskPixels.clear();
128
129 for(int i=0; i<cloudPoints.size(); i++)
130 {
131 delete cloudPoints[i];
132 cloudPoints[i] = NULL;
133 }
134 cloudPoints.clear();
135
136
137 for(int i=0; i<cloudColors.size(); i++)
138 {
7cbb649 @jvcleave remove unregister callbacks
authored
139 if (cloudColors[i])
140 {
141 cloudColors[i] = NULL;
142 }
143
935ca48 @jvcleave refactoring/leaks
authored
144 }
145 cloudColors.clear();
146
7cbb649 @jvcleave remove unregister callbacks
authored
147 //user_generator.UnregisterUserCallbacks(user_cb_handle);
148 //user_generator.GetSkeletonCap().UnregisterCalibrationCallbacks(calibration_cb_handle);
149 //user_generator.GetPoseDetectionCap().UnregisterFromPoseCallbacks(user_pose_cb_handle);
935ca48 @jvcleave refactoring/leaks
authored
150 for(int i =0; i<tracked_users.size(); i++)
151 {
152 delete tracked_users[i];
153 tracked_users[i] = NULL;
154 }
155 tracked_users.clear();
156 user_generator.Unref();
157 }
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
158 //----------------------------------------
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
159 void ofxUserGenerator::startPoseDetection(XnUserID nID) {
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
160 printf("Start pose detection: %d +++++++++++++++++++++++++++++\n", nID);
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
161 user_generator.GetPoseDetectionCap().StartPoseDetection(calibration_pose, nID);
162 }
163
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
164
165 //----------------------------------------
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
166 void ofxUserGenerator::stopPoseDetection(XnUserID nID) {
167 user_generator.GetPoseDetectionCap().StopPoseDetection(nID);
168 }
169
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
170
171 //----------------------------------------
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
172 void ofxUserGenerator::requestCalibration(XnUserID nID) {
173 user_generator.GetSkeletonCap().RequestCalibration(nID, TRUE);
c35f56e @roxlu Experimenting with easy to install ofxOpenNI
roxlu authored
174 }
175
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
176
177 // Setup the user generator.
178 //----------------------------------------
935ca48 @jvcleave refactoring/leaks
authored
179 bool ofxUserGenerator::setup( ofxOpenNIContext* pContext, int maxUsers=8) {
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
180
935ca48 @jvcleave refactoring/leaks
authored
181 maxNumUsers = maxUsers;
72dbf23 Multiple depth mask near/far threshold setting made possible; some bug f...
Matthew Gingold authored
182 bool ok = false;
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
183 // store context and generator references
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
184 context = pContext;
72dbf23 Multiple depth mask near/far threshold setting made possible; some bug f...
Matthew Gingold authored
185 ok = context->getDepthGenerator(&depth_generator);
186 if (!ok) return false;
187
b04de10 @gameoverhack Init from XML now works correctly (not re-making nodes nymore). Also sim...
gameoverhack authored
188 context->getImageGenerator(&image_generator);
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
189
c35f56e @roxlu Experimenting with easy to install ofxOpenNI
roxlu authored
190 XnStatus result = XN_STATUS_OK;
191
b04de10 @gameoverhack Init from XML now works correctly (not re-making nodes nymore). Also sim...
gameoverhack authored
192 // get map_mode so we can setup width and height vars from depth gen size
193 XnMapOutputMode map_mode;
194 depth_generator.GetMapOutputMode(map_mode);
178552c @gameoverhack Added User masking and update example
gameoverhack authored
195
b04de10 @gameoverhack Init from XML now works correctly (not re-making nodes nymore). Also sim...
gameoverhack authored
196 width = map_mode.nXRes;
197 height = map_mode.nYRes;
178552c @gameoverhack Added User masking and update example
gameoverhack authored
198
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
199 // set update mask pixels default to false
200 useMaskPixels = false;
935ca48 @jvcleave refactoring/leaks
authored
201 if (maskPixels.size() < maxUsers)
202 {
203
204 for (int i = 0; i < maxUsers; i++)
205 {
206
207 maskPixels.push_back(new unsigned char[width * height]);
208
209 }
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
210 }
211
935ca48 @jvcleave refactoring/leaks
authored
212
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
213 // set update cloud points default to false
214 useCloudPoints = false;
215
216 // setup cloud points array TODO: clean this up on closing or dtor
637bab3 @novogrammer Fix BufferOverrun About CloudPoints
novogrammer authored
217 //including 0 as all users
935ca48 @jvcleave refactoring/leaks
authored
218 if (cloudPoints.size() < maxUsers)
219 {
220 for (int i = 0; i < maxNumUsers; i++)
221 {
222 cloudPoints.push_back(new ofPoint[width * height]);
223 }
224 }
225
226 if (cloudColors.size() < maxUsers)
227 {
228 for (int i = 0; i < maxNumUsers; i++)
229 {
230 cloudColors.push_back(new ofColor[width * height]);
231 }
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
232 }
178552c @gameoverhack Added User masking and update example
gameoverhack authored
233
c35f56e @roxlu Experimenting with easy to install ofxOpenNI
roxlu authored
234 // check if the USER generator exists.
b04de10 @gameoverhack Init from XML now works correctly (not re-making nodes nymore). Also sim...
gameoverhack authored
235 if(!context->getUserGenerator(&user_generator)) {
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
236
237 // if one doesn't exist then create user generator.
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
238 result = user_generator.Create(context->getXnContext());
72dbf23 Multiple depth mask near/far threshold setting made possible; some bug f...
Matthew Gingold authored
239 CHECK_RC(result, "Create user generator");
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
240
72dbf23 Multiple depth mask near/far threshold setting made possible; some bug f...
Matthew Gingold authored
241 if (result != XN_STATUS_OK) return false;
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
242 }
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
243
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
244 // register user callbacks
935ca48 @jvcleave refactoring/leaks
authored
245
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
246 user_generator.RegisterUserCallbacks(
247 User_NewUser
248 ,User_LostUser
249 ,this
250 ,user_cb_handle
251 );
252
935ca48 @jvcleave refactoring/leaks
authored
253
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
254 user_generator.GetSkeletonCap().RegisterCalibrationCallbacks(
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
255 UserCalibration_CalibrationStart
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
256 ,UserCalibration_CalibrationEnd
257 ,this
258 ,calibration_cb_handle
259 );
260
261 // check if we need to pose for calibration
262 if(user_generator.GetSkeletonCap().NeedPoseForCalibration()) {
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
263
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
264 needs_pose = true;
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
265
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
266 if(!user_generator.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) {
267 printf("Pose required, but not supported!\n");
268 return false;
269 }
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
270
935ca48 @jvcleave refactoring/leaks
authored
271
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
272 user_generator.GetPoseDetectionCap().RegisterToPoseCallbacks(
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
273 UserPose_PoseDetected
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
274 ,NULL
275 ,this
276 ,user_pose_cb_handle
277 );
278 user_generator.GetSkeletonCap().GetCalibrationPose(calibration_pose);
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
279
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
280 }
281
282 user_generator.GetSkeletonCap().SetSkeletonProfile(XN_SKEL_PROFILE_ALL);
283
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
284 // needs this to allow skeleton tracking when using pre-recorded .oni or nodes init'd by code (as opposed to xml)
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
285 // as otherwise the image/depth nodes play but are not generating callbacks
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
286 //if (context->isUsingRecording()) {
287 result = context->getXnContext().StartGeneratingAll();
288 CHECK_RC(result, "StartGenerating");
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
289
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
290 // pre-generate the tracked users.
935ca48 @jvcleave refactoring/leaks
authored
291 if (tracked_users.size()<maxNumUsers)
292 {
293 for(int i = 0; i < maxNumUsers; ++i) {
294 printf("Creating user: %i\n", i+1);
295 ofxTrackedUser* tracked_user = new ofxTrackedUser(context);
296 tracked_users.push_back(tracked_user);
297 }
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
298 }
935ca48 @jvcleave refactoring/leaks
authored
299
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
300
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
301 return true;
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
302 }
303
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
304
305 // Draw a specific user (start counting at 0)
306 //----------------------------------------
2c8ad2c @ssbanerje drawing skeleton by specifying the width and height of box to draw in
ssbanerje authored
307 void ofxUserGenerator::drawUser(int nUserNum, const float wScale, const float hScale) {
935ca48 @jvcleave refactoring/leaks
authored
308 /*if(nUserNum - 1 > max_num_users)
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
309 return;
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
310 tracked_users[nUserNum]->updateBonePositions();
935ca48 @jvcleave refactoring/leaks
authored
311 tracked_users[nUserNum]->debugDraw(wScale, hScale);*/
312 /*for( int i=0; i<tracked_users.size(); i++)
313 {
314 tracked_users[i]->updateBonePositions();
315 tracked_users[i]->debugDraw(wScale, hScale);
316 }*/
55f0255 @jvcleave added OpenNITracker
authored
317
318 tracked_users[nUserNum]->debugDraw(wScale, hScale);
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
319 }
320
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
321 // Draw all the found users.
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
322 //----------------------------------------
2c8ad2c @ssbanerje drawing skeleton by specifying the width and height of box to draw in
ssbanerje authored
323 void ofxUserGenerator::draw(const int width, const int height) {
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
324
3d0e1b7 @jvcleave some custom stuff
authored
325 if (found_users > 0)
326 {
327 const float wScale = width/640.0f;
328 const float hScale = height/480.0f;
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
329
330 // draw all the users
3d0e1b7 @jvcleave some custom stuff
authored
331 for(int i = 0; i < found_users; ++i)
332 {
2c8ad2c @ssbanerje drawing skeleton by specifying the width and height of box to draw in
ssbanerje authored
333 drawUser(i, wScale, hScale);
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
334 }
55f0255 @jvcleave added OpenNITracker
authored
335 }
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
336
cf84822 @gameoverhack Fixed initialization of Context
gameoverhack authored
337 }
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
338
339 // Get a tracked user.
340 //----------------------------------------
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
341 ofxTrackedUser* ofxUserGenerator::getTrackedUser(int nUserNum) {
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
342
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
343 if(nUserNum - 1 > found_users)
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
344 return NULL;
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
345 return tracked_users[nUserNum - 1];
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
346
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
347 }
348
df65059 @jvcleave getTrackedUsers and Joint end/begin
authored
349 vector<ofxTrackedUser*> ofxUserGenerator::getTrackedUsers() {
350 vector<ofxTrackedUser*> found;
935ca48 @jvcleave refactoring/leaks
authored
351 for(int i =0; i<maxNumUsers; i++)
df65059 @jvcleave getTrackedUsers and Joint end/begin
authored
352 {
353 ofxTrackedUser* user = tracked_users[i];
354 if (user->skeletonCalibrated)
355 {
356 found.push_back(user);
357 }
358 }
359
360 return found;
361 }
362
935ca48 @jvcleave refactoring/leaks
authored
363
4907b92 Fixed bug with MAX_NUMBER_USERS for point cloud and mask drawing (mainly...
Matthew Gingold authored
364
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
365 // Get number of tracked users
366 int ofxUserGenerator::getNumberOfTrackedUsers() {
367 return found_users;
368 }
369
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
370 // Update the tracked users, should be called each frame
371 //----------------------------------------
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
372 void ofxUserGenerator::update() {
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
373
935ca48 @jvcleave refactoring/leaks
authored
374 found_users = maxNumUsers;
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
375
935ca48 @jvcleave refactoring/leaks
authored
376 XnUserID* users = new XnUserID[maxNumUsers];
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
377 user_generator.GetUsers(users, found_users);
0ba3cdd @gameoverhack Merged all diatomanabe changes, including making cyclic buffer and direc...
gameoverhack authored
378
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
379 for(int i = 0; i < found_users; ++i) {
380 if(user_generator.GetSkeletonCap().IsTracking(users[i])) {
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
381 tracked_users[i]->id = users[i];
d18f49d Pre-calibration user data
Rene Christen authored
382 user_generator.GetCoM(users[i], tracked_users[i]->center);
907cff5 @jvcleave break out ofxLimb
authored
383
384 //cout << "tracked_users[i]->center.X: " << tracked_users[i]->center.X << endl;
385 //cout << "tracked_users[i]->center.Y: " << tracked_users[i]->center.Y << endl;
386 //cout << "tracked_users[i]->center.Z: " << tracked_users[i]->center.Z << endl;
d18f49d Pre-calibration user data
Rene Christen authored
387 tracked_users[i]->skeletonTracking = user_generator.GetSkeletonCap().IsTracking(users[i]);
388 tracked_users[i]->skeletonCalibrating = user_generator.GetSkeletonCap().IsCalibrating(users[i]);
389 tracked_users[i]->skeletonCalibrated = user_generator.GetSkeletonCap().IsCalibrated(users[i]);
390 if(tracked_users[i]->skeletonTracking) tracked_users[i]->updateBonePositions();
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
391 }
392 }
178552c @gameoverhack Added User masking and update example
gameoverhack authored
393
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
394 delete [] users;
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
395
396 if (useMaskPixels) updateUserPixels();
397 if (useCloudPoints) updateCloudPoints();
178552c @gameoverhack Added User masking and update example
gameoverhack authored
398 }
399
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
400 void ofxUserGenerator::setUseMaskPixels(bool b) {
401 useMaskPixels = b;
402 }
403
404 void ofxUserGenerator::setUseCloudPoints(bool b) {
405 useCloudPoints = b;
406 }
407
408 // return user pixels -> use 0 (default) to get all user masks
409 // or specify a number if you want seperate masks
410 //----------------------------------------
411 unsigned char * ofxUserGenerator::getUserPixels(int userID) {
178552c @gameoverhack Added User masking and update example
gameoverhack authored
412
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
413 if (!useMaskPixels && userID == 0) { // for people who just want all the user masks at once and don't want to waste the extra cycles looking through all users!!!
178552c @gameoverhack Added User masking and update example
gameoverhack authored
414
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
415 xn::SceneMetaData smd;
416 unsigned short *userPix;
417
418 if (user_generator.GetUserPixels(0, smd) == XN_STATUS_OK) {
419 userPix = (unsigned short*)smd.Data();
420 }
421
422 for (int i =0 ; i < width * height; i++) {
423 if (userPix[i] == 0) {
424 maskPixels[0][i] = 0;
425 } else maskPixels[0][i] = 255;
426
427
428 }
178552c @gameoverhack Added User masking and update example
gameoverhack authored
429
430 }
431
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
432 return maskPixels[userID];
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
433 }
434
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
435 // return user pixels -> use 0 (default) to get all user masks
436 // or specify a number if you want seperate masks
437 //----------------------------------------
438 void ofxUserGenerator::updateUserPixels() {
439
440 xn::SceneMetaData smd;
441 unsigned short *userPix;
442
443 if (user_generator.GetUserPixels(0, smd) == XN_STATUS_OK) { // GetUserPixels is supposed to take a user ID number,
444 userPix = (unsigned short*)smd.Data(); // but you get the same data no matter what you pass.
445 } // userPix actually contains an array where each value
446 // corresponds to the user being tracked.
447 // Ie., if userPix[i] == 0 then it's not being tracked -> it's the background!
448 // if userPix[i] > 0 then the pixel belongs to the user who's value IS userPix[i]
449 // // (many thanks to ascorbin who's code made this apparent to me)
935ca48 @jvcleave refactoring/leaks
authored
450 for (int i =0 ; i < width * height; i++)
451 {
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
452
453 // lets cycle through the users and allocate pixels into seperate masks for each user, including 0 as all users
935ca48 @jvcleave refactoring/leaks
authored
454 for (int user = 0; user <maxNumUsers; user++)
455 {
456 if (userPix[i] == user)
457 {
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
458 maskPixels[user][i] = (user == 0 ? 0 : 255);
935ca48 @jvcleave refactoring/leaks
authored
459 } else
460 {
461 maskPixels[user][i] = (user == 0 ? 255 : 0);
462 }
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
463 }
464
465 }
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
466 }
467
468 //----------------------------------------
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
469 void ofxUserGenerator::updateCloudPoints() {
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
470
471 xn::DepthMetaData dm;
472 xn::ImageMetaData im;
473
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
474 const XnRGB24Pixel* pColor;
475 const XnDepthPixel* pDepth;
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
476
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
477 depth_generator.GetMetaData(dm);
478 pDepth = dm.Data();
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
479
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
480 bool hasImageGenerator = image_generator.IsValid();
178552c @gameoverhack Added User masking and update example
gameoverhack authored
481
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
482 if (hasImageGenerator) {
483 image_generator.GetMetaData(im);
484 pColor = im.RGB24Data();
485 }
486
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
487 xn::SceneMetaData smd;
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
488 unsigned short *userPix;
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
489
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
490 if (user_generator.GetUserPixels(0, smd) == XN_STATUS_OK) {
491 userPix = (unsigned short*)smd.Data();
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
492 }
493
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
494 int step = 1;
495 int nIndex = 0;
496
497 for (int nY = 0; nY < height; nY += step) {
ee0360b @gameoverhack Changed cyclic record buffer from vector based (back) to array based (as...
gameoverhack authored
498
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
499 for (int nX = 0; nX < width; nX += step, nIndex += step) {
500
935ca48 @jvcleave refactoring/leaks
authored
501 for (int user = 0; user <maxNumUsers; user++) {
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
502
503 if (userPix[nIndex] == user || user == 0) {
504 cloudPoints[user][nIndex].x = nX;
505 cloudPoints[user][nIndex].y = nY;
506 cloudPoints[user][nIndex].z = pDepth[nIndex];
507 cloudColors[user][nIndex].r = hasImageGenerator ? pColor[nIndex].nRed : 255;
508 cloudColors[user][nIndex].g = hasImageGenerator ? pColor[nIndex].nGreen : 255;
509 cloudColors[user][nIndex].b = hasImageGenerator ? pColor[nIndex].nBlue : 255;
510 cloudColors[user][nIndex].a = 255;
511 } else {
512 cloudPoints[user][nIndex].z = 0; // behaves a bit wackily (you need to ignore z == 0 data for userID > 0...)
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
513 }
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
514
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
515 }
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
516
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
517 }
518 }
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
519 }
520
521 ofPoint ofxUserGenerator::getWorldCoordinateAt(int x, int y, int userID) {
522
00fd2c5 @novogrammer y*height+x -> y*width+x
novogrammer authored
523 return cloudPoints[userID][y * width + x];
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
524
525 }
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
526
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
527 ofColor ofxUserGenerator::getWorldColorAt(int x, int y, int userID) {
528
00fd2c5 @novogrammer y*height+x -> y*width+x
novogrammer authored
529 return cloudColors[userID][y * width + x];
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
530
531 }
532
aa5d03a @gameoverhack ofxHandTracker & ofxGestureGenerator seperated and implimented using ofE...
gameoverhack authored
533 //--------------------------------------------------------------
534 void ofxUserGenerator::setSmoothing(float smooth) {
535 if (smooth > 0.0f && smooth < 1.0f) {
536 smoothing_factor = smooth;
537 if (user_generator.IsValid()) {
538 user_generator.GetSkeletonCap().SetSmoothing(smooth);
539 }
540 }
541 }
542
543 //--------------------------------------------------------------
544 float ofxUserGenerator::getSmoothing() {
545 return smoothing_factor;
546 }
547
5b4153a @gameoverhack Lot's of changes, including more efficient mask pixels and cloud points ...
gameoverhack authored
548 //----------------------------------------
549 int ofxUserGenerator::getWidth() {
550 return width;
551 }
552
553 //----------------------------------------
554 int ofxUserGenerator::getHeight() {
555 return height;
ca4d623 @gameoverhack Record and Playback fixed to work correctly (including skeleton/user tra...
gameoverhack authored
556 }
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
557
558 //----------------------------------------
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
559 void ofxUserGenerator::startTracking(XnUserID nID) {
560 user_generator.GetSkeletonCap().StartTracking(nID);
561 }
562
526c094 @polytrope Update my own ofxImageGenerator changes
polytrope authored
563 //----------------------------------------
ccfbb9a @roxlu Added the ofxUserTracker
roxlu authored
564 bool ofxUserGenerator::needsPoseForCalibration() {
565 return needs_pose;
cf84822 @gameoverhack Fixed initialization of Context
gameoverhack authored
566 }
567
568 // Get a ref to the xn::UserGenerator object.
569 //----------------------------------------
570 xn::UserGenerator& ofxUserGenerator::getXnUserGenerator() {
571 return user_generator;
2c8ad2c @ssbanerje drawing skeleton by specifying the width and height of box to draw in
ssbanerje authored
572 }
Something went wrong with that request. Please try again.