This probably isn’t the most efficient way to do this, but it works and it’s a starting point:
local function isZero(vector)
return vector.x == 0 and vector.y == 0 and vector.z == 0
end
local function makePerpendicular(axis, forward, up)
local temp = axis:Cross(forward)
if isZero(temp) then -- backup vector for if forward is parallel to axis
if axis:Dot(forward) > 0 then
up = -up
end
temp = axis:Cross(up)
end
return temp:Cross(axis).Unit, temp
end
--This returns the needed rotation for the hand.
local function GetHandRotation()
local handCFrameInUpperArmSpace = UpperArmCenter.CFrame:toObjectSpace(HandCenter.CFrame)
local axisVector = UpperArmCenter.CFrame.upVector
local upperArmFrontVector, upperArmRightVector = makePerpendicular(axisVector, UpperArmCenter.CFrame.lookVector, UpperArmCenter.CFrame.upVector)
local handFrontVector, handRightVector = makePerpendicular(axisVector, HandCenter.CFrame.lookVector, HandCenter.CFrame.upVector)
local angle = math.clamp(upperArmFrontVector:Dot(handFrontVector), -1, 1)
if angle == 1 or angle == -1 then
if (handFrontVector - upperArmFrontVector):isClose(Vector3.new(0, 0, 0), 0.1) then
print("hand angle: 0")
return 0
elseif (handFrontVector + upperArmFrontVector):isClose(Vector3.new(0, 0, 0), 0.1) then
print("hand angle: 180")
return math.pi
end
end
angle = math.acos(angle)
local temp = upperArmFrontVector:Cross(handFrontVector)
if temp:Dot(axisVector) < 0 then
angle = -angle
end
print("hand angle:",math.deg(angle))
return angle
end
The idea is to get an axis, convert the UpperArm and Hand look vectors to be perpendicular to it, then get the difference in the angle between the UpperArm and Hand’s axis-perpendicular vector.
I’m not sure how good of a solution this is. You can try with different axes and see how it works out. It could probably be written in a more efficient manner, too.
It does handle the case that that look vector is parallel to the axis though (using the up vector or down vector as a backup), so that’s nice!
https://gfycat.com/ExhaustedValuableAtlanticridleyturtle
https://gfycat.com/PhysicalPoliticalGalapagosalbatross
The point where the arm is inverted from the expected position is fixed in the above code.