fork download
  1. /*
  2.  * JointHitDetector.cpp
  3.  * emptyExample
  4.  *
  5.  * Created by Ryan Challinor on 5/17/11.
  6.  * Copyright 2011 aww bees. All rights reserved.
  7.  *
  8.  */
  9.  
  10. #include "JointHitDetector.h"
  11. #include "ofxVec2f.h"
  12. //#include "ActiveSkeleton.h"
  13. //#include "UDPMessenger.h"
  14.  
  15. static float _hitAreaDisplayTime = .25f;
  16. #define KEEPALIVE_TIME 3.1f
  17.  
  18. JointHitDetector::JointHitDetector(XnSkeletonJoint joint, XnSkeletonJoint refJoint, string name, float requiredLength)
  19. : mPointHistorySize(5)
  20. , mRequiredLength(requiredLength)
  21. , mMessageWorldJointPos(0)
  22. , mMessageBodyJointPos(0)
  23. , mMessageScreenJointPos(0)
  24. , mJoint(joint)
  25. , mRefJoint(refJoint)
  26. , mName(name)
  27. {
  28. for (int i=0; i<kNumHitDirections; ++i)
  29. mHitAreaDisplay[i] = 0;
  30. //output
  31. TheMessenger->AddListener(this, mName+"_requiredlength");
  32. TheMessenger->AddListener(this, mName+"_pointhistorysize");
  33. TheMessenger->AddListener(this, mName+"_trackjointpos");
  34. TheMessenger->AddListener(this, mName+"_gettuninginfo");
  35.  
  36. BroadcastTuningInfo();
  37. }
  38.  
  39. JointHitDetector::~JointHitDetector()
  40. {
  41. TheMessenger->RemoveListener(this);
  42. }
  43.  
  44. void JointHitDetector::Poll(float dt)
  45. {
  46. if (TheActiveSkeleton->IsTracked())
  47. {
  48. float confidence, refConfidence;
  49. ofxVec3f vJoint = TheActiveSkeleton->GetRealWorldPos(mJoint, confidence);
  50. ofxVec3f vRefJoint = TheActiveSkeleton->GetRealWorldPos(mRefJoint, refConfidence);
  51.  
  52. ofxVec3f vRefToJoint = vJoint - vRefJoint;
  53. //use ref joint as anchor, unless vJoint and vRefJoint are the same
  54. if (vRefToJoint.lengthSquared() != 0)
  55. mPoints.push_back(vRefToJoint);
  56. else
  57. mPoints.push_back(vJoint);
  58. //limit to kPointHistorySize
  59. while (mPoints.size() > mPointHistorySize)
  60. mPoints.erase(mPoints.begin());
  61.  
  62. if (mMessageWorldJointPos > 0)
  63. TheMessenger->SendVectorMessage(mName+"_pos_world", vJoint);
  64. if (mMessageBodyJointPos > 0)
  65. TheMessenger->SendVectorMessage(mName+"_pos_body", vRefToJoint);
  66. if (mMessageScreenJointPos > 0)
  67. {
  68. ofxVec3f vScreen = TheActiveSkeleton->GetProjectivePos(mJoint);
  69. TheMessenger->SendVectorMessage(mName+"_pos_screen", vScreen);
  70. }
  71.  
  72. mMessageWorldJointPos = MAX(0, mMessageWorldJointPos - dt);
  73. mMessageBodyJointPos = MAX(0, mMessageBodyJointPos - dt);
  74. mMessageScreenJointPos = MAX(0, mMessageScreenJointPos - dt);
  75.  
  76. float refDist = vRefToJoint.length();
  77. if (refDist != 0)
  78. vRefToJoint /= refDist;
  79.  
  80. for (int i=0; i<kNumHitDirections; ++i)
  81. mHitAreaDisplay[i] = MAX(0, mHitAreaDisplay[i] - dt);
  82.  
  83. ofxVec3f vDir;
  84. const ofxVec3f vUp(0,1,0);
  85. const ofxVec3f vDown(0,-1,0);
  86. const ofxVec3f vLeft(-1,0,0);
  87. const ofxVec3f vRight(1,0,0);
  88. const ofxVec3f vBack(0,0,1);
  89. const ofxVec3f vForward(0,0,-1);
  90. if (DetectHit(vDir) && (refDist > 300 || !NeedDistFromRef()) && confidence > .3f)
  91. {
  92. vDir.normalize();
  93. if (MatchesDir(vUp, vDir, vRefToJoint))
  94. {
  95. TheMessenger->SendStringMessage(mName, "up");
  96. mHitAreaDisplay[kHitUp] = _hitAreaDisplayTime;
  97. }
  98. else if (MatchesDir(vDown, vDir, vRefToJoint))
  99. {
  100. TheMessenger->SendStringMessage(mName, "down");
  101. mHitAreaDisplay[kHitDown] = _hitAreaDisplayTime;
  102. }
  103. else if (MatchesDir(vRight, vDir, vRefToJoint))
  104. {
  105. TheMessenger->SendStringMessage(mName, "right");
  106. mHitAreaDisplay[kHitRight] = _hitAreaDisplayTime;
  107. }
  108. else if (MatchesDir(vForward, vDir, vRefToJoint))
  109. {
  110. TheMessenger->SendStringMessage(mName, "forward");
  111. mHitAreaDisplay[kHitForward] = _hitAreaDisplayTime;
  112. }
  113. else if (MatchesDir(vLeft, vDir, vRefToJoint))
  114. {
  115. TheMessenger->SendStringMessage(mName, "left");
  116. mHitAreaDisplay[kHitLeft] = _hitAreaDisplayTime;
  117. }
  118. else if (MatchesDir(vBack, vDir, vRefToJoint))
  119. {
  120. TheMessenger->SendStringMessage(mName, "back");
  121. mHitAreaDisplay[kHitBack] = _hitAreaDisplayTime;
  122. }
  123. }
  124. }
  125. }
  126.  
  127. void JointHitDetector::SetJoint(XnSkeletonJoint joint)
  128. {
  129. if (mJoint != joint)
  130. {
  131. mJoint = joint;
  132. mPoints.clear();
  133. }
  134. }
  135.  
  136. void JointHitDetector::BroadcastTuningInfo()
  137. {
  138. TheMessenger->SendFloatMessage(mName+"_requiredlength", mRequiredLength);
  139. TheMessenger->SendIntMessage(mName+"_pointhistorysize", mPointHistorySize);
  140. }
  141.  
  142. bool JointHitDetector::MatchesDir(const ofxVec3f& vMatchDir, const ofxVec3f& vCheckDir, const ofxVec3f& vRefDir) const
  143. {
  144. const float cos45 = 0.707106781f;
  145. return vMatchDir.dot(vCheckDir) > cos45 && (vMatchDir.dot(vRefDir) > .3f || !NeedDistFromRef());
  146. }
  147.  
  148. bool JointHitDetector::DetectHit(ofxVec3f& vDir)
  149. {
  150. int numTrackedPoints = mPoints.size();
  151. if (numTrackedPoints < 3)
  152. return false;
  153.  
  154. ofxVec3f A = mPoints[1] - mPoints[0];
  155. ofxVec3f B = mPoints[2] - mPoints[1];
  156.  
  157. for (int i=2; i<=numTrackedPoints; ++i)
  158. {
  159. //printf("*** i = %i\n", i);
  160. //printf("A = (%f,%f,%f) B = (%f,%f,%f)\n", A.x, A.y, A.z, B.x, B.y, B.z);
  161. ofxVec3f C = mPoints[numTrackedPoints > i ? i : i-1] - mPoints[i-1];
  162. ofxVec3f normA = A.getNormalized();
  163. ofxVec3f normB = B.getNormalized();
  164.  
  165. static float _shortEnough = 30.0f;
  166. if (LongEnough(A) && (normA.dot(normB) < .1f || B.length() < _shortEnough))
  167. {
  168. vDir = A;
  169. for (int j=0; j<i; ++j) //erase the A part, keep the B
  170. mPoints.erase(mPoints.begin());
  171. return true;
  172. }
  173. else if (normA.dot(normB) > .8f || (LongEnough(A) && normA.dot(normB) > .4f))
  174. {
  175. A = A+B; B = C;
  176. }
  177. else
  178. {
  179. A = B; B = C;
  180. }
  181. }
  182.  
  183. return false;
  184. }
  185.  
  186. bool JointHitDetector::LongEnough(const ofxVec3f& vec) const
  187. {
  188. return vec.lengthSquared() > mRequiredLength * mRequiredLength;
  189. }
  190.  
  191. void JointHitDetector::Draw() const
  192. {
  193. for (int i=1; i<mPoints.size(); ++i)
  194. {
  195. glPushMatrix();
  196. glLineWidth(3);
  197. glColor3f(0,0,1);
  198. glBegin(GL_LINES);
  199. glVertex2f(320 + mPoints[i-1].x * .5f, 240 - mPoints[i-1].y * .5f);
  200. glVertex2f(320 + mPoints[i].x * .5f, 240 - mPoints[i].y * .5f);
  201. glEnd();
  202. glPopMatrix();
  203. }
  204.  
  205. for (int i=0; i<kNumHitDirections; ++i)
  206. DrawHitDirection((HitDirection)i);
  207. }
  208.  
  209. void JointHitDetector::DrawHitDirection(HitDirection hitDirection) const
  210. {
  211. ofxVec2f vDisplayPoint;
  212.  
  213. switch(hitDirection)
  214. {
  215. case kHitUp:
  216. vDisplayPoint.x = 0;
  217. vDisplayPoint.y = -20;
  218. break;
  219. case kHitRight:
  220. vDisplayPoint.x = 20;
  221. vDisplayPoint.y = 0;
  222. break;
  223. case kHitLeft:
  224. vDisplayPoint.x = -20;
  225. vDisplayPoint.y = 0;
  226. break;
  227. case kHitDown:
  228. vDisplayPoint.x = 0;
  229. vDisplayPoint.y = 20;
  230. break;
  231. case kHitForward:
  232. vDisplayPoint.x = 0;
  233. vDisplayPoint.y = -5;
  234. break;
  235. case kHitBack:
  236. vDisplayPoint.x = 0;
  237. vDisplayPoint.y = 5;
  238. break;
  239. }
  240.  
  241. ofxVec3f vPos = TheActiveSkeleton->GetProjectivePos(mJoint);
  242.  
  243. glPushMatrix();
  244. glLineWidth(10);
  245. glColor3f(0,mHitAreaDisplay[hitDirection]/_hitAreaDisplayTime,0);
  246. glBegin(GL_LINES);
  247. glVertex2f(vPos.x + vDisplayPoint.x - 10, vPos.y + vDisplayPoint.y);
  248. glVertex2f(vPos.x + vDisplayPoint.x + 10, vPos.y + vDisplayPoint.y);
  249. glEnd();
  250. glPopMatrix();
  251. }
  252.  
  253. void JointHitDetector::OnMessage(const ofxOscMessage& msg)
  254. {
  255. if (msg.getAddress() == mName+"_requiredlength")
  256. {
  257. assert(msg.getNumArgs() == 1);
  258. assert(msg.getArgType(0) == OFXOSC_TYPE_FLOAT);
  259. mRequiredLength = msg.getArgAsFloat(0);
  260. }
  261. if (msg.getAddress() == mName+"_pointhistorysize")
  262. {
  263. assert(msg.getNumArgs() == 1);
  264. assert(msg.getArgType(0) == OFXOSC_TYPE_INT32);
  265. mPointHistorySize = msg.getArgAsInt32(0);
  266. }
  267. if (msg.getAddress() == mName+"_trackjointpos")
  268. {
  269. assert(msg.getNumArgs() == 1);
  270. assert(msg.getArgType(0) == OFXOSC_TYPE_INT32);
  271. switch(msg.getArgAsInt32(0))
  272. {
  273. case 1:
  274. mMessageBodyJointPos = KEEPALIVE_TIME;
  275. break;
  276. case 2:
  277. mMessageWorldJointPos = KEEPALIVE_TIME;
  278. break;
  279. case 3:
  280. mMessageScreenJointPos = KEEPALIVE_TIME;
  281. break;
  282. }
  283. }
  284. if (msg.getAddress() == mName+"_gettuninginfo")
  285. {
  286. BroadcastTuningInfo();
  287. }
  288. }
  289.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:10:30: error: JointHitDetector.h: No such file or directory
