Basic player controller (WIP)
This commit is contained in:
parent
1d61087e62
commit
270b8866a6
@ -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) {
|
||||||
@ -58,13 +58,15 @@ static void defaultInput(GLFWwindow *window, void *data) {
|
|||||||
kekData.activeCamera->translate(direction * KEK_NOCLIP_SPEED * kekData.lastFrameTime);
|
kekData.activeCamera->translate(direction * KEK_NOCLIP_SPEED * kekData.lastFrameTime);
|
||||||
}else {
|
}else {
|
||||||
//kekData.player->physics->body->applyCentralImpulse(Physics::fromGLM(glm::normalize(direction) * (kekData.lastFrameTime * 20)));
|
//kekData.player->physics->body->applyCentralImpulse(Physics::fromGLM(glm::normalize(direction) * (kekData.lastFrameTime * 20)));
|
||||||
btVector3 vel = kekData.player->physics->body->getLinearVelocity();
|
/*btVector3 vel = kekData.player->physics->body->getLinearVelocity();
|
||||||
glm::vec3 newVel = glm::normalize(direction) * 6.0f;
|
glm::vec3 newVel = glm::normalize(direction) * KEK_PLAYER_WALK_VELOCITY;
|
||||||
newVel.y = vel.y();
|
newVel.y = vel.y();
|
||||||
if(jump) newVel.y = 2.7f;
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
kekData.player->controller->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void defaultKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods, void *data) {
|
static void defaultKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods, void *data) {
|
||||||
@ -176,21 +178,33 @@ void init() {
|
|||||||
float radii[2] = {KEK_PLAYER_RADIUS, KEK_PLAYER_RADIUS};
|
float radii[2] = {KEK_PLAYER_RADIUS, KEK_PLAYER_RADIUS};
|
||||||
btCollisionShape *shape = new btMultiSphereShape(positions, radii, 2);
|
btCollisionShape *shape = new btMultiSphereShape(positions, radii, 2);
|
||||||
btRigidBody *body = new btRigidBody(KEK_PLAYER_MASS, nullptr, shape);
|
btRigidBody *body = new btRigidBody(KEK_PLAYER_MASS, nullptr, shape);
|
||||||
|
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||||
body->setFriction(3);
|
body->setFriction(3);
|
||||||
body->setActivationState(DISABLE_DEACTIVATION);
|
body->setActivationState(DISABLE_DEACTIVATION);
|
||||||
kekData.physics->world->addRigidBody(body);
|
kekData.physics->world->addRigidBody(body);
|
||||||
|
|
||||||
btCollisionShape *jumpShape = new btSphereShape(KEK_PLAYER_RADIUS / 2);
|
/*btCollisionShape *jumpShape = new btSphereShape(KEK_PLAYER_RADIUS / 2);
|
||||||
btGhostObject *jumpCollider = new btGhostObject();
|
btGhostObject *jumpCollider = new btGhostObject();
|
||||||
jumpCollider->setCollisionShape(jumpShape);
|
jumpCollider->setCollisionShape(jumpShape);
|
||||||
jumpCollider->setCollisionFlags(jumpCollider->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
jumpCollider->setCollisionFlags(jumpCollider->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||||
jumpCollider->setActivationState(DISABLE_DEACTIVATION);
|
jumpCollider->setActivationState(DISABLE_DEACTIVATION);
|
||||||
kekData.physics->world->addCollisionObject(jumpCollider);
|
kekData.physics->world->addCollisionObject(jumpCollider);*/
|
||||||
|
|
||||||
|
btTransform from;
|
||||||
|
from.setIdentity();
|
||||||
|
from.setOrigin(btVector3(0,0,0));
|
||||||
|
|
||||||
|
btTransform to;
|
||||||
|
to.setIdentity();
|
||||||
|
to.setOrigin(btVector3(1,1,1));
|
||||||
|
|
||||||
|
btCollisionWorld::ClosestConvexResultCallback cb = btCollisionWorld::ClosestConvexResultCallback(from.getOrigin(), to.getOrigin());
|
||||||
|
kekData.physics->world->convexSweepTest((btConvexShape *) shape, from, to, cb);
|
||||||
|
|
||||||
kekData.player->physics = new PlayerPhysicsObjectData();
|
kekData.player->physics = new PlayerPhysicsObjectData();
|
||||||
kekData.player->physics->body = body;
|
kekData.player->physics->body = body;
|
||||||
kekData.player->physics->jumpCollider = jumpCollider;
|
//kekData.player->physics->jumpCollider = jumpCollider;
|
||||||
kekData.player->moveTo(glm::vec3(0,10,0));
|
kekData.player->moveTo(glm::vec3(5,10,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
|
@ -122,7 +122,7 @@ int init() {
|
|||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
glClearColor(0.1f, 0.3f, 0.1f, 0.0f);
|
glClearColor(0.1f, 0.3f, 0.1f, 0.0f);
|
||||||
glfwSwapInterval(0);
|
//glfwSwapInterval(0);
|
||||||
|
|
||||||
stbi_set_flip_vertically_on_load(true);
|
stbi_set_flip_vertically_on_load(true);
|
||||||
|
|
||||||
|
@ -38,11 +38,11 @@ void step(float deltaT) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kekData.player->physics->jumpCollider->getWorldTransform().setOrigin(Physics::fromGLM(kekData.player->getFootPosition() + glm::vec3(0, KEK_PLAYER_RADIUS / 2, 0)));
|
//kekData.player->physics->jumpCollider->getWorldTransform().setOrigin(Physics::fromGLM(kekData.player->getFootPosition() + glm::vec3(0, KEK_PLAYER_RADIUS / 2, 0)));
|
||||||
|
|
||||||
kekData.physics->world->stepSimulation(deltaT, 100);
|
kekData.physics->world->stepSimulation(deltaT, 100);
|
||||||
|
|
||||||
kekData.player->onGround = kekData.player->physics->jumpCollider->getNumOverlappingObjects() > 1; // TODO: improve
|
//kekData.player->onGround = kekData.player->physics->jumpCollider->getNumOverlappingObjects() > 1; // TODO: improve
|
||||||
|
|
||||||
if(!kekData.player->noclip) {
|
if(!kekData.player->noclip) {
|
||||||
kekData.activeCamera->moveTo(kekData.player->getEyePosition());
|
kekData.activeCamera->moveTo(kekData.player->getEyePosition());
|
||||||
|
78
src/kekengine/cpp/player/defaultplayercontroller.cpp
Normal file
78
src/kekengine/cpp/player/defaultplayercontroller.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include "defaultplayercontroller.h"
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include "internal/physics.h"
|
||||||
|
|
||||||
|
#include <glm/gtx/vector_angle.hpp>
|
||||||
|
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
||||||
|
|
||||||
|
namespace kek {
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
btTransform to;
|
||||||
|
to.setIdentity();
|
||||||
|
to.setOrigin(Physics::fromGLM(pos + delta));
|
||||||
|
|
||||||
|
ClosestNotSelfConvexResultCallback cb = ClosestNotSelfConvexResultCallback(from.getOrigin(), to.getOrigin(), kekData.player->physics->body);
|
||||||
|
cb.m_collisionFilterGroup = -1;
|
||||||
|
cb.m_collisionFilterMask = -1;
|
||||||
|
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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultPlayerController::DefaultPlayerController() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultPlayerController::~DefaultPlayerController() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 DefaultPlayerController::move(glm::vec3 movement) {
|
||||||
|
glm::vec3 pos = kekData.player->getPosition();
|
||||||
|
|
||||||
|
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);
|
||||||
|
if(!collision) {
|
||||||
|
pos += movement;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
normal = glm::normalize(normal);
|
||||||
|
|
||||||
|
float angle = glm::angle(normal, glm::normalize(movement)) / M_PI;
|
||||||
|
|
||||||
|
if(angle > 0.9) break;
|
||||||
|
|
||||||
|
pos += movement * frac;
|
||||||
|
pos += 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultPlayerController::update() {
|
||||||
|
move(glm::vec3(0, -10, 0) * kekData.lastFrameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
|
#include "defaultplayercontroller.h"
|
||||||
#include "internal/physics.h"
|
#include "internal/physics.h"
|
||||||
|
|
||||||
namespace kek {
|
namespace kek {
|
||||||
@ -7,6 +8,7 @@ namespace kek {
|
|||||||
Player::Player(): RotateableObject() {
|
Player::Player(): RotateableObject() {
|
||||||
this->noclip = false;
|
this->noclip = false;
|
||||||
this->onGround = false;
|
this->onGround = false;
|
||||||
|
this->controller = new DefaultPlayerController();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::rotateTo(glm::quat rotation) {
|
void Player::rotateTo(glm::quat rotation) {
|
9
src/kekengine/cpp/player/playercontroller.cpp
Normal file
9
src/kekengine/cpp/player/playercontroller.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "playercontroller.h"
|
||||||
|
|
||||||
|
namespace kek {
|
||||||
|
|
||||||
|
PlayerController::~PlayerController() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -47,3 +47,5 @@
|
|||||||
#define KEK_PLAYER_RADIUS 0.5f
|
#define KEK_PLAYER_RADIUS 0.5f
|
||||||
#define KEK_PLAYER_EYE_OFFSET (KEK_PLAYER_HEIGHT / 2 - KEK_PLAYER_RADIUS)
|
#define KEK_PLAYER_EYE_OFFSET (KEK_PLAYER_HEIGHT / 2 - KEK_PLAYER_RADIUS)
|
||||||
#define KEK_PLAYER_MASS 50
|
#define KEK_PLAYER_MASS 50
|
||||||
|
#define KEK_PLAYER_WALK_VELOCITY 6.0f
|
||||||
|
#define KEK_PLAYER_JUMP_VELOCITY 2.4f
|
||||||
|
18
src/kekengine/include/defaultplayercontroller.h
Normal file
18
src/kekengine/include/defaultplayercontroller.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "playercontroller.h"
|
||||||
|
|
||||||
|
namespace kek {
|
||||||
|
|
||||||
|
class DefaultPlayerController: public PlayerController {
|
||||||
|
|
||||||
|
public:
|
||||||
|
DefaultPlayerController();
|
||||||
|
virtual ~DefaultPlayerController();
|
||||||
|
|
||||||
|
virtual glm::vec3 move(glm::vec3 movement);
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -17,6 +17,36 @@ struct PlayerPhysicsObjectData: public PhysicsObjectData {
|
|||||||
btGhostObject *jumpCollider;
|
btGhostObject *jumpCollider;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ClosestNotSelfConvexResultCallback : public btCollisionWorld::ConvexResultCallback {
|
||||||
|
ClosestNotSelfConvexResultCallback(const btVector3& convexFromWorld, const btVector3& convexToWorld, btCollisionObject *self) :
|
||||||
|
m_self(self),
|
||||||
|
m_convexFromWorld(convexFromWorld),
|
||||||
|
m_convexToWorld(convexToWorld),
|
||||||
|
m_hitCollisionObject(0){}
|
||||||
|
|
||||||
|
btCollisionObject *m_self;
|
||||||
|
btVector3 m_convexFromWorld; //used to calculate hitPointWorld from hitFraction
|
||||||
|
btVector3 m_convexToWorld;
|
||||||
|
|
||||||
|
btVector3 m_hitNormalWorld;
|
||||||
|
btVector3 m_hitPointWorld;
|
||||||
|
const btCollisionObject* m_hitCollisionObject;
|
||||||
|
|
||||||
|
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) {
|
||||||
|
if(convexResult.m_hitCollisionObject == m_self) return 1.0f;
|
||||||
|
m_closestHitFraction = convexResult.m_hitFraction;
|
||||||
|
m_hitCollisionObject = convexResult.m_hitCollisionObject;
|
||||||
|
if (normalInWorldSpace) {
|
||||||
|
m_hitNormalWorld = convexResult.m_hitNormalLocal;
|
||||||
|
}else{
|
||||||
|
///need to transform normal into worldspace
|
||||||
|
m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis() * convexResult.m_hitNormalLocal;
|
||||||
|
}
|
||||||
|
m_hitPointWorld = convexResult.m_hitPointLocal;
|
||||||
|
return convexResult.m_hitFraction;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace Physics {
|
namespace Physics {
|
||||||
|
|
||||||
glm::vec3 toGLM(btVector3 vec);
|
glm::vec3 toGLM(btVector3 vec);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
#include "defaultplayercontroller.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "errordialog.h"
|
#include "errordialog.h"
|
||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
@ -13,6 +14,8 @@
|
|||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "objparser.h"
|
#include "objparser.h"
|
||||||
#include "physics.h"
|
#include "physics.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "playercontroller.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gameobject.h"
|
#include "gameobject.h"
|
||||||
|
#include "playercontroller.h"
|
||||||
|
|
||||||
namespace kek {
|
namespace kek {
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ class Player: public RotateableObject {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
PlayerPhysicsObjectData *physics;
|
PlayerPhysicsObjectData *physics;
|
||||||
|
PlayerController *controller;
|
||||||
bool noclip;
|
bool noclip;
|
||||||
bool onGround;
|
bool onGround;
|
||||||
|
|
||||||
|
17
src/kekengine/include/playercontroller.h
Normal file
17
src/kekengine/include/playercontroller.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
namespace kek {
|
||||||
|
|
||||||
|
class PlayerController {
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~PlayerController() = 0;
|
||||||
|
|
||||||
|
virtual glm::vec3 move(glm::vec3 movement) = 0;
|
||||||
|
virtual void update() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -62,32 +62,42 @@ int main(int argc, char **argv) {
|
|||||||
scene->addObject(floor);
|
scene->addObject(floor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh *mesh = ObjParser::loadMesh("object/sphere/Sphere.obj");
|
GameObject *wall = new GameObject();
|
||||||
|
{
|
||||||
|
std::shared_ptr<Texture> tex = Texture::load("image/white.png");
|
||||||
|
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));
|
||||||
|
scene->addObject(wall);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Mesh *mesh = ObjParser::loadMesh("object/sphere/Sphere.obj");
|
||||||
GameObject *test = new GameObject();
|
GameObject *test = new GameObject();
|
||||||
btCollisionShape *shape = new btSphereShape(1);
|
btCollisionShape *shape = new btSphereShape(1);
|
||||||
test->addPhysics(shape, 10);
|
test->addPhysics(shape, 10);
|
||||||
test->addMesh(mesh);
|
test->addMesh(mesh);
|
||||||
test->moveTo(glm::vec3(0,5,0));
|
test->moveTo(glm::vec3(0,5,0));
|
||||||
scene->addObject(test);
|
scene->addObject(test);*/
|
||||||
|
|
||||||
Mesh *mesh2 = ObjParser::loadMesh("object/cube_colored/Cube.obj");
|
/*Mesh *mesh2 = ObjParser::loadMesh("object/cube_colored/Cube.obj");
|
||||||
GameObject *test3 = new GameObject();
|
GameObject *test3 = new GameObject();
|
||||||
btCollisionShape *shape2 = new btBoxShape(btVector3(1,1,1));
|
btCollisionShape *shape2 = new btBoxShape(btVector3(1,1,1));
|
||||||
test3->addPhysics(shape2, 0, btCollisionObject::CF_STATIC_OBJECT);
|
test3->addPhysics(shape2, 0, btCollisionObject::CF_STATIC_OBJECT);
|
||||||
test3->addMesh(mesh2);
|
test3->addMesh(mesh2);
|
||||||
test3->moveTo(glm::vec3(2, 1, 2));
|
test3->moveTo(glm::vec3(2, 1, 2));
|
||||||
scene->addObject(test3);
|
scene->addObject(test3);*/
|
||||||
|
|
||||||
for(int i = 0; i < 10; i++) {
|
/*for(int i = 0; i < 10; i++) {
|
||||||
GameObject *test2 = new GameObject();
|
GameObject *test2 = new GameObject();
|
||||||
btCollisionShape *shape = new btBoxShape(btVector3(1,1,1));
|
btCollisionShape *shape = new btBoxShape(btVector3(1,1,1));
|
||||||
test2->addPhysics(shape, 10);
|
test2->addPhysics(shape, 10);
|
||||||
test2->addMesh(ObjParser::loadMesh("object/cube_colored/Cube.obj"));
|
test2->addMesh(ObjParser::loadMesh("object/cube_colored/Cube.obj"));
|
||||||
test2->moveTo(glm::vec3(1.0f, 5.0f, 3 * i));
|
test2->moveTo(glm::vec3(1.0f, 5.0f, 3 * i));
|
||||||
scene->addObject(test2);
|
scene->addObject(test2);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
PointLight *light = new PointLight(glm::vec3(1), 1, 0, 1);
|
PointLight *light = new PointLight(glm::vec3(1), 1, 0, 0.1);
|
||||||
light->moveTo(glm::vec3(0,1,0));
|
light->moveTo(glm::vec3(0,1,0));
|
||||||
scene->lights->add(light);
|
scene->lights->add(light);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user