| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- local transform = lovr.math.newMat4()
- local function solve(root, target, control, lengths)
- local T = target - root
- local C = control - root
- local R = vector(0)
- -- Basis
- local bx = T:normalize()
- local by = (C - bx * C:dot(bx)):normalize()
- local bz = bx:cross(by)
- -- Matrix from basis
- transform:set(
- bx.x, bx.y, bx.z, 0,
- by.x, by.y, by.z, 0,
- bz.x, bz.y, bz.z, 0,
- 0, 0, 0, 1
- )
- local distance = T:length()
- local x = (distance + (lengths[1] ^ 2 - lengths[2] ^ 2) / distance) / 2
- local y = math.sqrt(lengths[1] ^ 2 - x ^ 2)
- local solution = vector(x, y, 0)
- return root + transform * solution
- end
- function lovr.load()
- boneLengths = { .3, .3 }
- points = {
- root = vector(-.2, 1.5, -.5),
- target = vector(.2, 1.5, -.7),
- control = vector(0, 1.8, -.6)
- }
- pointSize = .04
- drags = {}
- end
- function lovr.update(dt)
- -- Allow hands to drag any of the points
- for i, hand in ipairs(lovr.headset.getHands()) do
- local handPosition = vector(lovr.headset.getPosition(hand .. '/point'))
- if lovr.headset.wasPressed(hand, 'trigger') then
- for k, point in pairs(points) do
- if handPosition:distance(point) < pointSize then
- drags[hand] = k
- end
- end
- elseif lovr.headset.wasReleased(hand, 'trigger') then
- drags[hand] = nil
- end
- if drags[hand] then
- points[drags[hand]] = handPosition
- end
- end
- end
- function lovr.draw(pass)
- local root, target, control = points.root, points.target, points.control
- -- Draw the joints and the control point
- pass:setColor(0xff80ff)
- pass:sphere(root, pointSize / 2)
- pass:sphere(target, pointSize / 2)
- pass:setColor(0x80ffff)
- pass:sphere(control, pointSize / 2)
- -- Draw the hand
- pass:setColor(0xffffff)
- for _, hand in ipairs(lovr.headset.getHands()) do
- local x, y, z, angle, ax, ay, az = lovr.headset.getPose(hand .. '/point')
- pass:cube(x, y, z, .01, angle, ax, ay, az)
- end
- -- Draw a line from the root to the result from the IK solver, then to the target
- pass:line(root, solve(root, target, control, boneLengths), target)
- end
|