Commit d02f2309 authored by Adam Štěpánek's avatar Adam Štěpánek
Browse files

Finish implementing positional camera

parent bda71f63
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ private:
	GLuint _id;

public:
	GLuint id() {
	GLuint id() const {
		return _id;
	}
};
+33 −12
Original line number Diff line number Diff line
@@ -8,8 +8,7 @@
///
/// Use left mouse button to change the point of view.
/// Use right mouse button to zoom in and zoom out.
class RotateCamera
{
class RotateCamera {
private:
	/// Constants that defines the behaviour of the camera
	///		- Minimum elevation in radians
@@ -28,24 +27,28 @@ class RotateCamera
	///		- 90 degrees .. I look in -x direction
	///		- 180 degrees .. I look in +z direction
	///		- 270 degrees .. I look in +x direction
	float angleDirection;
	float _angleDirection = 0.0f;

	/// angle_direction is an angle in which determines from which "height" I look.
	///		- positive elevation .. I look from above the xz plane
	///		- negative elevation .. I look from below the xz plane
	float angleElevation;
	float _angleElevation = 0.5f;

	/// Distance from (0,0,0), the point at which I look
	float distance;
	float _distance = 50.0f;

	/// Final position of the eye in world space coordinates, for LookAt or shaders
	glm::vec3 eyePosition;
	glm::vec3 _eyePosition;

	/// Last X and Y coordinates of the mouse cursor
	int lastX, lastY;
	int _lastX = 0;
	int _lastY = 0;

	/// True or false if moused buttons are pressed and the user rotates/zooms the camera
	bool isRotating, isZooming;
	bool _isRotating = false;
	bool _isZooming = false;

	glm::vec3 _center = glm::vec3(0.0f, 0.0f, 0.0f);

	/// Recomputes 'eye_position' from 'angle_direction', 'angle_elevation', and 'distance'
	void updateEyePos();
@@ -60,7 +63,25 @@ class RotateCamera
	void onMouseMove(double x, double y);

