From: Juhu <5894800-Juhu_@users.noreply.gitlab.com> Date: Sat, 28 Sep 2024 15:55:37 +0000 (+0200) Subject: dynamic gravity support, WIP X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=refs%2Fheads%2FJuhu%2Fdynamic_gravity;p=xonotic%2Fxonotic-data.pk3dir.git dynamic gravity support, WIP --- diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 261fd1b01..a7689dd2a 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -1692,6 +1692,41 @@ void CSQC_UpdateView(entity this, float w, float h, bool notmenu) // Render the Scene view_origin = getpropertyvec(VF_ORIGIN); view_angles = getpropertyvec(VF_ANGLES); + + /*{ + vector grav_angles = vectoangles(PHYS_GRAVITY_DIR(this)); + + // model is already facing the floor, no need to tilt 90 degrees + PITCH(grav_angles) += 90; + + // adjust roll and pitch depending on grav direction + float pitch_ratio = cos((YAW(grav_angles) - YAW(view_angles)) * DEG2RAD); + float roll_ratio = sin((YAW(grav_angles) - YAW(view_angles)) * DEG2RAD); + ROLL(view_angles) = PITCH(grav_angles) * roll_ratio + ROLL(grav_angles) * pitch_ratio; + }*/ + + { + vector grav_dir = PHYS_GRAVITY_DIR(this); + bool upside_down = grav_dir.z > 0; + + if (upside_down) grav_dir.z = -grav_dir.z; + + vector grav_angles = vectoangles(grav_dir); + + // model is already facing the floor, no need to tilt 90 degrees + PITCH(grav_angles) += 90; + PITCH(grav_angles) = PITCH(grav_angles) % 360; + + if (upside_down) YAW(grav_angles) += 180; + + // adjust roll and pitch depending on grav direction + float pitch_ratio = cos((YAW(grav_angles) - YAW(view_angles)) * DEG2RAD); + float roll_ratio = sin((YAW(grav_angles) - YAW(view_angles)) * DEG2RAD); + ROLL(view_angles) = PITCH(grav_angles) * roll_ratio + ROLL(grav_angles) * pitch_ratio; + + if (upside_down) ROLL(view_angles) += 180; + } + MAKE_VECTORS(view_angles, view_forward, view_right, view_up); #ifdef BLURTEST diff --git a/qcsrc/common/physics/movetypes/movetypes.qc b/qcsrc/common/physics/movetypes/movetypes.qc index 2c54617ef..e6cebbbce 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qc +++ b/qcsrc/common/physics/movetypes/movetypes.qc @@ -142,9 +142,9 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this)) { if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE) - this.velocity_z -= grav * 0.5; + this.velocity += grav * 0.5 * normalize(PHYS_GRAVITY_DIR(this)); else - this.velocity_z -= grav; + this.velocity += grav * normalize(PHYS_GRAVITY_DIR(this)); } } @@ -324,7 +324,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this)) { if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE) - this.velocity_z -= grav * 0.5f; + this.velocity += grav * 0.5f * normalize(PHYS_GRAVITY_DIR(this)); } } diff --git a/qcsrc/common/physics/movetypes/movetypes.qh b/qcsrc/common/physics/movetypes/movetypes.qh index db4c80d60..e82cfb3ce 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qh +++ b/qcsrc/common/physics/movetypes/movetypes.qh @@ -52,6 +52,7 @@ const int WATERLEVEL_SUBMERGED = 3; #define PHYS_GRAVITY(s) STAT(MOVEVARS_GRAVITY, s) // FIXME: 0 doesn't mean zero gravity + #define PHYS_GRAVITY_DIR(s) STAT(MOVEVARS_GRAVITY_DIR, s) #define PHYS_ENTGRAVITY(s) STAT(MOVEVARS_ENTGRAVITY, s) #define TICRATE ticrate @@ -63,6 +64,7 @@ const int WATERLEVEL_SUBMERGED = 3; #define GAMEPLAYFIX_Q2AIRACCELERATE autocvar_sv_gameplayfix_q2airaccelerate #define PHYS_GRAVITY(s) autocvar_sv_gravity + #define PHYS_GRAVITY_DIR(s) autocvar_sv_gravity_dir #define PHYS_ENTGRAVITY(s) ((s).gravity) #define TICRATE sys_frametime diff --git a/qcsrc/common/physics/player.qc b/qcsrc/common/physics/player.qc index b007afaf1..38f9ad7fd 100644 --- a/qcsrc/common/physics/player.qc +++ b/qcsrc/common/physics/player.qc @@ -384,6 +384,8 @@ bool PlayerJump(entity this) bool doublejump = false; float mjumpheight = ((PHYS_JUMPVELOCITY_CROUCH(this) && IS_DUCKED(this)) ? PHYS_JUMPVELOCITY_CROUCH(this) : PHYS_JUMPVELOCITY(this)); + vector grav_dir = normalize(PHYS_GRAVITY_DIR(this)); + float velocity_up = this.velocity * -grav_dir; bool track_jump = PHYS_CL_TRACK_CANJUMP(this); if (MUTATOR_CALLHOOK(PlayerJump, this, mjumpheight, doublejump)) @@ -402,7 +404,7 @@ bool PlayerJump(entity this) } else { - this.velocity_z = PHYS_MAXSPEED(this) * 0.7; + this.velocity = PHYS_MAXSPEED(this) * 0.7 * -grav_dir; return true; } } @@ -426,8 +428,8 @@ bool PlayerJump(entity this) { float minjumpspeed = mjumpheight * stof(PHYS_JUMPSPEEDCAP_MIN); - if (this.velocity_z < minjumpspeed) - mjumpheight += minjumpspeed - this.velocity_z; + if (velocity_up < minjumpspeed) + mjumpheight += minjumpspeed - velocity_up; } if(PHYS_JUMPSPEEDCAP_MAX != "") @@ -439,8 +441,8 @@ bool PlayerJump(entity this) { float maxjumpspeed = mjumpheight * stof(PHYS_JUMPSPEEDCAP_MAX); - if (this.velocity_z > maxjumpspeed) - mjumpheight -= this.velocity_z - maxjumpspeed; + if (velocity_up > maxjumpspeed) + mjumpheight -= velocity_up - maxjumpspeed; } } @@ -463,7 +465,7 @@ bool PlayerJump(entity this) #endif } - this.velocity_z += mjumpheight; + this.velocity += mjumpheight * -grav_dir; UNSET_ONGROUND(this); UNSET_ONSLICK(this); diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index 9b4394e45..14a0aa17e 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -415,12 +415,14 @@ REGISTER_STAT(ROUND_TIMELIMIT, float, round_limit) #ifdef SVQC float autocvar_sv_wallfriction; #define autocvar_sv_gravity cvar("sv_gravity") +vector autocvar_sv_gravity_dir = '0 0 -1'; float autocvar_sv_stepheight; #endif REGISTER_STAT(MOVEVARS_WALLFRICTION, int, autocvar_sv_wallfriction) REGISTER_STAT(MOVEVARS_TICRATE, float, autocvar_sys_ticrate) REGISTER_STAT(MOVEVARS_TIMESCALE, float, autocvar_slowmo) REGISTER_STAT(MOVEVARS_GRAVITY, float, autocvar_sv_gravity) +REGISTER_STAT(MOVEVARS_GRAVITY_DIR, vector, autocvar_sv_gravity_dir) REGISTER_STAT(MOVEVARS_STOPSPEED, float) REGISTER_STAT(MOVEVARS_MAXSPEED, float) REGISTER_STAT(MOVEVARS_ACCELERATE, float) diff --git a/qcsrc/ecs/systems/physics.qc b/qcsrc/ecs/systems/physics.qc index 167b49235..7174931de 100644 --- a/qcsrc/ecs/systems/physics.qc +++ b/qcsrc/ecs/systems/physics.qc @@ -87,6 +87,46 @@ void sys_phys_update(entity this, float dt) CheckPlayerJump(this); } + // make the player model face the ground relative to the current gravity direction + { + float saved_yaw = YAW(this.angles); + vector grav_dir = PHYS_GRAVITY_DIR(this); + bool upside_down = grav_dir.z > 0; + + if (upside_down) { + grav_dir.z = -grav_dir.z; + } + + this.angles = vectoangles(grav_dir); + + // model is already facing the floor, no need to tilt 90 degrees + PITCH(this.angles) += 90; + PITCH(this.angles) = PITCH(this.angles) % 360; + + if (upside_down) YAW(this.angles) += 180; + + // adjust roll and pitch depending on grav direction + float saved_pitch = PITCH(this.angles); + float saved_roll = ROLL(this.angles); + float pitch_ratio = cos((YAW(this.angles) - saved_yaw) * DEG2RAD); + float roll_ratio = sin((YAW(this.angles) - saved_yaw) * DEG2RAD); + PITCH(this.angles) = saved_pitch * pitch_ratio + saved_roll * roll_ratio; + ROLL(this.angles) = saved_pitch * roll_ratio + saved_roll * pitch_ratio; + YAW(this.angles) = saved_yaw; + + if (upside_down) ROLL(this.angles) += 180; + + // pitch can't be >= 90, transform to something usable + if (fabs(PITCH(this.angles)) >= 91) { + PITCH(this.angles) = copysign(180, PITCH(this.angles)) - PITCH(this.angles); + YAW(this.angles) += 180; + ROLL(this.angles) += 180; + } + else if (fabs(PITCH(this.angles)) > 89) { + PITCH(this.angles) = copysign(89, PITCH(this.angles)); + } + } + if (this.flags & FL_WATERJUMP) { this.velocity_x = this.movedir.x; this.velocity_y = this.movedir.y;