fixed spinning platforms clipping the player into the ground

This commit is contained in:
Alexandre 2025-03-19 16:02:48 +01:00
parent 8c38e0fe78
commit bc4560b2fd
7 changed files with 145 additions and 12 deletions

BIN
bin/back

Binary file not shown.

View File

@ -41,6 +41,10 @@ Entities:
[ -1.9, 0.1, 2.1, 3.8, 3.8, 3.8, 0.0, 0.0, 192, 129, 192, 1, 0, 10, 0.98, 1.0] [ -1.9, 0.1, 2.1, 3.8, 3.8, 3.8, 0.0, 0.0, 192, 129, 192, 1, 0, 10, 0.98, 1.0]
[ 6.1, 0.1, 2.1, 3.8, 3.8, 3.8, 0.0, 0.0, 192, 129, 192, 1, 0, 10, 0.98, 1.0] [ 6.1, 0.1, 2.1, 3.8, 3.8, 3.8, 0.0, 0.0, 192, 129, 192, 1, 0, 10, 0.98, 1.0]
[-16.0, 0.0, -0.3, 32.0, 0.3, 0.6, 0.0, 0.0, 192, 192, 192, 1,0, 2, 1.4, 0.0, 0.0, 0.0, 0.0, 5]
[-0.3, 1.2, -16.0, 0.6, 0.3, 32.0, 0.0, 0.0, 192, 192, 192, 1,0, 2, 1.4, 0.0, 0.0, 0.0, 0.0, 5]
[-3.0, 10.0, -3.0, 6.0, 1.0, 6.0, 0.0, 0.0, 192, 192, 192, 1, 0, 2, 1.0, 0.0, 0.0, 0.0, 0.0, 0]
[ -9.0, 0.0, 7.0, 2.0, 0.2, 2.0, 0.0, 0.0, 192, 129, 192, 1, 0, 14, 0] // keys [ -9.0, 0.0, 7.0, 2.0, 0.2, 2.0, 0.0, 0.0, 192, 129, 192, 1, 0, 14, 0] // keys
[ -5.0, 0.0, 7.0, 2.0, 0.2, 2.0, 0.0, 0.0, 192, 129, 192, 1, 0, 14, 1] [ -5.0, 0.0, 7.0, 2.0, 0.2, 2.0, 0.0, 0.0, 192, 129, 192, 1, 0, 14, 1]
[ 3.0, 0.0, -9.0, 2.0, 0.2, 2.0, 0.0, 0.0, 192, 129, 192, 1, 0, 14, 2] [ 3.0, 0.0, -9.0, 2.0, 0.2, 2.0, 0.0, 0.0, 192, 129, 192, 1, 0, 14, 2]

Binary file not shown.

Binary file not shown.

View File

