diff --git a/bin/back b/bin/back index 1169b55..4321870 100755 Binary files a/bin/back and b/bin/back differ diff --git a/levels/level_04/room_0 b/levels/level_04/room_0 index b18a962..221430d 100644 --- a/levels/level_04/room_0 +++ b/levels/level_04/room_0 @@ -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] [ 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 [ -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] diff --git a/obj/entities.o b/obj/entities.o index b500cc3..fd9027d 100644 Binary files a/obj/entities.o and b/obj/entities.o differ diff --git a/obj/move.o b/obj/move.o index 42171a9..46bbf3e 100644 Binary files a/obj/move.o and b/obj/move.o differ diff --git a/src/entities.c b/src/entities.c index 6f4a0dc..66dff2e 100644 --- a/src/entities.c +++ b/src/entities.c @@ -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->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) { - ret->hz_angle -= ((double)dtime)*ent->metad1; + /*ret->hz_angle -= ((double)dtime)*ent->metad1; ret->vt_angle -= ((double)dtime)*ent->metad2; ret->x = ent->metad4+(ent->metad7)*cos(ret->hz_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); - - updateF(ret, (double)dtime, ent); + ret->z = ent->metad6+(ent->metad7)*sin(ret->hz_angle)+(ent->metad8)*cos(ret->vt_angle);*/ + //printf("DDDD\n"); + 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) { //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) { diff --git a/src/move.c b/src/move.c index 79a5d39..feada60 100644 --- a/src/move.c +++ b/src/move.c @@ -32,6 +32,12 @@ double gravity_factor = 26.0; const double blockRestitution = 0.2; +entity* entToVelCheck = NULL; +bool doUpdateEntVel = false; + +entity* movingPlatformUpdate = NULL; +bool doUpdateMoving = false; + bool is_clipping = false; 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) { for(int d = 0; d < 6; d++) { 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.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.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); } - pt_2d utheta = cross_product(camD, normal); + 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.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); } - 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; 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 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 h = -1; h <= 1; 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); //} if(dist <= min_dist) { - if(updateForces) { + if(update_physics && updateForces) { updateF(vstd->map[k], (double)dtime, NULL); } globalCollision = true; @@ -394,7 +498,7 @@ bool is_colliding(float dtime) { 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); if(dist <= min_dist) { - if(updateForces) { + if(update_physics && updateForces) { updateF(vstd->tps[k]->hitbox, (double)dtime, NULL); } int old_chx = player_chx; @@ -434,7 +538,7 @@ bool is_colliding(float dtime) { 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]); } if(exists && ( @@ -455,7 +559,15 @@ bool is_colliding(float dtime) { return globalCollision; } +double old_camx = 0.0; +double old_camy = 0.0; +double old_camz = 0.0; + void movePlayerG(float dtime) { + old_camx = camx; + old_camy = camy; + old_camz = camz; + updateForces = true; fx = 0.0; fy = 0.0; @@ -473,6 +585,7 @@ void movePlayerG(float dtime) { camy += dely; camz += delz; is_clipping = true; + update_physics = true; if(is_colliding(dtime)) { if(is_clipping) { //player_hp -= (dtime)*clip_dps; @@ -522,6 +635,13 @@ void movePlayerG(float dtime) { current_room = hashtbl_find_opt(visited, player_chx, player_chy); resetProj(); } + + update_physics = false; + if(is_colliding(dtime)) { + camx = old_camx; + camy = old_camy; + camz = old_camz; + } } void teleport_on_edge() { diff --git a/src/structure.h b/src/structure.h index befa908..d8e09a3 100644 --- a/src/structure.h +++ b/src/structure.h @@ -204,6 +204,12 @@ extern bool mathSignal; extern int mathSigCD; extern mathRes mathResult; +extern entity* entToVelCheck; +extern bool doUpdateEntVel; + +extern entity* movingPlatformUpdate; +extern bool doUpdateMoving; + extern int creativeWarpTarget; extern int creativeIntID;