Sign in to follow this  

Camera/player movement spherically around plant

Recommended Posts

Posted (edited)

Edit: title should be "Camera/player movement spherically around planet", cant change it :p

Hi there, I have been working on a project to with spherical generation of a planet with heighmaps and such, and now want to get a working FPS camera to fly around the planet, the project has been developed using GLFW in C++. I have managed to achieve what i want somewhat but it is very buggy when the player enters certain orientations of the planet, this is the sudo of what I have done:

* normalized the player position and then multiplied by the desired altitude to maintain

* increment camera yaw with mouseX

* calculate the yaw rotation as a quaternion

* calculate the players rot as quaternion (this combines the yaw rotation also)

* set the players rotation in euler angles

* check for and apply wasd movement based on the players current orientation

and here is some of the code on how I am applying this:

void FpsPlayerComponent::Update()
{
	InputManager* input = GameWindow::GetInstance()->GetInputManager();
	float deltaTime = GameWindow::GetInstance()->GetFrameTimer()->GetDeltaTime();
        //GetParent is an entity with a transform component
	Transform* transform = GetParent()->GetTransform();

	glm::vec3 playerPos = transform->GetLocalPosition();
	playerPos = glm::normalize(playerPos);
	playerPos *= _minAltitude;
	transform->SetWorldPosition(playerPos);

	glm::vec2 mouseMovement = input->GetMouseMovement();
	if (mouseMovement.x != 0)
	{
		_playerYaw += mouseMovement.x * deltaTime * 10.0f;
		while (abs(_playerYaw) > 360.0)
		{
			if (_playerYaw > 0)
				_playerYaw -= 360.0f;
			else
				_playerYaw += 360.0F;
		}
	}

	playerPos = transform->GetLocalPosition();
	glm::vec3 playerDir = glm::normalize(playerPos);
	glm::vec3 up = glm::vec3(0, 1, 0);
	glm::vec3 forward = glm::vec3(0, 0, 1);

	glm::mat3 playerYawRot = glm::mat3(glm::rotate(glm::radians(_playerYaw), up));
	glm::quat playerYaw = glm::rotation(forward, forward * playerYawRot);
	glm::quat playerRot = playerYaw * glm::rotation(playerDir, up);

	glm::vec3 euler = glm::eulerAngles(playerRot);
	euler = glm::degrees(euler);
	cout << "euler: " << glm::to_string(euler) << endl;
	transform->SetLocalRotation(glm::vec3(euler.x, euler.y, euler.z));

	float movementSpeed = 25.0f;
	glm::vec3 movement = glm::vec3(0, 0, 0);

	if (input->KeyDown(GLFW_KEY_A))
	{
		movement.x = -movementSpeed * deltaTime;
	}
	else if (input->KeyDown(GLFW_KEY_D))
	{
		movement.x = movementSpeed * deltaTime;
	}

	if (input->KeyDown(GLFW_KEY_W))
	{
		movement.z = -movementSpeed * deltaTime;
	}
	else if (input->KeyDown(GLFW_KEY_S))
	{
		movement.z = movementSpeed * deltaTime;
	}

	movement = movement * transform->GetRotationMatrix();
	glm::vec3 newPos = transform->GetLocalPosition() + movement;
	transform->SetLocalPosition(newPos);
}

I also dont know if the view matrix is calculating correctly now that its not a standard fps camera as the orientation is changing more so here is some code on how I apply the view matrix:

void Camera::LookThrough()
{
	glm::vec3 targetPos = (glm::vec4(0, 0, -1, 1) * _rotationMatrix).xyz();
	targetPos = _position + targetPos;
	//glm::vec3 up(0, 1, 0);
	//glm::vec3 up = (glm::vec4(0, 1, 0, 1) * _rotationMatrix).xyz;

        //look at also works pretty similar
	//glm::mat4 viewMatrix = glm::lookAt(_position, targetPos, up);
	glm::mat4 viewMatrix = _rotationMatrix * glm::translate(-_position);
	//glm::mat4 viewMatrix = _rotationMatrix * glm::translate(_position);
	Renderer::SetWorldMatrix(viewMatrix);
	Lighting::ApplyLighting(viewMatrix, _rotationMatrix, _position);
}

and how I get my rotation matrix of my Tranform object:

glm::mat3 Transform::GetRotationMatrix()
{
	glm::vec3 rot = GetWorldRotation();

	glm::mat4 xRot = glm::rotate(glm::radians(rot.x), glm::vec3(1.0f, 0.0f, 0.0f));
	glm::mat4 yRot = glm::rotate(glm::radians(rot.y), glm::vec3(0.0f, 1.0f, 0.0f));
	glm::mat4 zRot = glm::rotate(glm::radians(rot.z), glm::vec3(0.0f, 0.0f, 1.0f));
	return glm::mat3(zRot * yRot * xRot);
}

also when implementing the rotation of the _playerYaw it rotates fine on the y axis until the _playerYaw if around -/+ 90 degrees, it then looks straight down.

any help is appreciated this has been bugging me for 2 days now ;p

Edited by jikoriko

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this