From 69fd7af21114bfd30cc1476370c19920f7821dc0 Mon Sep 17 00:00:00 2001 From: MrLetsplay2003 Date: Mon, 14 Nov 2022 09:20:42 +0100 Subject: [PATCH] Improve gravity --- src/kekengine/cpp/common/defaults.cpp | 9 ++-- .../cpp/player/defaultplayercontroller.cpp | 51 +++++++++++++------ .../include/defaultplayercontroller.h | 8 +++ src/kekengine/include/playercontroller.h | 1 + src/kekgame/cpp/kekgame.cpp | 3 +- 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/kekengine/cpp/common/defaults.cpp b/src/kekengine/cpp/common/defaults.cpp index 58b2ff6..60c1c20 100644 --- a/src/kekengine/cpp/common/defaults.cpp +++ b/src/kekengine/cpp/common/defaults.cpp @@ -42,10 +42,10 @@ static void defaultInput(GLFWwindow *window, void *data) { direction += glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f))); } - //bool jump = false; + bool jump = false; if(Input::getKeyState(keyUp) == GLFW_PRESS) { direction += glm::vec3(0,1,0); - //jump = kekData.player->onGround; + jump = kekData.player->onGround; } if(Input::getKeyState(keyDown) == GLFW_PRESS) { @@ -63,9 +63,12 @@ static void defaultInput(GLFWwindow *window, void *data) { newVel.y = vel.y(); if(jump) newVel.y = KEK_PLAYER_JUMP_VELOCITY; kekData.player->physics->body->setLinearVelocity(Physics::fromGLM(newVel));*/ - kekData.player->controller->move(direction * (kekData.lastFrameTime * 10)); + glm::vec3 xz = glm::vec3(direction.x, 0, direction.z); + kekData.player->controller->move(xz * (kekData.lastFrameTime * 10)); + if(jump) kekData.player->controller->jump(); } } + kekData.player->controller->update(); } diff --git a/src/kekengine/cpp/player/defaultplayercontroller.cpp b/src/kekengine/cpp/player/defaultplayercontroller.cpp index 301169f..ccb2ef1 100644 --- a/src/kekengine/cpp/player/defaultplayercontroller.cpp +++ b/src/kekengine/cpp/player/defaultplayercontroller.cpp @@ -8,7 +8,7 @@ namespace kek { -static bool castPlayer(glm::vec3 pos, glm::vec3 delta, const btCollisionObject **outBody, float *outFrac, glm::vec3 *outPoint, glm::vec3 *outNormal){ +static bool castPlayer(glm::vec3 pos, glm::vec3 delta, const btCollisionObject **outBody, float *outFrac, glm::vec3 *outPoint, glm::vec3 *outNormal) { btTransform from; from.setIdentity(); from.setOrigin(Physics::fromGLM(pos)); @@ -23,13 +23,21 @@ static bool castPlayer(glm::vec3 pos, glm::vec3 delta, const btCollisionObject * kekData.physics->world->convexSweepTest((btConvexShape *) kekData.player->physics->body->getCollisionShape(), from, to, cb); if(!cb.m_hitCollisionObject) return false; - *outBody = cb.m_hitCollisionObject; - *outFrac = cb.m_closestHitFraction; - *outPoint = Physics::toGLM(cb.m_hitPointWorld); - *outNormal = Physics::toGLM(cb.m_hitNormalWorld); + if(outBody) *outBody = cb.m_hitCollisionObject; + if(outFrac) *outFrac = cb.m_closestHitFraction; + if(outPoint) *outPoint = Physics::toGLM(cb.m_hitPointWorld); + if(outNormal) *outNormal = Physics::toGLM(cb.m_hitNormalWorld); return true; } +static bool checkPlayerGrounded() { + glm::vec3 point; + glm::vec3 normal; + bool onGround = castPlayer(kekData.player->getPosition(), glm::vec3(0,-1,0), nullptr, nullptr, &point, &normal); + // TODO: angle check + return onGround; +} + DefaultPlayerController::DefaultPlayerController() { } @@ -40,39 +48,50 @@ DefaultPlayerController::~DefaultPlayerController() { glm::vec3 DefaultPlayerController::move(glm::vec3 movement) { glm::vec3 pos = kekData.player->getPosition(); + glm::vec3 totalMovement = glm::vec3(0); int count = 0; while (count < 3) { - const btCollisionObject *object; float frac; - glm::vec3 point; glm::vec3 normal; - bool collision = castPlayer(pos, movement, &object, &frac, &point, &normal); + bool collision = castPlayer(pos + totalMovement, movement, nullptr, &frac, nullptr, &normal); if(!collision) { - pos += movement; + totalMovement += movement; break; } normal = glm::normalize(normal); - float angle = glm::angle(normal, glm::normalize(movement)) / M_PI; + float angle = 90.0f - glm::angle(normal, glm::normalize(movement)) / M_PI * 90.0f; - if(angle > 0.9) break; + if(angle < minSlideAngle) break; - pos += movement * frac; - pos += normal * 0.001f; + totalMovement += movement * frac; + totalMovement += normal * 0.001f; glm::vec3 remainingProjected = glm::normalize(glm::cross(normal, glm::cross(movement, normal))) * glm::length(movement) * (1 - frac); movement = remainingProjected; count++; } - kekData.player->moveTo(pos); - return pos; + kekData.player->translate(totalMovement); + return totalMovement; +} + +void DefaultPlayerController::jump() { + velocity += glm::vec3(0, 10 * jumpHeight, 0); } void DefaultPlayerController::update() { - move(glm::vec3(0, -10, 0) * kekData.lastFrameTime); + bool onGround = checkPlayerGrounded(); + kekData.player->onGround = onGround; + if(!onGround) { + velocity += gravity * kekData.lastFrameTime; + }else{ + velocity = glm::vec3(0); + } + + move(velocity); } } diff --git a/src/kekengine/include/defaultplayercontroller.h b/src/kekengine/include/defaultplayercontroller.h index 24b1a86..77c1ca1 100644 --- a/src/kekengine/include/defaultplayercontroller.h +++ b/src/kekengine/include/defaultplayercontroller.h @@ -7,10 +7,18 @@ namespace kek { class DefaultPlayerController: public PlayerController { public: + glm::vec3 gravity = glm::vec3(0,-9.81,0); + float minSlideAngle = 5; + float maxWalkAngle = 60; + float jumpHeight = 1; + + glm::vec3 velocity = glm::vec3(0); + DefaultPlayerController(); virtual ~DefaultPlayerController(); virtual glm::vec3 move(glm::vec3 movement); + virtual void jump(); virtual void update(); }; diff --git a/src/kekengine/include/playercontroller.h b/src/kekengine/include/playercontroller.h index b6a819a..1dd1ff2 100644 --- a/src/kekengine/include/playercontroller.h +++ b/src/kekengine/include/playercontroller.h @@ -10,6 +10,7 @@ public: virtual ~PlayerController() = 0; virtual glm::vec3 move(glm::vec3 movement) = 0; + virtual void jump() = 0; virtual void update() = 0; }; diff --git a/src/kekgame/cpp/kekgame.cpp b/src/kekgame/cpp/kekgame.cpp index 3c17f20..f60016f 100644 --- a/src/kekgame/cpp/kekgame.cpp +++ b/src/kekgame/cpp/kekgame.cpp @@ -68,7 +68,8 @@ int main(int argc, char **argv) { wall->addMesh(genCubeMesh(1, 10, 50, tex, tex, tex)); btCollisionShape *shape = new btBoxShape(btVector3(0.5,5,25)); wall->addPhysics(shape, 0, btCollisionObject::CF_STATIC_OBJECT); - wall->moveTo(glm::vec3(0,5,0)); + wall->moveTo(glm::vec3(0,2.5,0)); + wall->rotate(45.0f, glm::vec3(0,0,1)); scene->addObject(wall); }