added matching physics for spinning things

This commit is contained in:
Alexandre 2025-03-06 16:24:24 +01:00
parent 254744509f
commit a075564477
20 changed files with 95 additions and 53 deletions

View File

@ -41,7 +41,7 @@ entities:
-> 0 (coin) -> damage equals the coin's value
-> 1 (non-moving explosive)
-> 2 (damaging firebar)
[.. hz_rps, vt_rps, x_offset, y_offset, z_offset dps] with
[.. hz_rps, vt_rps, x_offset, y_offset, z_offset, dps] with
{hz,vt}_rps = double
hz0, vt_0 = double
{x,y,z}_offset = double // if all is 0.0, the solid will rotate according to its center of mass, this shifts that center
@ -82,9 +82,7 @@ entities:
{ontime,offtime} = double[>0.0]
start = {0,1}
-> 10 (spinning platform)
[.. hz_speed, vt_speed] with
{hz_speed,vt_speed} = double
-> 10 UNUSED
-> 11 (button trigger)
[.. freq, dtime] with

BIN
bin/back

Binary file not shown.

View File

@ -4,7 +4,6 @@ Blocks :
[ -4.0,-10.0, -4.0, 8.0, 2.0, 8.0, 0.0, 0.0, 128, 128, 128]
[ -4.0, -6.5, -2.0, 2.0, 1.0, 2.0, 0.0, 0.3, 128, 128, 128]
[ -4.0, -6.5, 2.0, 2.0, 1.0, 2.0, 0.3, 0.0, 128, 128, 128]
[-18.0, 10.0, -16.0, 3.0, 1.0,32.0, 0.0, 0.4, 255, 255, 255]
[ -6.0, 10.0, 0.0, 6.0, 2.0, 2.0, 0.0, 0.0, 32, 192, 32] // cp1
@ -31,6 +30,9 @@ Blocks :
[7.0, 44.0, 2.0, 4.0, 1.0, 4.0, 0.0, 0.0, 32, 192, 32] // cp4
Entities:
[-15.0, 4.0, -15.0, 4.0, 1.0, 5.0, 0.0, 0.0, 255, 255, 255, 1, 0, 2, 0.0, 42.0, 0.0, 0.0, 2.0, 1]
[8.0, 1.0 , 8.0, 2.0, 2.0, 2.0, 0.0, 0.0, 255, 255, 128, 1, 0, 8, 100, 1, 128, 128, 128]
[-8.0, 1.0, 8.0, 2.0, 2.0, 2.0, 0.0, 0.0, 255, 255, 255, 1, 0, 6, get over it, 192, 192, 192]
[8.5, 1.5 , 8.5, 1.0, 1.0, 1.0, 0.0, 0.0, 192, 192, 192, 1, 0, 7, levels/level_01/, 7, great, 192, 192, 192]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -402,6 +402,27 @@ void project_to_cube(double x0, double y0, double z0, double* rx, double* ry, do
if(rz != NULL) {*rz = c->z + c->d/2.0 + zry*cos(c->vt_angle) - yry*sin(c->vt_angle);}
}
pt_2d rotate_to_x_axis(double x, double y, double z, double y0, double z0, int angle) {
pt_2d res;
res.x = x;
res.y = y0+(y-y0)*cos(angle) + (z-z0)*sin(angle);
res.z = z0+(z-z0)*cos(angle) - (y-y0)*sin(angle);
//printf("> %lf %lf %lf <\n", res.x, res.y, res.z);
return res;
}
pt_2d rotate_to_y_axis(double x, double y, double z, double x0, double z0, int angle) {
pt_2d res;
res.x = x0+(x-x0)*cos(angle) - (z-z0)*sin(angle);
res.y = y;
res.z = z0+(z-z0)*cos(angle) + (x-x0)*sin(angle);
return res;
}
// ------------------------------------------------------------------------------------------------ //
void remove_entity(entity** arr, int* memlen, int* len, int index) {

View File

@ -60,5 +60,7 @@ void add_entity(entity** arr, int* memlen, int* len, entity* ent);
void project_to_camera(double x0, double y0, double z0, double* rx, double* ry, double* rz);
void project_to_cube(double x0, double y0, double z0, double* rx, double* ry, double* rz, cube_0* c);
pt_2d rotate_to_x_axis(double x, double y, double z, double y0, double z0, int angle);
pt_2d rotate_to_y_axis(double x, double y, double z, double x0, double z0, int angle);
#endif

View File

@ -16,6 +16,7 @@
#include "display.h"
#include "menus.h"
#include "proj.h"
#include "move.h"
#include "maeth.h"
#include "entities.h"
@ -223,6 +224,16 @@ void lava_postStep(double x, double y, double z, double w, double h, double d, d
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);
if(distance_pt_cube_0_3d_infinite(camx, camy, camz, ret) <= min_dist) {
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);
}
}
void lava_onHit(float dtime, int* hp, int* dmg, entity* ent, cube_0* ret) {

View File

@ -125,9 +125,9 @@ void init_ent_generator(int n) {
hashtbl_entities[10].id = 10;
hashtbl_entities[10].tex = 4;
hashtbl_entities[10].tex2 = 4;
hashtbl_entities[10].name = "SpinningPlatform";
hashtbl_entities[10].updatePos = &spinning_platform;
hashtbl_entities[10].onHit = &spinning_translate;
hashtbl_entities[10].name = "E";
hashtbl_entities[10].updatePos = NULL;
hashtbl_entities[10].onHit = NULL;
hashtbl_entities[10].onDeath = NULL;
hashtbl_entities[11].id = 11;
@ -471,6 +471,11 @@ void parse_one_room(int id, char* filename) {
pool[id].area->ents[k]->metad8 = sqrt(offy*offy+offz*offz);
printf("--> %lf %lf <-- with %lf %lf %lf\n", pool[id].area->ents[k]->metad7, pool[id].area->ents[k]->metad8, offx, offy, offz);
pool[id].area->ents[k]->metai1 = dps;
if(dps == 0) {
pool[id].area->ents[k]->tex = 4;
pool[id].area->ents[k]->tex2 = 4;
}
} else if(entry->id == 3) {
// mine
double pspd = read_float(ptr);
@ -611,12 +616,7 @@ void parse_one_room(int id, char* filename) {
pool[id].area->ents[k]->metad3 = 0.0;
pool[id].area->ents[k]->metai1 = 1-stst;
} else if(entry->id == 10) {
// spinning platform
double hzspd = read_float(ptr);
double vtspd = read_float(ptr);
pool[id].area->ents[k]->metad1 = hzspd;
pool[id].area->ents[k]->metad2 = vtspd;
// UNUSED
} else if(entry->id == 11) {
int freq = read_int(ptr);
double acttime = read_float(ptr);

View File

@ -30,6 +30,8 @@ double friction = 0.3;
double gravity_factor = 26.0;
// ---------------------------------------------------------------------------------------------------- //
const double blockRestitution = 0.2;
bool is_clipping = false;
int clip_dps = 500;
@ -195,6 +197,14 @@ void getNormal() {
normal.z /= norm;
}
pt_2d cross_product(pt_2d p1, pt_2d p2) {
return (pt_2d){
.x = p1.y*p2.z - p1.z*p2.y,
.y = p1.z*p2.x - p1.x*p2.z,
.z = p1.x*p2.y - p1.y*p2.x
};
}
void normalize(pt_2d* p) {
double norm = sqrt(p->x*p->x + p->y*p->y + p->z*p->z);
p->x /= norm;
@ -227,7 +237,7 @@ void debugMove(cube_0* cb) {
}
}
void updateF(cube_0* cb, double dtime) {
void updateF(cube_0* cb, double dtime, entity* ent) {
for(int d = 0; d < 6; d++) {
cb->x -= min_dist;
cb->y -= min_dist;
@ -267,13 +277,33 @@ void updateF(cube_0* cb, double dtime) {
pt_2d u = (pt_2d){.x = normal.x*nu, .y = normal.y*nu, .z = normal.z*nu};
camvx += u.x;
camvy += u.y;
camvz += u.z;
normalize(&u);
//camvx /= 1.41;
//camvy /= 1.41;
//camvz /= 1.41;
if(ent != NULL && ent->entity_type == 2) {
double radspeed = distance_pt_pt_3d(camx, camy, camz, ent->metad4, ent->metad5, ent->metad6)*(ent->metad1+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;
normalize(&camD);
pt_2d utheta = cross_product(camD, normal);
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;
normalize(&camD2);
pt_2d utheta2 = cross_product(camD2, normal);
camvx = u.x*normv*(blockRestitution) + utheta.x*radspeed - utheta2.x*radspeed;
camvy = u.y*normv*(blockRestitution) + utheta.y*radspeed - utheta2.y*radspeed;
camvz = u.z*normv*(blockRestitution) + utheta.z*radspeed - utheta2.z*radspeed;
} else {
camvx = u.x*normv*(blockRestitution);
camvy = u.y*normv*(blockRestitution);
camvz = u.z*normv*(blockRestitution);
}
is_clipping = false;
}
@ -293,7 +323,7 @@ bool is_colliding(float dtime) {
//}
if(dist <= min_dist) {
if(updateForces) {
updateF(vstd->map[k], (double)dtime);
updateF(vstd->map[k], (double)dtime, NULL);
}
globalCollision = true;
}
@ -303,7 +333,7 @@ bool is_colliding(float dtime) {
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) {
updateF(vstd->tps[k]->hitbox, (double)dtime);
updateF(vstd->tps[k]->hitbox, (double)dtime, NULL);
}
int old_chx = player_chx;
int old_chy = player_chy;
@ -343,7 +373,7 @@ bool is_colliding(float dtime) {
}
}
if(exists && updateForces && vstd->ents[k]->entity_type != 0) {
updateF(vstd->ents[k]->pos, (double)dtime);
updateF(vstd->ents[k]->pos, (double)dtime, vstd->ents[k]);
}
if(exists && (
vstd->ents[k]->entity_type == 13 ||

View File

@ -6,6 +6,8 @@ bool is_colliding(float dtime);
void update_buttons(float dtime);
void updateF(cube_0* cb, double dtime, entity* ent);
void debugMove(cube_0* cb);
void teleport_on_edge();

View File

@ -111,6 +111,7 @@ bool get_id(int* res) {
}
void play_sound(char* filename) {
return;
pthread_mutex_lock(&lock);
int id;
if(get_id(&id)) {

View File

@ -8,37 +8,12 @@ Teleporters :
[-1.0, 1.0, 9.0, 2.0, 2.0, 1.0, 0.0, 0.0, 0, 0, 255; 0, 1]
Entities:
[-2.0, 4.1, -2.0, 4.0, 1.0, 4.0, 0.0, 0.0, 32, 128, 192, 10, 0, 5, 0.0, 4.0, 0.0, 0.0, 5.5, 0.0]
[-6.0, 8.1, -2.0, 4.0, 1.0, 4.0, 0.0, 0.0, 32, 128, 192, 10, 0, 10, 2.0, 0.0]
[6.0, 12.1, -2.0, 4.0, 1.0, 4.0, 0.0, 0.0, 32, 128, 192, 10, 0, 5, 0.0, 4.0, 0.0, 0.0, 6.5, 0.0]
[-2.0, 4.1, -2.0, 4.0, 1.0, 4.0, 0.0, 0.0, 32, 128, 192, 1, 0, 5, 0.0, 4.0, 0.0, 0.0, 5.5, 0.0]
[-6.0, 8.1, -2.0, 4.0, 1.0, 4.0, 0.0, 0.0, 32, 128, 192, 1, 0, 2, 2.0, 0.0, 0.0, 0.0, 0.0, 0]
[6.0, 12.1, -2.0, 4.0, 1.0, 4.0, 0.0, 0.0, 32, 128, 192, 1, 0, 5, 0.0, 4.0, 0.0, 0.0, 6.5, 0.0]
[0.0, 20.0, 0.0, 0.5, 0.5, 0.5, 0.0, 0.0, 255, 255, 0, 10, 0, 0]
Weight :
50
$
entities:
[x, y, z, w, h, d, rhz, rvt, red, green, blue, hp, damage, entityType ..]
if entityType = 4 (moving platform)
[.. amplitude_x, amplitude_y, amplitude_z, mult, divd, phase] with
amplitude_{x,y,z} = double[>= 0.0]
{mult,divd} = int
{phase} = int[0, 360]
else if entityType = 5 (linear moving platform)
[.. amplitude_x, amplitude_y, amplitude_z, speed_x, speed_y, speed_z] with
amplitude_{x,y,z} = double[>= 0.0]
speed_{x,y,z} = double
else if entityType = 6 (text box)
[.. text] with
text = {char*}
else if entityType = 7 (warp text box)
[.. dest_folder, room_count, text, r, g, b] with
{dest_folder,text} = {char*} (length <= 50)
{r,g,b} = int[0-256]
else
[..]