main.lua 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. local function getJointDirection(skeleton, joint)
  2. return quat(unpack(skeleton[joint], 5)):direction()
  3. end
  4. local function getCurl(skeleton, finger)
  5. local fingers = { thumb = 4, index = 8, middle = 13, ring = 18, pinky = 23 }
  6. local jointCount = finger == 'thumb' and 2 or 3
  7. local directions = {}
  8. repeat
  9. local orientation = quat(unpack(skeleton[fingers[finger] + #directions], 5))
  10. table.insert(directions, orientation:direction())
  11. until #directions == jointCount
  12. local straightness = 0
  13. for i = 2, jointCount do
  14. straightness = straightness + math.max(directions[i]:dot(directions[i - 1]), 0)
  15. end
  16. local curliness = 1 - (straightness / (jointCount - 1))
  17. return curliness
  18. end
  19. local function isThumbsUp(skeleton)
  20. return skeleton and
  21. getCurl(skeleton, 'thumb') < .1 and
  22. getJointDirection(skeleton, 6).y > .4 and
  23. getCurl(skeleton, 'index') > .6 and
  24. getCurl(skeleton, 'middle') > .6 and
  25. getCurl(skeleton, 'ring') > .6 and
  26. getCurl(skeleton, 'pinky') > .6
  27. end
  28. function lovr.load()
  29. hands = {
  30. left = {},
  31. right = {}
  32. }
  33. end
  34. function lovr.update(dt)
  35. for device, hand in pairs(hands) do
  36. hand.skeleton = lovr.headset.getSkeleton(device)
  37. hand.thumbsup = isThumbsUp(hand.skeleton)
  38. end
  39. end
  40. local function drawSkeleton(pass, skeleton)
  41. if not skeleton then return end
  42. pass:setColor(0xf0f0f0)
  43. for i, joint in ipairs(skeleton) do
  44. pass:sphere(vec3(unpack(joint)), .01)
  45. end
  46. pass:setColor(0xb0b0b0)
  47. for f = 1, 5 do
  48. local base = ({ 3, 7, 12, 17, 22 })[f]
  49. local length = f == 1 and 3 or 4
  50. for j = 1, length do
  51. local from = vec3(unpack(skeleton[base + j - 1]))
  52. local to = vec3(unpack(skeleton[base + j - 0]))
  53. pass:capsule(from, to, .002)
  54. end
  55. end
  56. end
  57. local function drawCurls(pass, skeleton, x)
  58. if not skeleton then return end
  59. pass:push()
  60. pass:translate(x, 0, 0)
  61. local str = 'curls:'
  62. for i, finger in ipairs({ 'thumb', 'index', 'middle', 'ring', 'pinky' }) do
  63. str = str .. ('\n%s: %.2f'):format(finger, getCurl(skeleton, finger))
  64. end
  65. pass:text(str, 0, 1.7, -2, .1)
  66. pass:pop()
  67. end
  68. function lovr.draw(pass)
  69. local str = 'Detecting thumbs up gesture..\n'
  70. if hands.left.thumbsup or hands.right.thumbsup then
  71. str = str .. 'Good job!'
  72. end
  73. pass:text(str, 0, 1.7, -2, .2)
  74. drawSkeleton(pass, hands.left.skeleton)
  75. drawSkeleton(pass, hands.right.skeleton)
  76. drawCurls(pass, hands.left.skeleton, -2)
  77. drawCurls(pass, hands.right.skeleton, 2)
  78. end