]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
dynamic gravity support, WIP Juhu/dynamic_gravity
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Sat, 28 Sep 2024 15:55:37 +0000 (17:55 +0200)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Sat, 28 Sep 2024 15:55:37 +0000 (17:55 +0200)
qcsrc/client/view.qc
qcsrc/common/physics/movetypes/movetypes.qc
qcsrc/common/physics/movetypes/movetypes.qh
qcsrc/common/physics/player.qc
qcsrc/common/stats.qh
qcsrc/ecs/systems/physics.qc

index 261fd1b01149392e106e1b2e56b5bb15b6b1e5a2..a7689dd2a7ce9301e4d985573da135bbaf29d0ef 100644 (file)
@@ -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
index 2c54617ef208c689b60f07b7cc7f2438d0618f7d..e6cebbbcec452487784ebec1612d882d2b5f4fad 100644 (file)
@@ -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));
                }
        }
 
index db4c80d6001e5af82f1b26b19107c3e16a901518..e82cfb3ce8a9aee5fefc6fad4b155414dd390953 100644 (file)
@@ -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
index b007afaf1875342cfd2b5afa988ba81603bf8320..38f9ad7fd78f9ca920e9cbc099705241e1bc77a3 100644 (file)
@@ -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);
index 9b4394e45a62f1d0a2851555945521740c7c8e71..14a0aa17e397eae3010ef652b66d206785ba6b3a 100644 (file)
@@ -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)
index 167b492356195e61f9d63d369b8443470a2a6e8a..7174931ded106e85d53c43d0f3960c19ea5f1ad7 100644 (file)
@@ -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;