From e618d735e1ad74131d76bf96b408e78b0f730dfc Mon Sep 17 00:00:00 2001 From: MrLetsplay2003 Date: Thu, 17 Nov 2022 18:27:34 +0100 Subject: [PATCH] Improve walking on slopes --- .../cpp/player/defaultplayercontroller.cpp | 17 +++++++++++++---- src/kekengine/include/defaultplayercontroller.h | 3 --- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/kekengine/cpp/player/defaultplayercontroller.cpp b/src/kekengine/cpp/player/defaultplayercontroller.cpp index 1b48c13..1401f9c 100644 --- a/src/kekengine/cpp/player/defaultplayercontroller.cpp +++ b/src/kekengine/cpp/player/defaultplayercontroller.cpp @@ -30,14 +30,16 @@ static bool castPlayer(glm::vec3 pos, glm::vec3 delta, const btCollisionObject * return true; } -bool DefaultPlayerController::checkPlayerGrounded() { +static bool checkPlayerGrounded(float groundDistance, float maxWalkAngle, const btCollisionObject **outGround, glm::vec3 *outNormal) { glm::vec3 groundDir = glm::vec3(0,-groundDistance,0); glm::vec3 point; glm::vec3 normal; - bool onGround = castPlayer(kekData.player->getPosition(), groundDir, nullptr, nullptr, &point, &normal); + bool onGround = castPlayer(kekData.player->getPosition(), groundDir, outGround, nullptr, &point, &normal); if(!onGround) return false; + if(outNormal) *outNormal = normal; + normal = glm::normalize(normal); float angle = 180.0f - glm::angle(normal, glm::normalize(groundDir)) / M_PI * 180.0f; @@ -77,7 +79,7 @@ glm::vec3 DefaultPlayerController::move(glm::vec3 movement) { totalMovement += normal * 0.001f; - glm::vec3 remainingProjected = glm::normalize(glm::cross(normal, glm::cross(movement, normal))) * glm::length(movement) * (1 - frac); + glm::vec3 remainingProjected = glm::normalize(glm::cross(normal, glm::cross(movement, normal))) * glm::length(movement) * (1 - frac) * (angle / 90.0f); movement = remainingProjected; count++; } @@ -87,7 +89,9 @@ glm::vec3 DefaultPlayerController::move(glm::vec3 movement) { } void DefaultPlayerController::update() { - bool onGround = checkPlayerGrounded(); + const btCollisionObject *ground; + glm::vec3 groundNormal; + bool onGround = checkPlayerGrounded(groundDistance, maxWalkAngle, &ground, &groundNormal); kekData.player->onGround = onGround; if(!onGround) { @@ -120,6 +124,11 @@ void DefaultPlayerController::update() { direction = glm::vec3(direction.x, 0, direction.z); + if(onGround) { + // Project movement onto ground + direction = glm::normalize(glm::cross(groundNormal, glm::cross(direction, groundNormal))); + } + glm::vec3 move = velocity; if(glm::length2(direction) > 0) { direction = glm::normalize(direction) * walkSpeed; diff --git a/src/kekengine/include/defaultplayercontroller.h b/src/kekengine/include/defaultplayercontroller.h index e31bc2e..2898946 100644 --- a/src/kekengine/include/defaultplayercontroller.h +++ b/src/kekengine/include/defaultplayercontroller.h @@ -7,9 +7,6 @@ namespace kek { class DefaultPlayerController: public PlayerController { -protected: - bool checkPlayerGrounded(); - public: glm::vec3 gravity = glm::vec3(0,-9.81,0); float minSlideAngle = 5;