@ -268,14 +268,15 @@ void lava_postStep(double x, double y, double z, double w, double h, double d, d
ret->y = ent->metad5+(ent->metad8)*sin(ret->vt_angle); ret->y = ent->metad5+(ent->metad8)*sin(ret->vt_angle);
ret->z = ent->metad6+(ent->metad7)*sin(ret->hz_angle)+(ent->metad8)*cos(ret->vt_angle); ret->z = ent->metad6+(ent->metad7)*sin(ret->hz_angle)+(ent->metad8)*cos(ret->vt_angle);
if(distance_pt_cube_0_3d_infinite(camx, camy, camz, ret) <= min_dist) { if(distance_pt_cube_0_3d_infinite(camx, camy, camz, ret) <= min_dist) {
ret->hz_angle -= ((double)dtime)*ent->metad1; /*ret->hz_angle -= ((double)dtime)*ent->metad1;
ret->vt_angle -= ((double)dtime)*ent->metad2; ret->vt_angle -= ((double)dtime)*ent->metad2;
ret->x = ent->metad4+(ent->metad7)*cos(ret->hz_angle); ret->x = ent->metad4+(ent->metad7)*cos(ret->hz_angle);
ret->y = ent->metad5+(ent->metad8)*sin(ret->vt_angle); ret->y = ent->metad5+(ent->metad8)*sin(ret->vt_angle);
ret->z = ent->metad6+(ent->metad7)*sin(ret->hz_angle)+(ent->metad8)*cos(ret->vt_angle); ret->z = ent->metad6+(ent->metad7)*sin(ret->hz_angle)+(ent->metad8)*cos(ret->vt_angle);*/
//printf("DDDD\n");
updateF(ret, (double)dtime, ent); movingPlatformUpdate = ent;
doUpdateMoving = true;
} }
} }
@ -355,7 +356,9 @@ void movCrateButton_postStep(double x, double y, double z, double w, double h, d
void movableCrate_onHit(float dtime, int* hp, int* dmg, entity* ent, cube_0* ret) { void movableCrate_onHit(float dtime, int* hp, int* dmg, entity* ent, cube_0* ret) {
//printf("(+%lf, +%lf)\n", camvx, camvz); //printf("(+%lf, +%lf)\n", camvx, camvz);
updateF_movableCrate(ret, (double)dtime, ent); entToVelCheck = ent;
doUpdateEntVel = true;
//updateF_movableCrate(ret, (double)dtime, ent);
} }
void lava_onHit(float dtime, int* hp, int* dmg, entity* ent, cube_0* ret) { void lava_onHit(float dtime, int* hp, int* dmg, entity* ent, cube_0* ret) {

View File

@ -32,6 +32,12 @@ double gravity_factor = 26.0;
const double blockRestitution = 0.2; const double blockRestitution = 0.2;
entity* entToVelCheck = NULL;
bool doUpdateEntVel = false;
entity* movingPlatformUpdate = NULL;
bool doUpdateMoving = false;
bool is_clipping = false; bool is_clipping = false;
int clip_dps = 500; int clip_dps = 500;
@ -292,6 +298,10 @@ void updateF_movableCrate(cube_0* cb, double dtime, entity* ent) {
} }
} }
pt_2d normal_axis = {.x = 0.0, .y = 1.0, .z = 0.0};
pt_2d normal_axis2 = {.x = 1.0, .y = 0.0, .z = 0.0};
// rotation axis
void updateF(cube_0* cb, double dtime, entity* ent) { void updateF(cube_0* cb, double dtime, entity* ent) {
for(int d = 0; d < 6; d++) { for(int d = 0; d < 6; d++) {
cb->x -= min_dist; cb->x -= min_dist;
@ -344,19 +354,22 @@ void updateF(cube_0* cb, double dtime, entity* ent) {
camD.x = camx - ent->pos->w/2.0 - ent->metad4; camD.x = camx - ent->pos->w/2.0 - ent->metad4;
camD.y = 0.0; camD.y = 0.0;
camD.z = camz - ent->pos->d/2.0 - ent->metad6; camD.z = camz - ent->pos->d/2.0 - ent->metad6;
if(camD.x*camD.x + camD.y*camD.y + camD.z*camD.z != 0.0) { // avoid division by 0.0 if(camD.x*camD.x + camD.y*camD.y + camD.z*camD.z >= 0.001) { // avoid division by 0.0
normalize(&camD); normalize(&camD);
} }
pt_2d utheta = cross_product(camD, normal); pt_2d utheta = cross_product(camD, normal_axis);
pt_2d camD2; pt_2d camD2;
camD2.x = 0.0; camD2.x = 0.0;
camD2.y = camy - ent->pos->h/2.0 - ent->metad5; camD2.y = camy - ent->pos->h/2.0 - ent->metad5;
camD2.z = camz - ent->pos->d/2.0 - ent->metad6; camD2.z = camz - ent->pos->d/2.0 - ent->metad6;
if(camD2.x*camD2.x + camD2.y*camD2.y + camD2.z*camD2.z != 0.0) { // avoid division by 0.0 if(camD2.x*camD2.x + camD2.y*camD2.y + camD2.z*camD2.z >= 0.001) { // avoid division by 0.0
normalize(&camD2); normalize(&camD2);
} }
pt_2d utheta2 = normal;//cross_product(camD2, normal); pt_2d utheta2 = cross_product(camD2, normal_axis2);
//printf("(HZ) %lf %lf %lf\n", utheta.x*radspeed , utheta.y*radspeed , utheta.z*radspeed );
//printf("(VT) %lf %lf %lf\n\n", utheta2.x*radspeed2, utheta2.y*radspeed2, utheta2.z*radspeed2);
camvx = u.x*normv*(blockRestitution) + utheta.x*radspeed + utheta2.x*radspeed2; camvx = u.x*normv*(blockRestitution) + utheta.x*radspeed + utheta2.x*radspeed2;
camvy = u.y*normv*(blockRestitution) + utheta.y*radspeed + utheta2.y*radspeed2; camvy = u.y*normv*(blockRestitution) + utheta.y*radspeed + utheta2.y*radspeed2;
@ -372,8 +385,99 @@ void updateF(cube_0* cb, double dtime, entity* ent) {
} }
} }
void updateF_specific(cube_0* cb, double dtime, entity* ent) {
double dilat = distance_pt_cube_0_3d_infinite(camx, camy, camz, cb);
for(int d = 0; d < 6; d++) {
// force a collision
cb->x -= dilat;
cb->y -= dilat;
cb->z -= dilat;
getSF(cb, d);
cb->x += dilat;
cb->y += dilat;
cb->z += dilat;
getDirectors();
getNormal();
if(d==2 || d==5 || d==1) {
normal.x *= -1.0;
normal.y *= -1.0;
normal.z *= -1.0;
}
//printf("%lf %lf\n", dot3D(normal, directors[0]), dot3D(normal, directors[1]));
pt_2d vt = (pt_2d){.x = camx-camvx*dtime - surface[0].x, .y = camy-camvy*dtime - surface[0].y, .z = camz-camvz*dtime - surface[0].z};
pt_2d vtdt = (pt_2d){.x = camx - surface[0].x, .y = camy - surface[0].y, .z = camz - surface[0].z};
normalize(&vtdt);
normalize(&vt);
if(
(dot3D(vt, normal) <= 0.0 && dot3D(vtdt, normal) >= 0.0) ||
(dot3D(vt, normal) >= 0.0 && dot3D(vtdt, normal) <= 0.0)
) {
double normv = sqrt(camvx*camvx + camvy*camvy + camvz*camvz);
double alpha = acos(dot3D(normal, (pt_2d){.x = camvx, .y = camvy, .z = camvz})/normv);
double beta = 3.1415926535 - 2*alpha;
double nu = normv*sqrt(1-cos(beta));
pt_2d u = (pt_2d){.x = normal.x*nu, .y = normal.y*nu, .z = normal.z*nu};
normalize(&u);
camvx = u.x*normv*(blockRestitution);
camvy = u.y*normv*(blockRestitution);
camvz = u.z*normv*(blockRestitution);
is_clipping = false;
}
}
if(ent != NULL && ent->entity_type == 2) {
double radspeed = distance_pt_pt_3d(camx, camy, camz, ent->metad4+ent->pos->w/2.0, camy, ent->metad6+ent->pos->d/2.0
)*(ent->metad1);
double radspeed2 = distance_pt_pt_3d(camx, camy, camz, camx, ent->metad5+ent->pos->h/2.0, ent->metad6+ent->pos->d/2.0
)*(ent->metad2);
pt_2d camD;
camD.x = camx - ent->pos->w/2.0 - ent->metad4;
camD.y = 0.0;
camD.z = camz - ent->pos->d/2.0 - ent->metad6;
if(camD.x*camD.x + camD.y*camD.y + camD.z*camD.z >= 0.001) { // avoid division by 0.0
normalize(&camD);
}
pt_2d utheta = cross_product(camD, normal_axis);
pt_2d camD2;
camD2.x = 0.0;
camD2.y = camy - ent->pos->h/2.0 - ent->metad5;
camD2.z = camz - ent->pos->d/2.0 - ent->metad6;
if(camD2.x*camD2.x + camD2.y*camD2.y + camD2.z*camD2.z >= 0.001) { // avoid division by 0.0
normalize(&camD2);
}
pt_2d utheta2 = cross_product(camD2, normal_axis2);
//printf("(HZ) %lf %lf %lf\n", utheta.x*radspeed , utheta.y*radspeed , utheta.z*radspeed );
//printf("(VT) %lf %lf %lf\n\n", utheta2.x*radspeed2, utheta2.y*radspeed2, utheta2.z*radspeed2);
camvx = utheta.x*radspeed + utheta2.x*radspeed2;
camvy = utheta.y*radspeed + utheta2.y*radspeed2;
camvz = utheta.z*radspeed + utheta2.z*radspeed2;
}
//printf("\n");
}
bool update_physics = true;
bool is_colliding(float dtime) { bool is_colliding(float dtime) {
bool globalCollision = false; bool globalCollision = false;
if(doUpdateEntVel) {
updateF_movableCrate(entToVelCheck->pos, (double)dtime, entToVelCheck);
doUpdateEntVel = false;
}
if(doUpdateMoving) {
updateF_specific(movingPlatformUpdate->pos, (double)dtime, movingPlatformUpdate);
doUpdateMoving = false;
}
for(int w = -1; w <= 1; w++) { for(int w = -1; w <= 1; w++) {
for(int h = -1; h <= 1; h++) { for(int h = -1; h <= 1; h++) {
room* vstd = hashtbl_find_opt(visited, player_chx+w, player_chy+h); room* vstd = hashtbl_find_opt(visited, player_chx+w, player_chy+h);
@ -384,7 +488,7 @@ bool is_colliding(float dtime) {
// printf("(%lf)\n", dist); // printf("(%lf)\n", dist);
//} //}
if(dist <= min_dist) { if(dist <= min_dist) {
if(updateForces) { if(update_physics && updateForces) {
updateF(vstd->map[k], (double)dtime, NULL); updateF(vstd->map[k], (double)dtime, NULL);
} }
globalCollision = true; globalCollision = true;
@ -394,7 +498,7 @@ bool is_colliding(float dtime) {
for(int k = 0; k < vstd->tps_size; k++) { for(int k = 0; k < vstd->tps_size; k++) {
double dist = distance_pt_cube_0_3d_infinite(camx-2*room_width*w, camy, camz-2*room_depth*h, vstd->tps[k]->hitbox); double dist = distance_pt_cube_0_3d_infinite(camx-2*room_width*w, camy, camz-2*room_depth*h, vstd->tps[k]->hitbox);
if(dist <= min_dist) { if(dist <= min_dist) {
if(updateForces) { if(update_physics && updateForces) {
updateF(vstd->tps[k]->hitbox, (double)dtime, NULL); updateF(vstd->tps[k]->hitbox, (double)dtime, NULL);
} }
int old_chx = player_chx; int old_chx = player_chx;
@ -434,7 +538,7 @@ bool is_colliding(float dtime) {
k =- 1; k =- 1;
} }
} }
if(exists && updateForces && vstd->ents[k]->entity_type != 0) { if(update_physics && exists && updateForces && vstd->ents[k]->entity_type != 0) {
updateF(vstd->ents[k]->pos, (double)dtime, vstd->ents[k]); updateF(vstd->ents[k]->pos, (double)dtime, vstd->ents[k]);
} }
if(exists && ( if(exists && (
@ -455,7 +559,15 @@ bool is_colliding(float dtime) {
return globalCollision; return globalCollision;
} }
double old_camx = 0.0;
double old_camy = 0.0;
double old_camz = 0.0;
void movePlayerG(float dtime) { void movePlayerG(float dtime) {
old_camx = camx;
old_camy = camy;
old_camz = camz;
updateForces = true; updateForces = true;
fx = 0.0; fx = 0.0;
fy = 0.0; fy = 0.0;
@ -473,6 +585,7 @@ void movePlayerG(float dtime) {
camy += dely; camy += dely;
camz += delz; camz += delz;
is_clipping = true; is_clipping = true;
update_physics = true;
if(is_colliding(dtime)) { if(is_colliding(dtime)) {
if(is_clipping) { if(is_clipping) {
//player_hp -= (dtime)*clip_dps; //player_hp -= (dtime)*clip_dps;
@ -522,6 +635,13 @@ void movePlayerG(float dtime) {
current_room = hashtbl_find_opt(visited, player_chx, player_chy); current_room = hashtbl_find_opt(visited, player_chx, player_chy);
resetProj(); resetProj();
} }
update_physics = false;
if(is_colliding(dtime)) {
camx = old_camx;
camy = old_camy;
camz = old_camz;
}
} }
void teleport_on_edge() { void teleport_on_edge() {

View File

@ -204,6 +204,12 @@ extern bool mathSignal;
extern int mathSigCD; extern int mathSigCD;
extern mathRes mathResult; extern mathRes mathResult;
extern entity* entToVelCheck;
extern bool doUpdateEntVel;
extern entity* movingPlatformUpdate;
extern bool doUpdateMoving;
extern int creativeWarpTarget; extern int creativeWarpTarget;
extern int creativeIntID; extern int creativeIntID;