prog.cpp:11:22: error: ofxVec2f.h: No such file or directory
prog.cpp:18: error: ‘JointHitDetector’ has not been declared
prog.cpp:18: error: expected constructor, destructor, or type conversion before ‘(’ token
prog.cpp:39: error: expected constructor, destructor, or type conversion before ‘::’ token
prog.cpp:44: error: ‘JointHitDetector’ has not been declared
prog.cpp: In function ‘void Poll(float)’:
prog.cpp:46: error: ‘TheActiveSkeleton’ was not declared in this scope
prog.cpp:49: error: ‘ofxVec3f’ was not declared in this scope
prog.cpp:49: error: expected `;' before ‘vJoint’
prog.cpp:50: error: expected `;' before ‘vRefJoint’
prog.cpp:52: error: expected `;' before ‘vRefToJoint’
prog.cpp:54: error: ‘vRefToJoint’ was not declared in this scope
prog.cpp:55: error: ‘mPoints’ was not declared in this scope
prog.cpp:57: error: ‘mPoints’ was not declared in this scope
prog.cpp:57: error: ‘vJoint’ was not declared in this scope
prog.cpp:59: error: ‘mPoints’ was not declared in this scope
prog.cpp:59: error: ‘mPointHistorySize’ was not declared in this scope
prog.cpp:62: error: ‘mMessageWorldJointPos’ was not declared in this scope
prog.cpp:63: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:63: error: ‘mName’ was not declared in this scope
prog.cpp:63: error: ‘vJoint’ was not declared in this scope
prog.cpp:64: error: ‘mMessageBodyJointPos’ was not declared in this scope
prog.cpp:65: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:65: error: ‘mName’ was not declared in this scope
prog.cpp:65: error: ‘vRefToJoint’ was not declared in this scope
prog.cpp:66: error: ‘mMessageScreenJointPos’ was not declared in this scope
prog.cpp:68: error: expected `;' before ‘vScreen’
prog.cpp:69: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:69: error: ‘mName’ was not declared in this scope
prog.cpp:69: error: ‘vScreen’ was not declared in this scope
prog.cpp:72: error: ‘mMessageWorldJointPos’ was not declared in this scope
prog.cpp:72: error: ‘MAX’ was not declared in this scope
prog.cpp:73: error: ‘mMessageBodyJointPos’ was not declared in this scope
prog.cpp:74: error: ‘mMessageScreenJointPos’ was not declared in this scope
prog.cpp:76: error: ‘vRefToJoint’ was not declared in this scope
prog.cpp:80: error: ‘kNumHitDirections’ was not declared in this scope
prog.cpp:81: error: ‘mHitAreaDisplay’ was not declared in this scope
prog.cpp:83: error: expected `;' before ‘vDir’
prog.cpp:84: error: ‘ofxVec3f’ does not name a type
prog.cpp:85: error: ‘ofxVec3f’ does not name a type
prog.cpp:86: error: ‘ofxVec3f’ does not name a type
prog.cpp:87: error: ‘ofxVec3f’ does not name a type
prog.cpp:88: error: ‘ofxVec3f’ does not name a type
prog.cpp:89: error: ‘ofxVec3f’ does not name a type
prog.cpp:90: error: ‘vDir’ was not declared in this scope
prog.cpp:90: error: ‘DetectHit’ was not declared in this scope
prog.cpp:90: error: ‘NeedDistFromRef’ was not declared in this scope
prog.cpp:93: error: ‘vUp’ was not declared in this scope
prog.cpp:93: error: ‘MatchesDir’ was not declared in this scope
prog.cpp:95: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:95: error: ‘mName’ was not declared in this scope
prog.cpp:96: error: ‘mHitAreaDisplay’ was not declared in this scope
prog.cpp:96: error: ‘kHitUp’ was not declared in this scope
prog.cpp:98: error: ‘vDown’ was not declared in this scope
prog.cpp:100: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:100: error: ‘mName’ was not declared in this scope
prog.cpp:101: error: ‘mHitAreaDisplay’ was not declared in this scope
prog.cpp:101: error: ‘kHitDown’ was not declared in this scope
prog.cpp:103: error: ‘vRight’ was not declared in this scope
prog.cpp:105: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:105: error: ‘mName’ was not declared in this scope
prog.cpp:106: error: ‘mHitAreaDisplay’ was not declared in this scope
prog.cpp:106: error: ‘kHitRight’ was not declared in this scope
prog.cpp:108: error: ‘vForward’ was not declared in this scope
prog.cpp:110: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:110: error: ‘mName’ was not declared in this scope
prog.cpp:111: error: ‘mHitAreaDisplay’ was not declared in this scope
prog.cpp:111: error: ‘kHitForward’ was not declared in this scope
prog.cpp:113: error: ‘vLeft’ was not declared in this scope
prog.cpp:115: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:115: error: ‘mName’ was not declared in this scope
prog.cpp:116: error: ‘mHitAreaDisplay’ was not declared in this scope
prog.cpp:116: error: ‘kHitLeft’ was not declared in this scope
prog.cpp:118: error: ‘vBack’ was not declared in this scope
prog.cpp:120: error: ‘TheMessenger’ was not declared in this scope
prog.cpp:120: error: ‘mName’ was not declared in this scope
prog.cpp:121: error: ‘mHitAreaDisplay’ was not declared in this scope
prog.cpp:121: error: ‘kHitBack’ was not declared in this scope
prog.cpp:48: warning: unused variable ‘refConfidence’
prog.cpp: At global scope:
prog.cpp:127: error: ‘JointHitDetector’ has not been declared
prog.cpp:127: error: variable or field ‘SetJoint’ declared void
prog.cpp:127: error: ‘XnSkeletonJoint’ was not declared in this scope
stdout
Standard output is empty