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