Precision improvements (Part 2)
Improve player precision, especially location, but also rotation.
This commit is contained in:
parent
4bb12c872f
commit
6e3c2e066f
@ -45,50 +45,50 @@ class ClientPlayer : public Player {
|
||||
public:
|
||||
ClientPlayer(gk::Camera &camera);
|
||||
|
||||
void turnH(float angle);
|
||||
void turnV(float angle);
|
||||
void turnH(double angle);
|
||||
void turnV(double angle);
|
||||
|
||||
void move(float direction);
|
||||
void move(double direction);
|
||||
|
||||
void processInputs();
|
||||
void updatePosition(const ClientWorld &world);
|
||||
|
||||
void checkCollisions(const ClientWorld &world);
|
||||
|
||||
float pointTargetedX() const { return m_x + cos(m_angleH * RADIANS_PER_DEGREES) * cos(m_angleV * RADIANS_PER_DEGREES); }
|
||||
float pointTargetedY() const { return m_y + sin(m_angleH * RADIANS_PER_DEGREES) * cos(m_angleV * RADIANS_PER_DEGREES) - 0.00001; }
|
||||
float pointTargetedZ() const { return m_z + sin(m_angleV * RADIANS_PER_DEGREES); }
|
||||
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); }
|
||||
|
||||
static ClientPlayer &getInstance() { return *s_instance; }
|
||||
static void setInstance(ClientPlayer *instance) { s_instance = instance; }
|
||||
|
||||
float x() const { return m_x; }
|
||||
float y() const { return m_y; }
|
||||
float z() const { return m_z; }
|
||||
double x() const { return m_x; }
|
||||
double y() const { return m_y; }
|
||||
double z() const { return m_z; }
|
||||
|
||||
void setPosition(float x, float y, float z);
|
||||
void setPosition(double x, double y, double z);
|
||||
|
||||
gk::Camera &camera() { return m_camera; }
|
||||
|
||||
private:
|
||||
void testPoint(const ClientWorld &world, float x, float y, float z, glm::vec3 &speed);
|
||||
void testPoint(const ClientWorld &world, double x, double y, double z, glm::dvec3 &vel);
|
||||
|
||||
static ClientPlayer *s_instance;
|
||||
|
||||
gk::Camera &m_camera;
|
||||
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
|
||||
float m_angleH;
|
||||
float m_angleV;
|
||||
double m_angleH;
|
||||
double m_angleV;
|
||||
|
||||
glm::vec3 m_velocity{0};
|
||||
glm::dvec3 m_velocity{0};
|
||||
bool m_isJumping = false;
|
||||
|
||||
const float m_gravity = 0.001;
|
||||
const float m_jumpSpeed = 0.06f;
|
||||
const double m_gravity = 0.001;
|
||||
const double m_jumpSpeed = 0.06f;
|
||||
};
|
||||
|
||||
#endif // CLIENTPLAYER_HPP_
|
||||
|
@ -115,8 +115,8 @@ void BlockCursor::onEvent(const SDL_Event &event, const Hotbar &hotbar) {
|
||||
if (!blockId || block.drawType() == BlockDrawType::Liquid) {
|
||||
// Second, we check if the new block is not inside the player
|
||||
const Block &newBlock = Registry::getInstance().getBlock(hotbar.currentItem());
|
||||
gk::FloatBox boundingBox = newBlock.boundingBox() + gk::Vector3i{x, y, z};
|
||||
gk::FloatBox playerBoundingBox = m_player.hitbox() + gk::Vector3f{m_player.x(), m_player.y(), m_player.z()};
|
||||
gk::FloatBox boundingBox = newBlock.boundingBox() + gk::Vector3f(x - m_player.x(), y - m_player.y(), z - m_player.z());
|
||||
gk::FloatBox playerBoundingBox = m_player.hitbox();
|
||||
if (!boundingBox.intersects(playerBoundingBox)) {
|
||||
m_world.setBlock(x, y, z, hotbar.currentItem());
|
||||
|
||||
@ -242,7 +242,7 @@ void BlockCursor::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
||||
glCheck(glDisable(GL_CULL_FACE));
|
||||
|
||||
// Subtract the camera position - see comment in ClientWorld::draw()
|
||||
gk::Vector3d cameraPosition = m_player.camera().getPosition();
|
||||
gk::Vector3d cameraPosition = m_player.camera().getDPosition();
|
||||
states.transform.translate(m_selectedBlock.x - cameraPosition.x, m_selectedBlock.y - cameraPosition.y, m_selectedBlock.z - cameraPosition.z);
|
||||
|
||||
target.draw(m_vbo, GL_LINES, 0, 24, states);
|
||||
@ -259,9 +259,9 @@ void BlockCursor::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
||||
}
|
||||
|
||||
glm::ivec4 BlockCursor::findSelectedBlock() const {
|
||||
glm::dvec3 position{m_player.camera().getPosition().x,
|
||||
m_player.camera().getPosition().y,
|
||||
m_player.camera().getPosition().z};
|
||||
glm::dvec3 position{m_player.camera().getDPosition().x,
|
||||
m_player.camera().getDPosition().y,
|
||||
m_player.camera().getDPosition().z};
|
||||
|
||||
int_fast32_t bestX = int_fast32_t(floor(position.x));
|
||||
int_fast32_t bestY = int_fast32_t(floor(position.y));
|
||||
@ -296,9 +296,7 @@ glm::ivec4 BlockCursor::findSelectedBlock() const {
|
||||
}
|
||||
}
|
||||
|
||||
glm::dvec3 lookAt{m_player.pointTargetedX() - m_player.camera().getPosition().x,
|
||||
m_player.pointTargetedY() - m_player.camera().getPosition().y,
|
||||
m_player.pointTargetedZ() - m_player.camera().getPosition().z};
|
||||
glm::dvec3 lookAt{m_player.dirTargetedX(), m_player.dirTargetedY(), m_player.dirTargetedZ()};
|
||||
|
||||
// Ray casting algorithm to find out which block we are looking at
|
||||
const double maxReach = 10.;
|
||||
|
@ -125,7 +125,7 @@ void BlockCursorRaycast::rayCastToAxis(const Axis axis, const glm::dvec3 &positi
|
||||
if(blockID && block.drawType() != BlockDrawType::Liquid) {
|
||||
// Check bounding box; this should loop over all selection boxes
|
||||
// when they are implemented
|
||||
gk::DoubleBox selBox = block.boundingBox() + gk::Vector3d(double(nx), double(ny), double(nz));
|
||||
gk::DoubleBox selBox = block.boundingBox() + gk::Vector3d{double(nx), double(ny), double(nz)};
|
||||
|
||||
bool hit = false;
|
||||
|
||||
|
@ -41,41 +41,41 @@ ClientPlayer::ClientPlayer(gk::Camera &camera) : m_camera(camera) {
|
||||
m_angleH = -90.0;
|
||||
m_angleV = 0.01;
|
||||
|
||||
m_camera.setPosition(m_x, m_y, m_z - 0.1);
|
||||
m_camera.setTargetPosition(pointTargetedX(), pointTargetedY(), pointTargetedZ());
|
||||
m_camera.setDPosition(m_x, m_y, m_z - 0.1);
|
||||
m_camera.setDirection(dirTargetedX(), dirTargetedY(), dirTargetedZ());
|
||||
}
|
||||
|
||||
void ClientPlayer::turnH(float angle) {
|
||||
void ClientPlayer::turnH(double angle) {
|
||||
m_angleH += angle;
|
||||
|
||||
while(m_angleH >= 180.0f) {
|
||||
m_angleH -= 360.0f;
|
||||
while(m_angleH >= 180.0) {
|
||||
m_angleH -= 360.0;
|
||||
}
|
||||
while(m_angleH < -180.0f) {
|
||||
m_angleH += 360.0f;
|
||||
while(m_angleH < -180.0) {
|
||||
m_angleH += 360.0;
|
||||
}
|
||||
|
||||
m_camera.setTargetPosition(pointTargetedX(), pointTargetedY(), pointTargetedZ());
|
||||
m_camera.setDirection(dirTargetedX(), dirTargetedY(), dirTargetedZ());
|
||||
}
|
||||
|
||||
void ClientPlayer::turnV(float angle) {
|
||||
void ClientPlayer::turnV(double angle) {
|
||||
m_angleV += angle;
|
||||
|
||||
if(89.9f < m_angleV) {
|
||||
m_angleV = 89.9f;
|
||||
if(89.9 < m_angleV) {
|
||||
m_angleV = 89.9;
|
||||
}
|
||||
else if(-89.9f > m_angleV) {
|
||||
m_angleV = -89.9f;
|
||||
else if(-89.9 > m_angleV) {
|
||||
m_angleV = -89.9;
|
||||
}
|
||||
|
||||
m_camera.setTargetPosition(pointTargetedX(), pointTargetedY(), pointTargetedZ());
|
||||
m_camera.setDirection(dirTargetedX(), dirTargetedY(), dirTargetedZ());
|
||||
}
|
||||
|
||||
void ClientPlayer::move(float direction) {
|
||||
void ClientPlayer::move(double direction) {
|
||||
direction += m_angleH;
|
||||
|
||||
m_velocity.x = 0.04f * cosf(direction * RADIANS_PER_DEGREES);
|
||||
m_velocity.y = 0.04f * sinf(direction * RADIANS_PER_DEGREES);
|
||||
m_velocity.x = 0.04 * cos(direction * RADIANS_PER_DEGREES);
|
||||
m_velocity.y = 0.04 * sin(direction * RADIANS_PER_DEGREES);
|
||||
}
|
||||
|
||||
void ClientPlayer::processInputs() {
|
||||
@ -92,16 +92,16 @@ void ClientPlayer::processInputs() {
|
||||
m_velocity.z = -0.1;
|
||||
}
|
||||
|
||||
if(gk::GamePad::isKeyPressed(GameKey::Up)) move(0.0f);
|
||||
else if(gk::GamePad::isKeyPressed(GameKey::Down)) move(180.0f);
|
||||
if(gk::GamePad::isKeyPressed(GameKey::Up)) move(0.0);
|
||||
else if(gk::GamePad::isKeyPressed(GameKey::Down)) move(180.0);
|
||||
|
||||
if(gk::GamePad::isKeyPressed(GameKey::Left)) move(90.0f);
|
||||
else if(gk::GamePad::isKeyPressed(GameKey::Right)) move(-90.0f);
|
||||
if(gk::GamePad::isKeyPressed(GameKey::Left)) move(90.0);
|
||||
else if(gk::GamePad::isKeyPressed(GameKey::Right)) move(-90.0);
|
||||
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Left) && gk::GamePad::isKeyPressed(GameKey::Up)) move(45.0f);
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Right) && gk::GamePad::isKeyPressed(GameKey::Up)) move(-45.0f);
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Left) && gk::GamePad::isKeyPressed(GameKey::Down)) move(135.0f);
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Right) && gk::GamePad::isKeyPressed(GameKey::Down)) move(-135.0f);
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Left) && gk::GamePad::isKeyPressed(GameKey::Up)) move(45.0);
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Right) && gk::GamePad::isKeyPressed(GameKey::Up)) move(-45.0);
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Left) && gk::GamePad::isKeyPressed(GameKey::Down)) move(135.0);
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Right) && gk::GamePad::isKeyPressed(GameKey::Down)) move(-135.0);
|
||||
|
||||
if (gk::GamePad::isKeyPressed(GameKey::Sprint)) {
|
||||
m_velocity.x *= 1.5;
|
||||
@ -122,19 +122,19 @@ void ClientPlayer::updatePosition(const ClientWorld &world) {
|
||||
checkCollisions(world);
|
||||
|
||||
if (!Config::isFlyModeEnabled && m_velocity.z != 0) {
|
||||
m_velocity.x *= 0.75f;
|
||||
m_velocity.y *= 0.75f;
|
||||
m_velocity.x *= 0.75;
|
||||
m_velocity.y *= 0.75;
|
||||
}
|
||||
|
||||
m_x += m_velocity.x;
|
||||
m_y += m_velocity.y;
|
||||
m_z += m_velocity.z;
|
||||
|
||||
m_camera.setPosition(m_x, m_y, m_z - 0.1);
|
||||
m_camera.setDPosition(m_x, m_y, m_z - 0.1);
|
||||
Player::setPosition(m_x, m_y, m_z);
|
||||
|
||||
if (m_velocity.x != 0 || m_velocity.y != 0 || m_velocity.z != 0)
|
||||
m_camera.setTargetPosition(pointTargetedX(), pointTargetedY(), pointTargetedZ());
|
||||
m_camera.setDirection(dirTargetedX(), dirTargetedY(), dirTargetedZ());
|
||||
|
||||
m_velocity.x = 0;
|
||||
m_velocity.y = 0;
|
||||
@ -143,20 +143,20 @@ void ClientPlayer::updatePosition(const ClientWorld &world) {
|
||||
m_velocity.z = 0;
|
||||
}
|
||||
|
||||
void ClientPlayer::setPosition(float x, float y, float z) {
|
||||
void ClientPlayer::setPosition(double x, double y, double z) {
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_z = z;
|
||||
|
||||
Player::setPosition(x, y, z);
|
||||
m_camera.setPosition(x, y, z - 0.1);
|
||||
m_camera.setDPosition(x, y, z - 0.1);
|
||||
}
|
||||
|
||||
void ClientPlayer::checkCollisions(const ClientWorld &world) {
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__ANDROID__)
|
||||
const float PLAYER_HEIGHT = 1.8;
|
||||
float eyeheight = m_z + PLAYER_HEIGHT - 1.4;
|
||||
// testPoint(world, glm::vec3(m_x, m_y, m_z), m_velocity);
|
||||
const double PLAYER_HEIGHT = 1.8;
|
||||
double eyeheight = m_z + PLAYER_HEIGHT - 1.4;
|
||||
// testPoint(world, glm::dvec3(m_x, m_y, m_z), m_velocity);
|
||||
testPoint(world, m_x - 0.2, m_y - 0.2, eyeheight - PLAYER_HEIGHT - 0.4, m_velocity);
|
||||
testPoint(world, m_x + 0.2, m_y - 0.2, eyeheight - PLAYER_HEIGHT - 0.4, m_velocity);
|
||||
testPoint(world, m_x - 0.2, m_y + 0.2, eyeheight - PLAYER_HEIGHT - 0.4, m_velocity);
|
||||
@ -166,12 +166,12 @@ void ClientPlayer::checkCollisions(const ClientWorld &world) {
|
||||
testPoint(world, m_x - 0.2, m_y + 0.2, eyeheight - 0.4, m_velocity);
|
||||
testPoint(world, m_x + 0.2, m_y + 0.2, eyeheight - 0.4, m_velocity);
|
||||
#else
|
||||
for (float z = m_z + m_hitbox.z ; z <= m_z + m_hitbox.z + m_hitbox.sizeZ + 0.1f ; z += 0.9f) {
|
||||
for (float y = m_y + m_hitbox.y ; y <= m_y + m_hitbox.y + m_hitbox.sizeY + 0.1f ; y += 0.2f) {
|
||||
for (float x = m_x + m_hitbox.x ; x <= m_x + m_hitbox.x + m_hitbox.sizeX + 0.1f ; x += 0.2f) {
|
||||
if (x == m_x + m_hitbox.x || x == m_x + m_hitbox.x + m_hitbox.sizeX
|
||||
|| y == m_y + m_hitbox.y || y == m_y + m_hitbox.y + m_hitbox.sizeY
|
||||
|| z == m_z + m_hitbox.z || z == m_z + m_hitbox.z + m_hitbox.sizeZ)
|
||||
for (double z = m_z + m_hitbox.z ; z <= m_z + (m_hitbox.z + m_hitbox.sizeZ) + 0.1 ; z += 0.9) {
|
||||
for (double y = m_y + m_hitbox.y ; y <= m_y + (m_hitbox.y + m_hitbox.sizeY) + 0.1 ; y += 0.2) {
|
||||
for (double x = m_x + m_hitbox.x ; x <= m_x + (m_hitbox.x + m_hitbox.sizeX) + 0.1 ; x += 0.2) {
|
||||
if (x == m_x + m_hitbox.x || x == m_x + (m_hitbox.x + m_hitbox.sizeX)
|
||||
|| y == m_y + m_hitbox.y || y == m_y + (m_hitbox.y + m_hitbox.sizeY)
|
||||
|| z == m_z + m_hitbox.z || z == m_z + (m_hitbox.z + m_hitbox.sizeZ))
|
||||
testPoint(world, x, y, z, m_velocity);
|
||||
}
|
||||
}
|
||||
@ -179,23 +179,23 @@ void ClientPlayer::checkCollisions(const ClientWorld &world) {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool passable(const ClientWorld &world, float x, float y, float z) {
|
||||
bool passable(const ClientWorld &world, double x, double y, double z) {
|
||||
u32 blockID = world.getBlock(x, y, z);
|
||||
const Block &block = Registry::getInstance().getBlock(blockID);
|
||||
return !blockID || block.drawType() == BlockDrawType::Liquid || block.drawType() == BlockDrawType::XShape;
|
||||
}
|
||||
|
||||
void ClientPlayer::testPoint(const ClientWorld &world, float x, float y, float z, glm::vec3 &speed) {
|
||||
void ClientPlayer::testPoint(const ClientWorld &world, double x, double y, double z, glm::dvec3 &vel) {
|
||||
// FIXME: Temporary fix, find the real problem!!!
|
||||
if (x < 1) --x;
|
||||
if (y < 1) --y;
|
||||
if (z < 1) --z;
|
||||
|
||||
if(!passable(world, x + speed.x, y, z)) speed.x = 0;
|
||||
if(!passable(world, x, y + speed.y, z)) speed.y = 0;
|
||||
if(!passable(world, x, y, z + speed.z)) {
|
||||
if(speed.z < 0 && m_isJumping) m_isJumping = false;
|
||||
speed.z = 0;
|
||||
if(!passable(world, x + vel.x, y, z)) vel.x = 0;
|
||||
if(!passable(world, x, y + vel.y, z)) vel.y = 0;
|
||||
if(!passable(world, x, y, z + vel.z)) {
|
||||
if(vel.z < 0 && m_isJumping) m_isJumping = false;
|
||||
vel.z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,8 +219,8 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
||||
// vertex coordinates passed to the renderer are all small, and single
|
||||
// precision floats suffice for the drawing.
|
||||
|
||||
gk::Vector3d cameraPos(m_camera->getPosition());
|
||||
m_camera->setPosition(0, 0, 0); // Temporarily move the camera to the origin
|
||||
gk::Vector3d cameraPos(m_camera->getDPosition());
|
||||
m_camera->setDPosition(0, 0, 0); // Temporarily move the camera to the origin
|
||||
|
||||
std::vector<std::pair<ClientChunk*, gk::Transform>> chunks;
|
||||
for(auto &it : m_chunks) {
|
||||
@ -285,6 +285,6 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
||||
}
|
||||
}
|
||||
|
||||
m_camera->setPosition(cameraPos); // Restore the camera to its original position
|
||||
m_camera->setDPosition(cameraPos); // Restore the camera to its original position
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user