| 58 | } |
| 59 | |
| 60 | FORCE_INLINE static void Write(NetworkStream* stream, const Quaternion& data) |
| 61 | { |
| 62 | // Assumes rotation is normalized so W can be recalculated |
| 63 | Quaternion raw = data; |
| 64 | raw.Normalize(); |
| 65 | |
| 66 | // Compose flags that describe the data |
| 67 | uint8 flags = HasX | HasY | HasZ; |
| 68 | #define QUANTIZE_COMPONENT(comp, hasFlag, negativeFlag) \ |
| 69 | if (Math::IsZero(raw.comp)) \ |
| 70 | flags &= ~hasFlag; \ |
| 71 | else if (raw.comp < 0.0f) \ |
| 72 | flags |= negativeFlag |
| 73 | QUANTIZE_COMPONENT(X, HasX, NegativeX); |
| 74 | QUANTIZE_COMPONENT(Y, HasY, NegativeY); |
| 75 | QUANTIZE_COMPONENT(Z, HasZ, NegativeZ); |
| 76 | if (raw.W < 0.0f) |
| 77 | flags |= NegativeW; |
| 78 | #undef QUANTIZE_COMPONENT |
| 79 | |
| 80 | // Write data |
| 81 | stream->Write(flags); |
| 82 | #define WRITE_COMPONENT(comp, hasFlag) \ |
| 83 | if (flags & hasFlag) \ |
| 84 | { \ |
| 85 | const float norm = Math::Abs(raw.comp); \ |
| 86 | const uint16 packed = (uint16)(norm * MAX_uint16); \ |
| 87 | stream->Write(packed); \ |
| 88 | } |
| 89 | WRITE_COMPONENT(X, HasX); |
| 90 | WRITE_COMPONENT(Y, HasY); |
| 91 | WRITE_COMPONENT(Z, HasZ); |
| 92 | #undef WRITE_COMPONENT |
| 93 | } |
| 94 | }; |
| 95 | |
| 96 | NetworkStream::NetworkStream(const SpawnParams& params) |