# 2 Bone IK

SourceEdit
``````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

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'))

for j, point in ipairs(points) do
if handPosition:distance(point) < pointSize then
drags[hand] = point
end
end
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