diff --git a/Engine/source/core/stream/bitStream.cpp b/Engine/source/core/stream/bitStream.cpp index c5ec18de5..eb86c6860 100644 --- a/Engine/source/core/stream/bitStream.cpp +++ b/Engine/source/core/stream/bitStream.cpp @@ -344,22 +344,52 @@ void BitStream::writeInt(S32 val, S32 bitCount) void BitStream::writeFloat(F32 f, S32 bitCount) { - writeInt((S32)(f * ((1 << bitCount) - 1)), bitCount); + auto maxInt = (1U << bitCount) - 1; + U32 i; + if (f < POINT_EPSILON) + { + // Special case: <= 0 serializes to 0 + i = 0.0f; + } + else if (f == 0.5) + { + // Special case: 0.5 serializes to maxInt / 2 + 1 + i = maxInt / 2 + 1; + } + else if (f > (1.0f- POINT_EPSILON)) + { + // Special case: >= 1 serializes to maxInt + i = maxInt; + } + else + { + // Serialize normally but round the number + i = static_cast(roundf(f * maxInt)); + } + writeInt(i, bitCount); } F32 BitStream::readFloat(S32 bitCount) { - return readInt(bitCount) / F32((1 << bitCount) - 1); + auto maxInt = (1U << bitCount) - 1; + auto i = static_cast(readInt(bitCount)); + if (i == 0) + return 0; + if (i == maxInt / 2 + 1) + return 0.5; + if (i == maxInt) + return 1; + return i / static_cast(maxInt); } void BitStream::writeSignedFloat(F32 f, S32 bitCount) { - writeInt((S32)(((f + 1) * .5) * ((1 << bitCount) - 1)), bitCount); + writeFloat((f + 1) / 2, bitCount); } F32 BitStream::readSignedFloat(S32 bitCount) { - return readInt(bitCount) * 2 / F32((1 << bitCount) - 1) - 1.0f; + return readFloat(bitCount) * 2 - 1; } void BitStream::writeSignedInt(S32 value, S32 bitCount)