1/16 - People are scared about quaternions in #GameDev so I'm going to try to demystify them, specifically for gameplay coding and tech art/design, but in general for everybody.
They are like cars: don't have to know how they work to use them! Let's start from the beginning.
Conversation
Replying to
2/16 - Devs avoid quaternions because building them from scratch or reading them is unintuitive.
But there are a lot of gameplay situations where you have to work with rotations without having to translate them to something you know.
And there is where quaternions shine.
GIF
1
26
3/16 - They have many benefits over Euler angles: not suffering from gimbal lock or having spherical interpolation.
For me, it's already easier to do transforms and base changes with them.
Also, they are more compact than transform matrices.
1
20
4/16 - They represent the orientation of a 3D vector or the rotation that transforms the vector (1,0,0) to face that orientation.
Having a look at them we will find a 4-elements vector but we don't have to be able to read them to apply them.
Let's focus on how can be used.
1
1
15
5/16 - We use a quat to rotate a vector or to know where the forward vector of an actor is looking at.
They are applied to vectors to rotate them in 3D space.
In #UE4, to apply an FQuat to an FVector would be as easy as myQuat * myVector.
👁 Notice that is applied to the left.
1
11
6/16 - Imagine: we want to have always at our character's right side some kind of floating device. We can parent it, but if we want to later interpolate with other actors' location, it could be easier to just read the character's position than being parenting and unparenting it.
GIF
2
18
7/16 - To achieve that we have to find the Quat that transforms the Vector (1, 0, 0) and orientates it as the character Right vector.
Then apply that to a vector that is equal to (DesiredDitance, 0, 0) and add character location.
1
12
8/16 - In #UE4 we get the FQuat rightOrientation = FQuat::FindBetweenVectors(FVector(1,0,0), character.GetActorRightVector());
and then apply that like
device->SetActorLocation(character->GetActorLocation() + rightOrientation * FVector(desiredDistance, 0.0f, 0.0f)).
1
16
9/16 - But that would be easily achievable with Rotators, so let's see where quats truly shine.
Quats can be easily applied to other Quats in the same fashion: myQuat1 * myQuat2. We will be adding up
the rotation of myQuat1 to myQuat2.
1
10
10/16 - Beware, because it is not commutable.
If you want to apply a rotation locally, then multiply to the left, if you want it globally, to the right.
1
12
11/16 - And also we can have the inverse of a quaternion. So if myQuat transforms FVector(1,0,0) to a different orientation, the inversed quat is the one that
rotates it back to the original (1,0,0). And this is a very useful tool like we will see in the next example.
1
11
GIF
1
1
26
13/16 - If the mirror normal would be aligned with the X-axis it would be pretty easy to do, because we would multiply by -1 the location, for the position,
and the same for the rotation, we could grab the forward vector of the camera and multiply by -1 the x component.
GIF
1
1
14
14/16 - So what we are going to do is transform our arbitrary mirror into one that is in the origin, and that aligns with the X-axis,
and both cameras will follow relative to it. And then restore it back. As in the pic below.
GIF
1
12
15/16 - The process would be to, first, subtract the mirror location to the camera. Then rotate the inverse quat that the mirror has so its forward vector is aligned
with the (1,0,0) vector.
1
13
4
1
29