main.lua 2.4 KB

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