From 490abae3d36ba1d00c0884adc56e5f4905bab439 Mon Sep 17 00:00:00 2001 From: terencehill Date: Sat, 11 Nov 2023 18:11:51 +0100 Subject: [PATCH] Don't allow negative values for the y component of the shot origin offset because the gun can't be aligned to the left by default. Thanks to this change it's possible to restore precision of the y and z components back to 0.25 --- qcsrc/common/util.qc | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/qcsrc/common/util.qc b/qcsrc/common/util.qc index c0ea0afea..1bb77a1f5 100644 --- a/qcsrc/common/util.qc +++ b/qcsrc/common/util.qc @@ -1184,43 +1184,44 @@ vector get_shotvelocity(vector myvel, vector mydir, float spd, float newton_styl return myvel + spd * mydir; } -// compresses the shot origin offset vector to an int with the following format: -// xxxxxxxx SSyyyyyy SUzzzzzz -// 32109876 54321098 76543210 -// 1st byte: x component (it uses all 8 bits) -// 2nd byte: y component in the last 6 bits and the signs of the x and y components -// 3rd byte: z component in the last 6 bits and the sign of the z component (the 2nd bit is unused) -// all values are doubled on compression and halved on decompression -// so the precision for all components is 0.5 -// values are bound to the following ranges: -// x: -127.5 +127.5 -// y: -31.5 +31.5 -// z: -31.5 +31.5 +/* + * Compresses the shot origin offset vector to an int with the following format: + * xxxxxxxx|Syyyyyyy|Syzzzzzz + * 32109876|54321098|76543210 + * 1st byte: x component + * 2nd byte: y component in the last 7 bits and the sign of the x component in the 1st bit + * 3rd byte: z component in the last 7 bits and the sign of the z component in the 1st bit + * All values are multiplied on compression and divided on decompression + * so the precision of the values is 0.5 if multiplied by 2 and 0.25 if multiplied by 4 + * Values are bound to the following ranges: + * x: -127.5 +127.5 + * y: 0 +31.75 negative values not allowed because the gun can't be aligned to the left by default + * z: -31.75 +31.75 + */ float compressShotOrigin(vector v) { int rx_neg = (v.x < 0) ? 1 : 0; - int ry_neg = (v.y < 0) ? 1 : 0; int rz_neg = (v.z < 0) ? 1 : 0; int rx = rint(fabs(v.x) * 2); - int ry = rint(fabs(v.y) * 2); - int rz = rint(fabs(v.z) * 2); - if(rx > 255) + int ry = rint(v.y * 4); + int rz = rint(fabs(v.z) * 4); + if(rx > 255) // 128 * 2 - 1 { LOG_DEBUG("shot origin ", vtos(v), " x out of bounds\n"); rx = bound(0, rx, 255); } - if(ry > 63) + if(ry > 127 || ry < 0) // 32 * 4 - 1 { LOG_DEBUG("shot origin ", vtos(v), " y out of bounds\n"); - ry = bound(0, ry, 63); + ry = bound(0, ry, 127); } - if(rz > 63) + if(rz > 127) // 32 * 4 - 1 { LOG_DEBUG("shot origin ", vtos(v), " z out of bounds\n"); - rz = bound(0, rz, 63); + rz = bound(0, rz, 127); } - ry |= ry_neg * BIT(6) + rx_neg * BIT(7); - rz |= rz_neg * BIT(6); // BIT(7) unused + ry |= rx_neg * BIT(7); + rz |= rz_neg * BIT(7); return rx * 0x10000 + ry * 0x100 + rz; } vector decompressShotOrigin(int f) @@ -1231,9 +1232,8 @@ vector decompressShotOrigin(int f) v.z = f & 0xFF; // remove sign bits and apply sign if (v.y & BIT(7)) { v.y &= ~BIT(7); v.x *= -1; } - if (v.y & BIT(6)) { v.y &= ~BIT(6); v.y *= -1; } - if (v.z & BIT(6)) { v.z &= ~BIT(6); v.z *= -1; } - return v / 2; + if (v.z & BIT(7)) { v.z &= ~BIT(7); v.z *= -1; } + return vec3(v.x / 2, v.y / 4, v.z / 4); } #ifdef GAMEQC -- 2.39.2