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)));
}
//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();
}

View File

@ -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);
}
}

View File

@ -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();
};

View File

@ -10,6 +10,7 @@ public:
virtual ~PlayerController() = 0;
virtual glm::vec3 move(glm::vec3 movement) = 0;
virtual void jump() = 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));
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);
}