Camera that follows object + rotations

I am creating a 3D space shooter using OpenGL. I have a camera that is set to follow the player’s spaceship. I have managed to keep it at a certain distance and rotate together with the spaceship on the Y axis. See the code bellow for the camera :

float CalculateHorizontalDistance() {
	if (!mpPlayer) return 0.f;

	return distanceFromPlayer * glm::cos(glm::radians(-UpAngle));
}

float CalculateVerticalDistance() {
	if (!mpPlayer) return 0.f;

	return distanceFromPlayer * glm::sin(glm::radians(-UpAngle));
}

void calculateCameraPosition(float horizDistance, float verticDistance)
{
	if (!mpPlayer) return;

	float theta = mpPlayer->GetRotationY() + angleAroundPlayer;
	float offsetX = horizDistance * glm::sin(glm::radians(theta));
	float offsetZ = horizDistance * glm::cos(glm::radians(theta));

	Position.x = mpPlayer->GetPosition().x - offsetX;
	Position.y = mpPlayer->GetPosition().y + verticDistance;
	Position.z = mpPlayer->GetPosition().z - offsetZ;
}

Also the update and update vectors

void Update() {
	float horizDistance = CalculateHorizontalDistance();
	float vertDistance = CalculateVerticalDistance();
	calculateCameraPosition(horizDistance, vertDistance);

	if (mpPlayer)
	{
		RightAngle = 180.f - (mpPlayer->GetRotationY() + angleAroundPlayer);
	}

	updateCameraVectors();
}

void updateCameraVectors()
{
	// Yaw
	glm::quat aroundY = glm::angleAxis(glm::radians(-RightAngle), glm::vec3(0, 1, 0));

	// Pitch
	glm::quat aroundX = glm::angleAxis(glm::radians(UpAngle), glm::vec3(1, 0, 0));

	// Roll
	glm::quat aroundZ = glm::angleAxis(glm::radians(RollAngle), glm::vec3(0, 0, 1));

	Orientation = aroundY * aroundX * aroundZ;

	glm::quat qF = Orientation * glm::quat(0, 0, 0, -1) * glm::conjugate(Orientation);
	Front = { qF.x, qF.y, qF.z };
	Right = glm::normalize(glm::cross(Front, WorldUp));
	Up = glm::normalize(glm::cross(Right, Front));

}

and how I calculate the view

glm::mat4 GetViewMatrix()
{
	// You should know the camera move reversely relative to the user input.
	// That's the point of Graphics Camera

	glm::quat reverseOrient = glm::conjugate(Orientation);
	glm::mat4 rot = glm::mat4_cast(reverseOrient);
	glm::mat4 translation = glm::translate(glm::mat4(1.0), -Position);

	return rot * translation;
}

Although I am near to what I want my camera to do, I am not there yet. I would like the Camera to follow and rotate together with the spaceship and actually follow it. I can not wrap my mind around on how to make it follow the rotations on X and Z axis. Any help on how to achieve this? Code or ideas are welcomed and I hope this is the correct group for these kind of problems.

hi paokakis
Yaw, pitch, roll sounds just right for a pilot, but for a camera? I’ve chosen to use two angles, hight above/below ‘ground’ and a geographic angle. It’ll also give you a better chance to visualize. They suffice to construct any direction and it’s fairly easy to convert between angles and matrix. I suppose that you’ll have to choose one arbitrary angle for one of the three to get the associate to others.
As for the quaternions, I’m no help.
I’m not really sure of your camera use.
There is an end to how difficult it is to get the modelView from the camera & model world-matrixes.
If camera has a fixed pose relative to ship, the camera-matrix is given by the ship-matrix … the camera-forward could be something like vec = -cross(ship-forward,ship-up) [looking perpendicular at the side of the ship] and the constant camera->ship-distance is using this direction too to get to cam-position = ship-position - distance * vec (probably normalizing somewhere). Then the camera-matrix should have the invers-transpose to become a proper modelView-matrix.
Have no clue of how you can translate this into quaternion-lingo …

looking back at your code I can see that I’ve made the assumption that you’ve converted all the player-input into a matrix that you need somewhere for drawing. When you have that matrix, you can eak out the unite-vectors and position from there … Once they are converted into the matrix you don’t have to keep track of them.

I think you may helped me see the problem in a different way when you said :

If camera has a fixed pose relative to ship, the camera-matrix is given by the ship-matrix

I will try in the afternoon to use the ship matrix for the camera matrix and update with my results…

I’ve been testing out a matrix by compairing it with glLookAt(). The glLookAt() takes two positions as input, and the up-director. You could keep track of the cumulative yaw, pitch, roll and thus have camera-forward at hand. I will also need to keep track of camera-position in world-space since the view-matrix magically appear from
matrix invers_orient; //rotate -yaw, -pitch, -roll on an identity … or fill in the unit vectors (-forw, -right, -up)
matrix view = glm::translate(invers_orient, -camera_position) .
If you move the camera, you will be able to know position of where it ends if it follows the forward vector?

Thank you for the message. I managed to fix the problem using the yaw, pitch and roll of the spaceship in the camera calculation, but I’ll try your way also

I don’t know how I could miss out on the fact that the view-matrix is the mathemathical invers of the camera. That forces some expression of the camera-position to be present. The camera-matrix is not symmetric so the two transforms (rotation and translation) needs to be individually inversed [no conformance to LookAt, see below]; but also their order of concatenation… as I get it … this seems to be far easier to remember than to fiddle with the geometry in one’s head.
I noticed a solution to the position ‘problem’ for some ‘position-loose’ setup … he simply used center of screen as startout.
-------------- addition: -------------
If you setup the projection from scratch, from basic geometric principle, you should be warned, that from there, the inner openGL appears to be left-handed. A swap of z direction may be needed. This could be handy to know since you may scorn the view-matrix to be faul.

no conformance
I use a calculated rotation from the forward-vector but negates the 3 unite-vectors calculated. A plain inversion or transpose does not hit the target. Sorry for being a constant confusion.

I should know better than to keep stepping in it. But, I’ve probably found my faul thinking.
The eye-matrix looked for seems very aptly named for the real-world space that it models. That is not the view-box infront of the camera, but the eqvivalent box that emanates from the eye towards it’s sensors inside the eye. In the real world, this space is ‘on it’s head’ and left/right flipped looking in +z direction … perfectly primed for the projection.