]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Don't allow negative values for the y component of the shot origin offset because... terencehill/shotorigin_compression
authorterencehill <piuntn@gmail.com>
Sat, 11 Nov 2023 17:11:51 +0000 (18:11 +0100)
committerterencehill <piuntn@gmail.com>
Sat, 11 Nov 2023 17:15:16 +0000 (18:15 +0100)
qcsrc/common/util.qc

index c0ea0afeafa926fd2ec0abf4f5712dc3d74b000e..1bb77a1f5af176cb800e0894dace887c0b6ba49c 100644 (file)
@@ -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