	/// Returns the position of the eye in world space coordinates
	glm::vec3 getEyePosition() const {
		return eyePosition;
	glm::vec3 eyePosition() const {
		return _eyePosition;
	}

	glm::vec3 center() const {
		return _center;
	}

	void center(const glm::vec3 value) {
		_center = value;
		updateEyePos();
	}

	float angleDirection() const {
		return _angleDirection;
	}

	void angleDirection(float value) {
		_angleDirection = value;
		updateEyePos();
	}
};
+26 −32
Original line number Diff line number Diff line
@@ -8,63 +8,57 @@ const float RotateCamera::minDistance = 1.0f;
const float RotateCamera::angleSensitivity = 0.008f;
const float RotateCamera::zoomSensitivity = 0.003f;

RotateCamera::RotateCamera()
    : angleDirection(0.0f), angleElevation(0.785398163f), distance(15.0f), lastX(0), lastY(0), isRotating(false),
      isZooming(false)
{
RotateCamera::RotateCamera() {
	updateEyePos();
}

void RotateCamera::updateEyePos()
{
	eyePosition.x = distance * cosf(angleElevation) * -sinf(angleDirection);
	eyePosition.y = distance * sinf(angleElevation);
	eyePosition.z = distance * cosf(angleElevation) * cosf(angleDirection);
void RotateCamera::updateEyePos() {
	_eyePosition.x = _center.x + _distance * cosf(_angleElevation) * -sinf(_angleDirection);
	_eyePosition.y = _center.y + _distance * sinf(_angleElevation);
	_eyePosition.z = _center.z + _distance * cosf(_angleElevation) * cosf(_angleDirection);
}

void RotateCamera::onMouseButton(int button, int action, int mods)
{
void RotateCamera::onMouseButton(int button, int action, int mods) {
	// Left mouse button affects the angles
	if (button == GLFW_MOUSE_BUTTON_LEFT) {
		if (action == GLFW_PRESS) {
			isRotating = true;
			_isRotating = true;
		} else {
			isRotating = false;
			_isRotating = false;
		}
	}
	// Right mouse button affects the zoom
	if (button == GLFW_MOUSE_BUTTON_RIGHT) {
		if (action == GLFW_PRESS) {
			isZooming = true;
			_isZooming = true;
		} else {
			isZooming = false;
			_isZooming = false;
		}
	}
}

void RotateCamera::onMouseMove(double x, double y)
{
	float dx = float(x - lastX);
	float dy = float(y - lastY);
	lastX = static_cast<int>(x);
	lastY = static_cast<int>(y);
void RotateCamera::onMouseMove(double x, double y) {
	float dx = float(x - _lastX);
	float dy = float(y - _lastY);
	_lastX = static_cast<int>(x);
	_lastY = static_cast<int>(y);

	if (isRotating) {
		angleDirection += dx * angleSensitivity;
		angleElevation += dy * angleSensitivity;
	if (_isRotating) {
		_angleDirection += dx * angleSensitivity;
		_angleElevation += dy * angleSensitivity;

		// Clamp the results
		if (angleElevation > maxElevation)
			angleElevation = maxElevation;
		if (angleElevation < minElevation)
			angleElevation = minElevation;
		if (_angleElevation > maxElevation)
			_angleElevation = maxElevation;
		if (_angleElevation < minElevation)
			_angleElevation = minElevation;
	}
	if (isZooming) {
		distance *= (1.0f + dy * zoomSensitivity);
	if (_isZooming) {
		_distance *= (1.0f + dy * zoomSensitivity);

		// Clamp the results
		if (distance < minDistance)
			distance = minDistance;
		if (_distance < minDistance)
			_distance = minDistance;
	}
	updateEyePos();
}
+19 −35
Original line number Diff line number Diff line
@@ -4,9 +4,9 @@ Application::Application(size_t initialWidth, size_t initialHeight) {
	this->width = initialWidth;
	this->height = initialHeight;

	cameraUbo.position = glm::vec4(camera.getEyePosition(), 1.0f);
	cameraUbo.position = glm::vec4(camera.eyePosition(), 1.0f);
	cameraUbo.projection = glm::perspective(glm::radians(45.0f), float(width) / float(height), 0.01f, 1000.0f);
	cameraUbo.view = glm::lookAt(camera.getEyePosition(), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
	cameraUbo.view = glm::lookAt(camera.eyePosition(), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

	LightUBO directionalLight;
	directionalLight.position = glm::vec4(1.0f, 1.0f, 1.0f, 0.0f);
@@ -25,24 +25,12 @@ Application::Application(size_t initialWidth, size_t initialHeight) {
	beltMaterial.diffuseColor(glm::vec4(1.0f));
	beltMaterial.specularColor(glm::vec4(1.0f, 1.0f, 1.0f, 2048.0f));

	pioneerModelMatrix = glm::mat4(1.0f);
	pioneerModelMatrix = glm::translate(pioneerModelMatrix, glm::vec3(0.0f, 4.0f, 15.0f));
	pioneerModelMatrix = glm::scale(pioneerModelMatrix, glm::vec3(0.2f));
	pioneerModelMatrix = glm::rotate(pioneerModelMatrix, -3.14159f / 8.0f, glm::vec3(1.0, 0.0, 0.0));
	pioneer.modelMatrix() = glm::scale(pioneer.modelMatrix(), glm::vec3(0.2f));
	pioneer.modelMatrix() = glm::rotate(pioneer.modelMatrix(), -3.14159f / 8.0f, glm::vec3(1.0, 0.0, 0.0));

	voyagerModelMatrix = glm::mat4(1.0f);
	voyagerModelMatrix = glm::translate(voyagerModelMatrix, glm::vec3(20.0f, 2.0f, 0.0f));
	voyagerModelMatrix = glm::scale(voyagerModelMatrix, glm::vec3(0.1f));
	voyagerModelMatrix = glm::rotate(voyagerModelMatrix, 3.14159f / 2.0f, glm::vec3(1.0, 0.0, 0.0));
	voyagerModelMatrix = glm::rotate(voyagerModelMatrix, 3.14159f / 2.0f, glm::vec3(0.0, 0.0, 1.0));

	ulyssesModelMatrix = glm::mat4(1.0f);

	galileoModelMatrix = glm::mat4(1.0f);

	cassiniModelMatrix = glm::mat4(1.0f);

	junoModelMatrix = glm::mat4(1.0f);
	voyager.modelMatrix() = glm::scale(voyager.modelMatrix(), glm::vec3(0.1f));
	voyager.modelMatrix() = glm::rotate(voyager.modelMatrix(), 3.14159f / 2.0f, glm::vec3(1.0, 0.0, 0.0));
	voyager.modelMatrix() = glm::rotate(voyager.modelMatrix(), 3.14159f / 2.0f, glm::vec3(0.0, 0.0, 1.0));

	glCreateBuffers(1, &cameraBuffer);
	glNamedBufferStorage(cameraBuffer, sizeof(CameraUBO), &cameraUbo, GL_DYNAMIC_STORAGE_BIT);
@@ -79,25 +67,20 @@ void Application::drawProbe(Scene &scene, const glm::mat4 &modelMatrix) {
}

void Application::render() {
	time = glfwGetTime();
	// --------------------------------------------------------------------------
	// Update data
	// --------------------------------------------------------------------------

	time = glfwGetTime();
	if (lastTime > 0.0) {
		rotateProbeMatrix(pioneerModelMatrix, 0.2f);
		rotateProbeMatrix(voyagerModelMatrix, -0.1f);
	}
	pioneer.update();
	voyager.update();

	// Camera
	glm::vec3 cameraPosition;
	if (followedProbe) {
		cameraPosition = glm::vec3(*followedProbe * glm::vec4(camera.getEyePosition(), 1.0f));
	} else {
		cameraPosition = camera.getEyePosition();
		camera.center(followedProbe->position());
		camera.angleDirection(camera.angleDirection() - followedProbe->deltaAngle());
	}
	cameraUbo.position = glm::vec4(cameraPosition, 1.0f);
	cameraUbo.view = glm::lookAt(cameraPosition, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
	cameraUbo.position = glm::vec4(camera.eyePosition(), 1.0f);
	cameraUbo.view = glm::lookAt(camera.eyePosition(), camera.center(), glm::vec3(0.0f, 1.0f, 0.0f));
	glNamedBufferSubData(cameraBuffer, 0, sizeof(CameraUBO), &cameraUbo);

	// Belt
@@ -147,8 +130,8 @@ void Application::render() {
	glBindVertexArray(teapot.vao());
	glDrawElementsInstanced(teapot.mode(), teapot.indicesCount(), GL_UNSIGNED_INT, nullptr, 2048);

	drawProbe(pioneer, pioneerModelMatrix);
	drawProbe(voyager, voyagerModelMatrix);
	pioneer.draw();
	voyager.draw();
	//drawScene(ulysses, ulyssesModelMatrix);
	//drawScene(galileo, galileoModelMatrix);
	//drawScene(cassini, cassiniModelMatrix);
@@ -206,12 +189,13 @@ void Application::onKeyPressed(GLFWwindow *window, int key, int scancode, int ac
	switch (key) {
	case GLFW_KEY_0:
		followedProbe = nullptr;
		camera.center(glm::vec3(0.0f));
		break;
	case GLFW_KEY_1:
		followedProbe = &pioneerModelMatrix;
		followedProbe = &pioneer;
		break;
	case GLFW_KEY_2:
		followedProbe = &voyagerModelMatrix;
		followedProbe = &voyager;
		break;
	}
}
 No newline at end of file
+8 −13
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

#include "mesh.hpp"
#include "playback.hpp"
#include "probe.hpp"
#include "program.hpp"
#include "rotate_camera.hpp"
#include "scene.hpp"
@@ -63,18 +64,12 @@ private:
	Mesh teapot = Mesh::teapot();
	Mesh polarTeapot = Mesh::polarTeapot();

	Scene pioneer = Scene("objects/pioneer/pioneer.obj");
	glm::mat4 pioneerModelMatrix;
	Scene voyager = Scene("objects/voyager/voyager.obj");
	glm::mat4 voyagerModelMatrix;
	//Scene ulysses = Scene("objects/ulysses/ulysses.obj");
	glm::mat4 ulyssesModelMatrix;
	//Scene galileo = Scene("objects/galileo/galileo.obj");
	glm::mat4 galileoModelMatrix;
	//Scene cassini = Scene("objects/cassini/cassini.obj");
	glm::mat4 cassiniModelMatrix;
	//Scene juno = Scene("objects/juno/Juno.obj");
	glm::mat4 junoModelMatrix;
	Probe pioneer = Probe("objects/pioneer/pioneer.obj", { 0.0f, 4.0f, 15.0f }, 0.2f, texturedObjectProgram, normalMappedObjectProgram);
	Probe voyager = Probe("objects/voyager/voyager.obj", { 20.0f, 2.0f, 0.0f }, -0.1f, texturedObjectProgram, normalMappedObjectProgram);
	//Probe ulysses = Probe("objects/ulysses/ulysses.obj", { 20.0f, 2.0f, 0.0f }, texturedObjectProgram, normalMappedObjectProgram);
	//Probe galileo = Probe("objects/galileo/galileo.obj", { 20.0f, 2.0f, 0.0f }, texturedObjectProgram, normalMappedObjectProgram);
	//Probe cassini = Probe("objects/cassini/cassini.obj", { 20.0f, 2.0f, 0.0f }, texturedObjectProgram, normalMappedObjectProgram);
	//Probe juno = Probe("objects/juno/Juno.obj", { 20.0f, 2.0f, 0.0f }, texturedObjectProgram, normalMappedObjectProgram);

	Material jupiterMaterial;
	glm::mat4 jupiterModelMatrix;
@@ -103,7 +98,7 @@ private:
	double lastTime = 0.0f;
	double music[Playback::magicCount] = { 0 };
	const double musicStepDown = -0.03;
	glm::mat4 *followedProbe = nullptr;
	Probe *followedProbe = nullptr;

	void rotateProbeMatrix(glm::mat4 &modelMatrix, float velocity);
	void drawProbe(Scene &scene, const glm::mat4 &modelMatrix);
Loading