Copying only one of a CFrame's [rotational] axes

This may seem like a super simple question but I’ve been coding all day and my brain feels like mush so hear me out…

So I’ve got CFrame a and CFrame b.
local a = CFrame.new(pos,pos+dir)
local b = CFrame.new(pos,pos+dir2)

I want CFrame B’s Y (rotational) axis to be the same as CFrame A’s without messing with the position or any other axes’ rotation.

Example:
b.CFrame = b.CFrame * CFrame.Angles(0,?,0)

At first I thought to use toEulerAngles, but if you know anything about that method, it typically stinks. I also tried some tricks with toObjectSpace but I could never get it work perfectly. Would I use the CFrame’s components? toAxisAngle?

Assuming a and b are created using that method you’ve shown, you can assume the upVector of both CFrames points at least somewhat up.

There is a 90% chance I’m about to answer this wrong because the request is somewhat vague and there’s no explanation of what the application is for, but I’ll take a stab at it anyway.

--[[** Converts CFrame b such that it maintains its
upVector, but the lookVector points in approximately 
the same direction as a.

@param a The CFrame which we are targeting.
@param b The CFrame which we are starting from.
@returns The rotated CFrame b.
**--]]
function rotateCFrameToMatch(a, b)
local upVector = b.upVector;
local rightVector = upVector:Cross(-a.lookVector);
local backVector = rightVector:Cross(upVector);
return CFrame.fromMatrix(b.p, rightVector, upVector, backVector);
end
2 Likes

Thank you for the reply.
I’ve taken a look at it, and I believe it will work although CFrame.fromMatrix appears to be nil?? Can’t find any pages on the wiki about fromMatrix either. Odd.

Ah, well, the transformation is:

CFrame.new(b.p.x, b.p.y, b.p.z, rightVector.x, upVector.x, backVector.x, rightVector.y, upVector.y, backVector.y, rightVector.z, upVector.z, backVector.z)

I’ve seen that constructor on intellisense, but yeah, not on the wiki. Was kinda hoping it actually exists, because it really takes out the annoying statement I just wrote.

1 Like
function fromMatrix(p, rv, tv, bv)
    return CFrame.new(
        p.x, p.y, p.z,
        rv.x, tv.x, bv.x,
        rv.y, tv.y, bv.y,
        rv.z, tv.z, bv.z
    )
end

function rotateCFrameToMatch(a, b)
    local upVector = b.upVector;
    local rightVector = upVector:Cross(-a.lookVector);
    local backVector = rightVector:Cross(upVector);
    return fromMatrix(b.p, rightVector, upVector, backVector);
end

Typed it out on my phone so hopefully I didn’t typo anywhere, auto correct doesn’t like code.

Edit: got on my computer and fixed up the spacing. :stuck_out_tongue:

3 Likes

Haha the fact that you can type that with your phone is impressive! Thanks for the help my friend!

1 Like

Ahh, I see what you mean. Appreciate your help!