Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411500 Posts in 69373 Topics- by 58429 Members - Latest Member: Alternalo

April 25, 2024, 12:44:25 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Camera/player movement spherically around planet
Pages: [1]
Print
Author Topic: Camera/player movement spherically around planet  (Read 836 times)
jikoriko
Level 0
*


View Profile
« on: April 22, 2017, 01:20:14 PM »

Hi there, I have been working on a project to do 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 to achieve spherical movement:

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

* increment player yaw with mouseX

* calculate the yaw rotation of the player(quaternion)

* calculate the players orientation (this combines the yaw rotation also) based on their direction from planet

* set the players orientation

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



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

Code:
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 not sure 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:
Code:
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:
Code:
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 is around -/+ 90 degrees, it then looks straight down.

any help is appreciated this has been bugging me for days now ;p
Logged
jikoriko
Level 0
*


View Profile
« Reply #1 on: April 26, 2017, 02:58:06 PM »

Hi there, thought I would update this as I have found a work around solution for the time being,
I think the issue stemmed from allowing the camera to have any orientation, but now I am stationing
the camera/player directly above the planet, and when I press the wasd keys or rotate the mouse it
rotates the planet instead of moving the player, this achieves the effect of moving around the planet.
this solution works fine in the current context as this project is my dissertation and revolves around
a 3D simulation and the terraforming of the planet mars, so no other planetary bodies need to be considered.
It would be ideal to find a solution to the player moving and orientating around the planet though if
I were to continue on any other space/planet simulation projects in the future.

Thanks for your time, Jikoriko.
Logged
oahda
Level 10
*****



View Profile
« Reply #2 on: April 27, 2017, 03:01:53 AM »

That's what I did in our LD game just this weekend, haha. Rotated stuff around the player too.
Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic