I have a CFrame:
Now I want to rotate the CFrame about the up vector to point at a new look vector:
My current solution is to calculate the new right vector with a cross product and construct the new CFrame manually from the 3 component vectors.
local newCF = CFrame.fromMatrix(
pos,
newLook:Cross(up), -- new right
up,
-newLook
)
However, I’d prefer to use a CFrame operation instead. What are my options?
Check out the CFrame:VectorToWorldSpace() options here. It lets you translate an existing vector to a regular world space, that might be what you’re looking for. There are a couple of different options like that in there.
I’m looking for something different. I need an operation/function to rotate a CFrame about an axis.
Here’s a better way to ask my questions: I want to locally rotate a part to point from one vector to another.
The simplest solution to this is just multiplying your CFrame by CFrame.Angles(0, theta, 0)
, which is literally rotating a part about the Y-axis (or UpVector) locally:
local newCF = CF * CFrame.Angles(0, math.pi/2, 0)
--or alternatively, though not the same,
local newCF = CF * CFrame.Angles(0, -math.pi/2, 0)
Not much else to say, there’s nothing to it.
I was thinking that, too. The only problem is finding the angle between the old and new look vectors. You can obviously use dot product for that, but it wouldn’t work if you needed to rotate over 180 degrees.
EDIT: Project the new look onto the old look and old right vector. Then atan2 those two vectors.
1 Like
You could probably factor in the dot product between the look vector and right vector to figure out which side the angle would need to be on:
local baseAngle = math.acos(math.clamp(oldLook:Dot(newLook),0,1))
local direction = oldLook:Dot(newRight)
if direction == 0 then --for the case where CFrame has to spin 180 degrees
direction = 1
end
local angle = -math.sign(direction) * baseAngle --?
local newCF = CF * CFrame.Angles(0,angle,0)
Edit: What you just suggested looks the same as mine it seems.
That seems about right. Thanks!
2 Likes