main.lua 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. local transform = lovr.math.newMat4()
  2. local function solve(root, target, control, lengths)
  3. local T = target - root
  4. local C = control - root
  5. local R = vector(0)
  6. -- Basis
  7. local bx = T:normalize()
  8. local by = (C - bx * C:dot(bx)):normalize()
  9. local bz = bx:cross(by)
  10. -- Matrix from basis
  11. transform:set(
  12. bx.x, bx.y, bx.z, 0,
  13. by.x, by.y, by.z, 0,
  14. bz.x, bz.y, bz.z, 0,
  15. 0, 0, 0, 1
  16. )
  17. local distance = T:length()
  18. local x = (distance + (lengths[1] ^ 2 - lengths[2] ^ 2) / distance) / 2
  19. local y = math.sqrt(lengths[1] ^ 2 - x ^ 2)
  20. local solution = vector(x, y, 0)
  21. return root + transform * solution
  22. end
  23. function lovr.load()
  24. boneLengths = { .3, .3 }
  25. points = {
  26. root = vector(-.2, 1.5, -.5),
  27. target = vector(.2, 1.5, -.7),
  28. control = vector(0, 1.8, -.6)
  29. }
  30. pointSize = .04
  31. drags = {}
  32. end
  33. function lovr.update(dt)
  34. -- Allow hands to drag any of the points
  35. for i, hand in ipairs(lovr.headset.getHands()) do
  36. local handPosition = vector(lovr.headset.getPosition(hand .. '/point'))
  37. if lovr.headset.wasPressed(hand, 'trigger') then
  38. for k, point in pairs(points) do
  39. if handPosition:distance(point) < pointSize then
  40. drags[hand] = k
  41. end
  42. end
  43. elseif lovr.headset.wasReleased(hand, 'trigger') then
  44. drags[hand] = nil
  45. end
  46. if drags[hand] then
  47. points[drags[hand]] = handPosition
  48. end
  49. end
  50. end
  51. function lovr.draw(pass)
  52. local root, target, control = points.root, points.target, points.control
  53. -- Draw the joints and the control point
  54. pass:setColor(0xff80ff)
  55. pass:sphere(root, pointSize / 2)
  56. pass:sphere(target, pointSize / 2)
  57. pass:setColor(0x80ffff)
  58. pass:sphere(control, pointSize / 2)
  59. -- Draw the hand
  60. pass:setColor(0xffffff)
  61. for _, hand in ipairs(lovr.headset.getHands()) do
  62. local x, y, z, angle, ax, ay, az = lovr.headset.getPose(hand .. '/point')
  63. pass:cube(x, y, z, .01, angle, ax, ay, az)
  64. end
  65. -- Draw a line from the root to the result from the IK solver, then to the target
  66. pass:line(root, solve(root, target, control, boneLengths), target)
  67. end