I’m having a go at making an inverse kinematics script, and one of the great features of it is that the forward axis of the arms can be expressed as a vector.
It’s simple enough finding where the joint of a part is based on its axis:
joint = Part.CFrame*(Part.Size*axis * 0.5)
However, it’s not quite so easy to find the CFrame of a part based on its two joints and an axis.
Obviously the position is the average of the two joints, but the lookVector is harder to find: It should be based on both the direction between the two joints of the part and the axis.
The only way I can imagine to do this is to take the direction between the two joints, somehow rotate it by the axis, then make that the lookVector of the part.
I tried doing it by turning the direction between the two joints and the axis into CFrames, with CFrame.new(Vector3.new(), direction/axis) then multiplying those CFrames by each other, but it didn’t work.
You probably want to construct the CFrame from the three perpendicular vectors (front, right, up) instead of using CFrame.new(pos, look) so that it is independent of orientation. (CFrame.new constructs the up/right vectors with the initial assumption that the up vector is (0,1,0), which isn’t always desirable)
The up vector would be the axis direction, the right vector could be i.e. the cross product of the directions of two subsequent axes that make up the arm/leg/whatever. The forward vector follows from the cross product of the up/right vectors.
Use this constructor of CFrame once you have position / up / right / front vectors defined:
I’m not sure what the right vector is supposed to be.
The joints of “Part” are joints[i] and joints[i+1], positioned at the surface of the Part and displaced from the centre in the directions of axis and -axis.
So if axis is (0,0,1) then the joints are at the front and back of the part.
These joints are just positions in world space.
Since there are only two joints relevant to the part, only one direction can be made, thus there’s no second direction to use as a factor in a cross product.
Following your example, currently my definitions for up, right, and forward look like this:
local up = axis
local right = ?
local forward = up:Cross(right)
The two definitions I’ve tried for right are joints[i]:Cross(joints[i+1]) and (joints[i+1]-joints[i]).unit, neither of which have worked well (position is still fine, rotation is crazy)
I assume this is IK for an arm or so, so you should have at least 3 joints and 2 axes between these joints, correct? (shoulder to elbow, elbow to hand)
If so, the right vector for both parts of this arm (shoulder to elbow, elbow to hand) would be the cross product between -axisDirection1 and axisDirection2 (both axes pointing away from the middle joint), and then normalized.