Inverse kinematic system improvement

I’ve got a working kinematic system, but I want the leg to seem like its going from the top of the body attachemnt and into the top of the foot.(i know im bad at explaining things with words)

so like:
Capture_2021_01_08_17_21_16_228
as per a real leg.

Any ideas on how to do this?

(here’s the kinematic code if you need it):

    local foot = workspace.a
	local bodyatt = workspace.c
	
	local localizedUnit = CFrame.new(bodyatt.CFrame.p):PointToObjectSpace(foot.CFrame.p)--(-(bodyatt.CFrame*CFrame.new(0,bodyatt.Size.Y/2,0)):pointToObjectSpace((foot.CFrame*CFrame.new(0,foot.Size.Y/2,0)).Position)+(foot.CFrame*CFrame.new(0,bodyatt.Size.Y/2,0)):pointToObjectSpace((bodyatt.CFrame*CFrame.new(0,foot.Size.Y/2,0)).Position))/2
		
	local b = upperLeg.Size.X
	local a = lowerLeg.Size.X
	local c = localizedUnit.magnitude
	
	local axis = Vector3.new(0, 0, -1):Cross(localizedUnit)
	local angle = math.acos(-localizedUnit.unit.Z)
	local planeCF = CFrame.new(foot.CFrame.p) * CFrame.fromAxisAngle(axis, angle)
	
	local A = -math.acos((-a^2 + b^2 + c^2) / (2 * b * c))
	local C = math.acos((a^2 - b^2 + c^2) / (2 * a * c))
	
	if tostring(A) == "nan" then A = 0 end
	if tostring(C) == "-nan(ind)" then C = 0 end
	
	upperLeg.CFrame = planeCF*CFrame.Angles(A+math.pi,0,0)*CFrame.Angles(math.pi,math.rad(90),math.pi)*CFrame.new(upperLeg.Size.X/2,0,0)*CFrame.Angles(math.pi,0,0)
	lowerLeg.CFrame = upperLeg.CFrame*CFrame.new(upperLeg.Size.X/2,0,0)*CFrame.Angles(0,0,-(C-A)+math.pi/2)*CFrame.Angles(0,0,math.rad(90))*CFrame.new(-lowerLeg.Size.X/2,0,0)*CFrame.Angles(math.pi,0,0)
1 Like

Hmm, It’s pretty hard to tell what you want, for now I’m guessing you want to attach the leg to the foot and body correctly so it looks good? If so then I suggest looking at working with Motor6Ds as they already do the work of attaching the foot to the leg like in this really nice R15 example, which uses a similar trigonometric based IK solver like yours but applied to the C0 of the Motor6Ds creating a real good looking effect:

what i’m trying to say is that i want this
Capture_2021_01_09_09_19_03_680
The upper and lower legs are calculated with the current kinematic system that I have in this picture.

I want them to seem like the upper leg is coming out of the body attachment in the direction of the blue arrow, while the lower leg i want to be going into the foot by the red arrow.

So basically i want it to take into account the orientation of the foot and body attachment.

Slight update, I got a bit working but it doesn’t exactally work in many parts:

new code:

local foot = workspace.a
	local bodyatt = workspace.c
	
	
	local localizedUnit = bodyatt.CFrame:PointToObjectSpace(foot.CFrame.p)--(-(bodyatt.CFrame*CFrame.new(0,bodyatt.Size.Y/2,0)):pointToObjectSpace((foot.CFrame*CFrame.new(0,foot.Size.Y/2,0)).Position)+(foot.CFrame*CFrame.new(0,bodyatt.Size.Y/2,0)):pointToObjectSpace((bodyatt.CFrame*CFrame.new(0,foot.Size.Y/2,0)).Position))/2
	local t = foot.CFrame.RightVector+foot.CFrame.UpVector--CFrame.new(0,0,0):PointToObjectSpace(foot.CFrame.UpVector)
	
	local b = upperLeg.Size.X
	local a = lowerLeg.Size.X
	local c = localizedUnit.magnitude+((math.cosh(math.rad(foot.Orientation.Z)*1.1)-1)/3.075)*(math.pi*2)--+(math.cosh(math.rad(foot.Orientation.Z)*1.1)-1)/math.pi/math.pi
	
	local axis = Vector3.new(0,0,-1):Cross(localizedUnit.unit)
	local angle = math.acos(-localizedUnit.unit.Z)--+math.acos(math.rad(foot.Orientation.Z)/2)/2
	local planeCF = CFrame.new(bodyatt.CFrame.p) * CFrame.fromAxisAngle(axis, angle)*CFrame.Angles(0,math.rad(foot.Orientation.Z)/2,0)
	
	local A = -math.acos((-a^2 + b^2 + c^2) / (2 * b * c))
	local C = math.acos((a^2 - b^2 + c^2) / (2 * a * c))+((math.cosh(math.rad(foot.Orientation.Z)*1.1)-1)/3.075)*2.5--math.acos(math.rad(foot.Orientation.Z)/2)/2
	
	if tostring(A) == "nan" then A = 0 end
	if tostring(C) == "-nan(ind)" then C = 0 end
	
	local Zrot = math.asin(t.X/math.pi)-math.pi/8--math.asin(math.rad(foot.Orientation.Z)/2)/2
	
	upperLeg.CFrame = planeCF*CFrame.Angles(-A+math.pi,0,0)*CFrame.Angles(math.pi,math.rad(90),0)*CFrame.new(upperLeg.Size.X/2,0,0)--*CFrame.Angles(math.pi,0,0)
	lowerLeg.CFrame = upperLeg.CFrame*CFrame.new(upperLeg.Size.X/2,0,0)*CFrame.Angles(Zrot*phi,0,-(C-A)-math.pi/2)*CFrame.Angles(0,0,math.rad(90))*CFrame.new(lowerLeg.Size.X/2,0,0)--*CFrame.Angles(-math.pi/4,0,0)

what is wrong here?

nevermind, i realized that it was imposible to do the X axis, and it does it automatically, so I just stuck with the Z of the foot.