Improve gravity

This commit is contained in:
MrLetsplay 2022-11-14 09:20:42 +01:00
parent 270b8866a6
commit 69fd7af211
5 changed files with 52 additions and 20 deletions

View File

@ -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))); 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) { if(Input::getKeyState(keyUp) == GLFW_PRESS) {
direction += glm::vec3(0,1,0); direction += glm::vec3(0,1,0);
//jump = kekData.player->onGround; jump = kekData.player->onGround;
} }
if(Input::getKeyState(keyDown) == GLFW_PRESS) { if(Input::getKeyState(keyDown) == GLFW_PRESS) {
@ -63,9 +63,12 @@ static void defaultInput(GLFWwindow *window, void *data) {
newVel.y = vel.y(); newVel.y = vel.y();
if(jump) newVel.y = KEK_PLAYER_JUMP_VELOCITY; if(jump) newVel.y = KEK_PLAYER_JUMP_VELOCITY;
kekData.player->physics->body->setLinearVelocity(Physics::fromGLM(newVel));*/ 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(); kekData.player->controller->update();
} }

View File

@ -8,7 +8,7 @@
namespace kek { 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; btTransform from;
from.setIdentity(); from.setIdentity();
from.setOrigin(Physics::fromGLM(pos)); 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); kekData.physics->world->convexSweepTest((btConvexShape *) kekData.player->physics->body->getCollisionShape(), from, to, cb);
if(!cb.m_hitCollisionObject) return false; if(!cb.m_hitCollisionObject) return false;
*outBody = cb.m_hitCollisionObject; if(outBody) *outBody = cb.m_hitCollisionObject;
*outFrac = cb.m_closestHitFraction; if(outFrac) *outFrac = cb.m_closestHitFraction;
*outPoint = Physics::toGLM(cb.m_hitPointWorld); if(outPoint) *outPoint = Physics::toGLM(cb.m_hitPointWorld);
*outNormal = Physics::toGLM(cb.m_hitNormalWorld); if(outNormal) *outNormal = Physics::toGLM(cb.m_hitNormalWorld);
return true; 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() { DefaultPlayerController::DefaultPlayerController() {
} }
@ -40,39 +48,50 @@ DefaultPlayerController::~DefaultPlayerController() {
glm::vec3 DefaultPlayerController::move(glm::vec3 movement) { glm::vec3 DefaultPlayerController::move(glm::vec3 movement) {
glm::vec3 pos = kekData.player->getPosition(); glm::vec3 pos = kekData.player->getPosition();
glm::vec3 totalMovement = glm::vec3(0);
int count = 0; int count = 0;
while (count < 3) { while (count < 3) {
const btCollisionObject *object;
float frac; float frac;
glm::vec3 point;
glm::vec3 normal; glm::vec3 normal;
bool collision = castPlayer(pos, movement, &object, &frac, &point, &normal); bool collision = castPlayer(pos + totalMovement, movement, nullptr, &frac, nullptr, &normal);
if(!collision) { if(!collision) {
pos += movement; totalMovement += movement;
break; break;
} }
normal = glm::normalize(normal); 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; totalMovement += movement * frac;
pos += normal * 0.001f; 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);
movement = remainingProjected; movement = remainingProjected;
count++; count++;
} }
kekData.player->moveTo(pos); kekData.player->translate(totalMovement);
return pos; return totalMovement;
}
void DefaultPlayerController::jump() {
velocity += glm::vec3(0, 10 * jumpHeight, 0);
} }
void DefaultPlayerController::update() { 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);
} }
} }

View File

@ -7,10 +7,18 @@ namespace kek {
class DefaultPlayerController: public PlayerController { class DefaultPlayerController: public PlayerController {
public: 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(); DefaultPlayerController();
virtual ~DefaultPlayerController(); virtual ~DefaultPlayerController();
virtual glm::vec3 move(glm::vec3 movement); virtual glm::vec3 move(glm::vec3 movement);
virtual void jump();
virtual void update(); virtual void update();
}; };

View File

@ -10,6 +10,7 @@ public:
virtual ~PlayerController() = 0; virtual ~PlayerController() = 0;
virtual glm::vec3 move(glm::vec3 movement) = 0; virtual glm::vec3 move(glm::vec3 movement) = 0;
virtual void jump() = 0;
virtual void update() = 0; virtual void update() = 0;
}; };

View File

@ -68,7 +68,8 @@ int main(int argc, char **argv) {
wall->addMesh(genCubeMesh(1, 10, 50, tex, tex, tex)); wall->addMesh(genCubeMesh(1, 10, 50, tex, tex, tex));
btCollisionShape *shape = new btBoxShape(btVector3(0.5,5,25)); btCollisionShape *shape = new btBoxShape(btVector3(0.5,5,25));
wall->addPhysics(shape, 0, btCollisionObject::CF_STATIC_OBJECT); 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); scene->addObject(wall);
} }