Camera improvements

- Remove the degenerate case of vertical directions, by updating the viewup as the camera moves.
- Remove the consequent limitation to 89.9 degrees.
- Add (unused so far) camera roll angle, with setter.
- Add accessors for all angles. Lua will want to know that.
- Rename m_angleV/H to m_viewAngleV/H to distinguish them clearly from the orientation of the mesh. They will differ e.g. when the player is sitting somewhere.
- Rename vertical turn so it includes 'view' in the name, because this one does not affect the player's rotation as turnH does.
- Make player look north at start, like it originally did before the Z-up changes.
This commit is contained in:
Pedro Gimeno 2020-02-24 14:12:30 +01:00 committed by Gitea
parent 4fc45e3d93
commit 4f37012931
3 changed files with 42 additions and 29 deletions

View File

@ -46,7 +46,7 @@ class ClientPlayer : public Player {
ClientPlayer(gk::Camera &camera);
void turnH(double angle);
void turnV(double angle);
void turnViewV(double angle);
void move(double direction);
@ -55,9 +55,9 @@ class ClientPlayer : public Player {
void checkCollisions(const ClientWorld &world);
double dirTargetedX() const { return cos(m_angleH * RADIANS_PER_DEGREES) * cos(m_angleV * RADIANS_PER_DEGREES); }
double dirTargetedY() const { return sin(m_angleH * RADIANS_PER_DEGREES) * cos(m_angleV * RADIANS_PER_DEGREES) - 0.00001; }
double dirTargetedZ() const { return sin(m_angleV * RADIANS_PER_DEGREES); }
double dirTargetedX() const { return m_forwardDir.x; }
double dirTargetedY() const { return m_forwardDir.y; }
double dirTargetedZ() const { return m_forwardDir.z; }
static ClientPlayer &getInstance() { return *s_instance; }
static void setInstance(ClientPlayer *instance) { s_instance = instance; }
@ -66,12 +66,18 @@ class ClientPlayer : public Player {
double y() const { return m_y; }
double z() const { return m_z; }
double cameraYaw() const { return m_viewAngleH; }
double cameraPitch() const { return m_viewAngleV; }
double cameraRoll() const { return m_viewAngleRoll; }
void setPosition(double x, double y, double z);
void setCameraRoll(double angle) { m_viewAngleRoll = angle; updateDir(); };
gk::Camera &camera() { return m_camera; }
private:
void testPoint(const ClientWorld &world, double x, double y, double z, glm::dvec3 &vel);
void updateDir();
static ClientPlayer *s_instance;
@ -81,8 +87,12 @@ class ClientPlayer : public Player {
double m_y;
double m_z;
double m_angleH;
double m_angleV;
double m_viewAngleH;
double m_viewAngleV;
double m_viewAngleRoll;
// TODO: Add model transform
gk::Vector3d m_forwardDir;
glm::dvec3 m_velocity{0};
bool m_isJumping = false;

View File

@ -47,7 +47,6 @@ GameState::GameState(const std::string &host, int port) {
m_textureAtlas = &gk::ResourceHandler::getInstance().get<TextureAtlas>("atlas-blocks");
m_camera.setUpVector(gk::Vector3d{0., 0., 1.});
m_camera.setAspectRatio((float)Config::screenWidth / Config::screenHeight);
initShaders();
@ -77,7 +76,7 @@ void GameState::onEvent(const SDL_Event &event) {
if (event.type == SDL_MOUSEMOTION) {
if(Config::screenWidth / 2.0f != event.motion.x || Config::screenHeight / 2.0f != event.motion.y) {
m_player.turnH(event.motion.xrel * -0.01 * Config::mouseSensitivity);
m_player.turnV(event.motion.yrel * -0.01 * Config::mouseSensitivity);
m_player.turnViewV(event.motion.yrel * -0.01 * Config::mouseSensitivity);
gk::Mouse::resetToWindowCenter();
}

View File

@ -38,41 +38,45 @@ ClientPlayer::ClientPlayer(gk::Camera &camera) : m_camera(camera) {
m_y = 14;
m_z = 20;
m_angleH = -90.0;
m_angleV = 0.01;
m_viewAngleH = 90.;
m_viewAngleV = 0.01;
m_viewAngleRoll = 0.;
updateDir();
m_camera.setDPosition(m_x, m_y, m_z - 0.1);
m_camera.setDirection(dirTargetedX(), dirTargetedY(), dirTargetedZ());
}
void ClientPlayer::turnH(double angle) {
m_angleH += angle;
m_viewAngleH = (m_viewAngleH + angle >= -180. && m_viewAngleH + angle < 0.) ?
m_viewAngleH + angle : fmod(m_viewAngleH + angle, 360.);
while(m_angleH >= 180.0) {
m_angleH -= 360.0;
}
while(m_angleH < -180.0) {
m_angleH += 360.0;
}
if (m_viewAngleH >= 180.) m_viewAngleH -= 360.;
m_camera.setDirection(dirTargetedX(), dirTargetedY(), dirTargetedZ());
updateDir();
}
void ClientPlayer::turnV(double angle) {
m_angleV += angle;
void ClientPlayer::turnViewV(double angle) {
m_viewAngleV = std::max(std::min(m_viewAngleV + angle, 90.), -90.);
if(89.9 < m_angleV) {
m_angleV = 89.9;
}
else if(-89.9 > m_angleV) {
m_angleV = -89.9;
}
updateDir();
}
m_camera.setDirection(dirTargetedX(), dirTargetedY(), dirTargetedZ());
void ClientPlayer::updateDir() {
double ch = cos(m_viewAngleH * RADIANS_PER_DEGREES);
double sh = sin(m_viewAngleH * RADIANS_PER_DEGREES);
double cv = cos(m_viewAngleV * RADIANS_PER_DEGREES);
double sv = sin(m_viewAngleV * RADIANS_PER_DEGREES);
double cr = cos(m_viewAngleRoll * RADIANS_PER_DEGREES);
double sr = sin(m_viewAngleRoll * RADIANS_PER_DEGREES);
m_forwardDir = gk::Vector3d{ch * cv, sh * cv, sv};
m_camera.setDirection(m_forwardDir);
m_camera.setUpVector(gk::Vector3d{sh * sr - ch * sv * cr, -ch * sr - sh * sv * cr, cv * cr});
}
void ClientPlayer::move(double direction) {
direction += m_angleH;
direction += m_viewAngleH;
m_velocity.x = 0.04 * cos(direction * RADIANS_PER_DEGREES);
m_velocity.y = 0.04 * sin(direction * RADIANS_PER_DEGREES);