return myvel + spd * mydir;
}
-/*
- * 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
- */
+// 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
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(v.y * 4);
- int rz = rint(fabs(v.z) * 4);
- if(rx > 255) // 128 * 2 - 1
+ int ry = rint(fabs(v.y) * 2);
+ int rz = rint(fabs(v.z) * 2);
+ if(rx > 255)
{
LOG_DEBUG("shot origin ", vtos(v), " x out of bounds\n");
rx = bound(0, rx, 255);
}
- if(ry > 127 || ry < 0) // 32 * 4 - 1
+ if(ry > 63)
{
LOG_DEBUG("shot origin ", vtos(v), " y out of bounds\n");
- ry = bound(0, ry, 127);
+ ry = bound(0, ry, 63);
}
- if(rz > 127) // 32 * 4 - 1
+ if(rz > 63)
{
LOG_DEBUG("shot origin ", vtos(v), " z out of bounds\n");
- rz = bound(0, rz, 127);
+ rz = bound(0, rz, 63);
}
- ry |= rx_neg * BIT(7);
- rz |= rz_neg * BIT(7);
+ ry |= ry_neg * BIT(6) + rx_neg * BIT(7);
+ rz |= rz_neg * BIT(6); // BIT(7) unused
return rx * 0x10000 + ry * 0x100 + rz;
}
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.z & BIT(7)) { v.z &= ~BIT(7); v.z *= -1; }
- return vec3(v.x / 2, v.y / 4, v.z / 4);
+ 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;
}
#ifdef GAMEQC