1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- local function solve(root, target, control, lengths)
- local T = vec3(target - root)
- local C = vec3(control - root)
- local R = vec3(0)
- -- Basis
- local bx = vec3(T):normalize()
- local by = (C - bx * (C:dot(bx))):normalize()
- local bz = vec3(bx):cross(by)
- -- Matrix from basis
- local transform = mat4(
- bx.x, by.x, bz.x, 0,
- bx.y, by.y, bz.y, 0,
- bx.z, by.z, bz.z, 0,
- 0, 0, 0, 1
- ):transpose()
- local distance = #T
- local x = (distance + (lengths[1] ^ 2 - lengths[2] ^ 2) / distance) / 2
- local y = math.sqrt(lengths[1] ^ 2 - x ^ 2)
- local solution = vec4(x, y, 0, 1)
- return root + (transform * solution).xyz
- end
- function lovr.load()
- boneLengths = { .3, .3 }
- root = lovr.math.newVec3(-.2, 1.5, -.5)
- target = lovr.math.newVec3(.2, 1.5, -.7)
- control = lovr.math.newVec3(0, 1.8, -.6)
- pointSize = .04
- drags = {}
- end
- function lovr.update(dt)
- -- Allow hands to drag any of the points
- local points = { root, target, control }
- for i, hand in ipairs(lovr.headset.getHands()) do
- local handPosition = vec3(lovr.headset.getPosition(hand .. '/point'))
- if lovr.headset.wasPressed(hand, 'trigger') then
- for j, point in ipairs(points) do
- if handPosition:distance(point) < pointSize then
- drags[hand] = point
- end
- end
- elseif lovr.headset.wasReleased(hand, 'trigger') then
- drags[hand] = nil
- end
- if drags[hand] then
- drags[hand]:set(handPosition)
- end
- end
- end
- function lovr.draw(pass)
- -- 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
- pass:cube(mat4(lovr.headset.getPose(hand .. '/point')):scale(.01))
- 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
|