Raycasting character controller
This commit is contained in:
parent
da59158fd1
commit
9478bca2ad
99
src/game.c
99
src/game.c
@ -97,6 +97,15 @@ static void tick_pairs() {
|
||||
}
|
||||
}
|
||||
|
||||
static void vec3_project_to_plane(vec3 v, vec3 n, vec3 ret) {
|
||||
float scale = glm_vec3_dot(v, n) / glm_vec3_dot(n, n);
|
||||
|
||||
vec3 n2;
|
||||
glm_vec3_scale(n, scale, n2);
|
||||
|
||||
glm_vec3_sub(v, n2, ret);
|
||||
}
|
||||
|
||||
static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
||||
uint16_t e1 = (uintptr_t) dGeomGetData(g1);
|
||||
uint16_t e2 = (uintptr_t) dGeomGetData(g2);
|
||||
@ -197,19 +206,17 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
||||
vec3 n = {0, 1, 0};
|
||||
glm_quat_rotatev(q, n, n);
|
||||
|
||||
if(!ghost) for(int i = 0; i < numc; i++) {
|
||||
/*if(!ghost) for(int i = 0; i < numc; i++) {
|
||||
if(glm_vec3_dot(contact[i].geom.normal, n) >= 0.7) {
|
||||
struct CMovement *m = game_getcomponent(e1, movement);
|
||||
if(m) {
|
||||
if(m->holding != ENT_ID_INVALID && m->holding == e2) {
|
||||
ghost = 1;
|
||||
}
|
||||
|
||||
m->canJump = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if(c->trigger != TRIGGER_INVALID) {
|
||||
Game.triggers[c->trigger - 1](c->trigger, e1, e2, triggerType);
|
||||
@ -238,19 +245,16 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
||||
vec3 n = {0, -1, 0};
|
||||
glm_quat_rotatev(q, n, n);
|
||||
|
||||
if(!ghost) for(int i = 0; i < numc; i++) {
|
||||
/*if(!ghost) for(int i = 0; i < numc; i++) {
|
||||
if(glm_vec3_dot(contact[i].geom.normal, n) >= 0.7) {
|
||||
struct CMovement *m = game_getcomponent(e2, movement);
|
||||
if(m) {
|
||||
if(m->holding != ENT_ID_INVALID && m->holding == e1) {
|
||||
ghost = 1;
|
||||
}
|
||||
|
||||
m->canJump = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if(c->trigger != TRIGGER_INVALID) {
|
||||
Game.triggers[c->trigger - 1](c->trigger, e2, e1, triggerType);
|
||||
@ -349,7 +353,82 @@ void game_raycast(struct LocalRay *rays, size_t count) {
|
||||
}
|
||||
}
|
||||
|
||||
static void game_character_controller_raycast_handler(void *data, dGeomID g1, dGeomID g2) {
|
||||
if(dGeomGetClass(g1) != dRayClass && dGeomGetClass(g2) != dRayClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
dContact contact[1];
|
||||
memset(contact, 0, sizeof(contact));
|
||||
|
||||
int numc = dCollide(g1, g2, 1, &contact[0].geom, sizeof(dContact));
|
||||
|
||||
uint16_t e1 = (uintptr_t) dGeomGetData(g1);
|
||||
uint16_t e2 = (uintptr_t) dGeomGetData(g2);
|
||||
|
||||
if(numc) {
|
||||
|
||||
vec3 n = {0, -1, 0};
|
||||
|
||||
if(dGeomGetClass(g1) == dRayClass) {
|
||||
struct CMovement *cm = &Game.entities.movement[(uintptr_t) dGeomGetData(g1)];
|
||||
|
||||
if(glm_vec3_dot(contact[0].geom.normal, n) <= -0.7) {
|
||||
cm->canJump = 1;
|
||||
glm_vec3_scale(contact[0].geom.normal, 1, cm->groundNormal);
|
||||
}
|
||||
|
||||
return;
|
||||
} else if(dGeomGetClass(g2) == dRayClass) {
|
||||
struct CMovement *cm = &Game.entities.movement[(uintptr_t) dGeomGetData(g2)];
|
||||
|
||||
if(glm_vec3_dot(contact[0].geom.normal, n) <= -0.7) {
|
||||
cm->canJump = 1;
|
||||
glm_vec3_scale(contact[0].geom.normal, -1, cm->groundNormal);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
void game_character_controller_raycast() {
|
||||
dGeomID rayGeoms[Game.entities.movementCount];
|
||||
|
||||
for(int i = 0; i < Game.entities.movementCount; i++) {
|
||||
struct CPhysics *cp = game_getcomponent(Game.entities.movement[i].entity, physics);
|
||||
|
||||
if(!cp || !cp->geom || cp->type != CPHYSICS_CAPSULE) {
|
||||
rayGeoms[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
rayGeoms[i] = dCreateRay(Game.space, 1);
|
||||
|
||||
dGeomSetData(rayGeoms[i], (void*) (uintptr_t) i);
|
||||
|
||||
dGeomSetCategoryBits(rayGeoms[i], CATEGORY_RAY);
|
||||
dGeomSetCollideBits(rayGeoms[i], CATEGORY_STATIC | CATEGORY_ENTITY);
|
||||
|
||||
dBodyID bid = dGeomGetBody(cp->geom);
|
||||
|
||||
const float *position = dBodyGetPosition(bid);
|
||||
|
||||
dGeomRaySet(rayGeoms[i], position[0], position[1] - cp->capsule.length / 2 + 0.5, position[2], 0, -1, 0);
|
||||
}
|
||||
|
||||
dSpaceCollide(Game.space, NULL, game_character_controller_raycast_handler);
|
||||
|
||||
for(int i = 0; i < Game.entities.movementCount; i++) {
|
||||
if(rayGeoms[i]) {
|
||||
dGeomDestroy(rayGeoms[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void game_update() {
|
||||
game_character_controller_raycast();
|
||||
|
||||
for(size_t i = 0; i < Game.entities.playerctrlCount; i++) {
|
||||
struct CPlayerCtrl *cc = &Game.entities.playerctrl[i];
|
||||
|
||||
@ -528,6 +607,8 @@ void game_update() {
|
||||
if(glm_vec3_norm(wishvel) > 3) {
|
||||
glm_vec3_scale_as(wishvel, 3, wishvel);
|
||||
}
|
||||
} else {
|
||||
vec3_project_to_plane(wishvel, Game.entities.movement[mi].groundNormal, wishvel);
|
||||
}
|
||||
|
||||
float currentspeed = glm_vec3_dot(wishvel, dBodyGetLinearVel(bid));
|
||||
|
@ -88,6 +88,7 @@ struct CMovement {
|
||||
vec3 dir;
|
||||
float pointing;
|
||||
char jump, canJump;
|
||||
vec3 groundNormal;
|
||||
uint16_t holding;
|
||||
};
|
||||
|
||||
|
@ -227,6 +227,7 @@ static int eng_init() {
|
||||
GameWnd = glfwCreateWindow(START_WIDTH, START_HEIGHT, START_TITLE, NULL, NULL);
|
||||
}
|
||||
|
||||
// Attempt compatibility
|
||||
if(!GameWnd) {
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);
|
||||
@ -299,7 +300,7 @@ static void fix_resol() {
|
||||
}
|
||||
|
||||
static void eng_ui_init() {
|
||||
set_ui_mode(1);
|
||||
set_ui_mode(!!UiActive);
|
||||
}
|
||||
|
||||
static void fps_counter_step(double newDT) {
|
||||
@ -338,6 +339,7 @@ static int gr_shadowmap_init() {
|
||||
"!!ARBfp1.0\n"
|
||||
"TEMP col;\n"
|
||||
"TEX col, fragment.texcoord, texture[0], 2D;\n"
|
||||
"MOV result.color, col;\n"
|
||||
"MAD col.xyz, -col, 29.9, 30.1;\n"
|
||||
"RCP col.x, col.x;\n"
|
||||
"RCP col.y, col.y;\n"
|
||||
@ -393,7 +395,6 @@ int main(int argc_, char **argv_) {
|
||||
argv = argv_;
|
||||
|
||||
eng_init();
|
||||
eng_ui_init();
|
||||
|
||||
gr_shadowmap_init();
|
||||
gr_bloom_init();
|
||||
@ -413,6 +414,8 @@ int main(int argc_, char **argv_) {
|
||||
luaapi_load(k4_get_arg("script") ? k4_get_arg("script") : "init");
|
||||
//
|
||||
|
||||
eng_ui_init();
|
||||
|
||||
LuaapiStartTime = glfwGetTime();
|
||||
|
||||
LastTime = glfwGetTime();
|
||||
|
Loading…
Reference in New Issue
Block a user