Rotate a CFrame orientation like a vector

Hello!

Would there be a way to rotate a CFrame orientation using another CFrame in the same manner as rotating a vector using a CFrame ( CFrame:VectorToWorldSpace(Vector3) ) ?

For example, ( 0, 90, 0 ) rotated by ( 90, 0, 0 ) would give ( 0, 0, 90 ) and by ( 45, 0, 0 ) would give ( 0, 45, 45 ).

It is the same behaviour as with the rotation axises when rotating a part which shift positions with each other.

Thanks !

2 Likes

You mean someCFrame:toWorldSpace(otherCFrame)?
That’s the same as someCFrame * otherCFrame
If that’s not working, you need to do some debugging. Go to the console and mess around with CFrames and see where it gets you. Or make a script to visualize all the rotation components in a dummy system. That’s how I test CFrame math.

I saw your other post, I think you need to learn how CFrame rotation matrices work so you can get away from thinking in 90 degree 3-axis rotations. That’s not a good way to think about rotation and it can cause problems.

Edit: Actually that example you gave is not how rotation works anyways. That’s how rotating vectors works in linear algebra, but not rotations.

2 Likes

I tried multiplying the two CFrames but it ends up converging the two. And I did try debugging it and I really don’t know why it isn’t working. Using a vector kinda gives me what I want but because the math behind is made for vectors, it sometimes give invalid values which exceeds 180 degrees.

[ 1, 0, 0 ]
[ 0, 1, 0 ]

[ 1, 1, 0 ]

And, when you say

what do you mean exactly? I use 90 degrees as it is simpler for me to make examples with them.

1 Like

[90, 0, 0] + [0, 90, 0] is supposed to be [90, 90, 0].
The vector [1, 0, 0] rotated by [0, 90, 0] should equal the vector [0, 0, 1].
So to me it looks like you’re confusing rotations and vectors.

That vector isn’t a unit vector, it should be [0.707, 0.707, 0]. CFrames should automatically fix this when you create one.

For rotations you should be using either quaternions or rotation matrices. I prefer rotation matrices.

1 Like

I’m using vectors as it is the closest thing to what I’m trying to do and the way to visualize it. In my case, imagine the rotation is the UpVector of a part ( Y axis ( 0, 1, 0 ) ), now, let say I flip the part by 90 degrees on the X axis. After being flipped, the UpVector becomes ( 0, 0, 1 ) as it has been shifted.

What I’m trying to do is the same but with rotation.

1 Like

Okay that first paragraph checks out but I’m still confused on the second paragraph.
You’re trying to treat rotations like vectors? I can’t imagine why, but I’ll suppress that for now. So you’re trying to rotate a vector of [0, 90, 0] around the X axis?
[0, 90, 0] * [-1, 0, 0] = [0, 0, 90]
You’ll need to do vector multiplication to get this.

1 Like

Ok, so you understood the core concept of what I’m trying to do. Now, I need to find a way to do the same but with rotation.

You’re example would become this.
[0, 90, 0] ? [90, 0, 0] = [0, 0, 90]

1 Like

[-1, 0, 0] is rotating it 90 degrees on the X axis.
If you want to save some hassle during testing, you can probably piggyback off of CFrames, but it would be inefficient.

(CFrame.new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0) * CFrame.Angles(math.rad(90), 0, 0)).lookVector

Is this what you’re looking for?

1 Like

I removed the .LookVector as it created issues if not rotating it at 90 degrees.
(CFrame.new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0) * CFrame.Angles(math.rad(45), 0, 0))
Tough it still doesn’t work properly as it returns ( 0, 63, -63 ) when it should return ( 0, 45, 45 ).

1 Like

Oh I see. Yeah so that’s not vector rotation either. You’ll need to divide it up with if statements then or write a custom system.

1 Like

What do you mean exactly with the if statment and the system?

1 Like

Well you’re trying to do something that is neither rotation nor linear algebra. You’ll probably need to make some custom algorithm for it. Why do you need this?

1 Like

I’m making a gyroscopic camera system and I’m trying to make the head look where the user is looking. By default the head rotates with the torso so an offset has to be applied to counter this.

This offset disalign the other axises creating unwanted behaviour where if you bend down it will bend on the left and so on.

It is like rotating a part whitout updating the RightVector.

1 Like

Dude you just need to figure out the orientation of set up and multiply by a CFrame. This is what was suggested in the other thread.

2 Likes

Well, as I stated before, this doesn’t work as the desaligment is still present. Or I don’t understand what you are telling me.

1 Like

Share the code you are currently using which causes this axis alteration and I may be able to provide some help

1 Like

So you need to take the camera vector and multiply by the inverse of the character’s vector and get the angle of the resulting vector, then apply that to the neck joint.

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local Players = game:GetService("Players")
local Player = Players.LocalPlayer

local Character = Player.CharacterAdded:Wait()

local Head = Character:WaitForChild("Head")
local Neck = Head.Neck
local NeckConnect = Neck.Part0

local Camera = workspace.CurrentCamera
local CurrentRotation = Camera.CFrame

wait()

if UserInputService.GyroscopeEnabled then
	Camera.CameraType = "Scriptable"

	RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, function()
		local Input, RotCFrame = UserInputService:GetDeviceRotation()
		local X, Y, Z = RotCFrame:ToOrientation()

		CurrentRotation = CFrame.fromEulerAnglesYXZ(X, Z, Y):ToWorldSpace(CFrame.Angles(math.rad(-90), 0, 0))
		Camera.CFrame = CFrame.new(Head.Position) * CurrentRotation
		Camera.Focus = CFrame.new(CurrentRotation * Vector3.new(0, 0, -10))
		Neck.C0 = CFrame.new(Neck.C0.Position) * (CurrentRotation * NeckConnect.CFrame.Rotation:Inverse())
	end)
	
	Player.CharacterAdded:Connect(function(NewCharacter)
		wait()
		Character = NewCharacter
		
		Head = Character:WaitForChild("Head")
		Neck = Head.Neck
		NeckConnect = Neck.Part0
	end)
end

It works perfectly but if the torso rotation isn’t 0 then it will start to desalign. And some of the modifications to the rotation are made due to IOS axises being swaped.

It has been an hour since the last sign of activity. Could you clarify if you are able to help with this or not.

Thanks!

So most of the action seems to be happening on this line here:

but the CurrentRotation CFrame is also of interest.

Presumably the camera is meant to be positioned relative to the torso / Neck.Part0.

I think the solution looks something like this.

Camera.CFrame = CFrame.new(Head.Position) * RotCFrame.Rotation
Camera.Focus = Camera.CFrame * Vector3.new(0,0,10)

 Neck.C0 = RotCFrame.Rotation * Neck.Part0.CFrame:inverse() * CFrame.new(Neck.Part1.Position)

Now if you have issues with axes not being what you expect you can replace RotCFrame.Rotation with something like CFrame.Angles(x, y, z) * RotCFrame.Rotation where you’ll need to figure out x, y, z.