public void WriteTestStruct(WriteStream stream, ref TestStruct testStruct) { stream.Bool(testStruct.bool_value); stream.Int(testStruct.int_value, -100, 100); stream.Uint(testStruct.uint_value, 100, 1000); stream.Bits(testStruct.bits_value, 23); }
public void WriteClientsPacket(WriteStream w, bool[] areConnected, ulong[] userIds, string[] userNames) { w.Bits((byte)ClientsInfo, 8); for (int i = 0; i < MaxClients; ++i) { w.Bool(areConnected[i]); if (!areConnected[i]) { continue; } w.Bits(userIds[i], 64); w.String(userNames[i]); } }
void WriteAvatar(WriteStream w, ref AvatarStateQuantized s) { w.Int(s.clientId, 0, MaxClients - 1); w.Int(s.headPositionX, MinPositionXZ, MaxPositionXZ); w.Int(s.headPositionY, MinPositionY, MaxPositionY); w.Int(s.headPositionZ, MinPositionXZ, MaxPositionXZ); w.Bits(s.headRotationLargest, 2); w.Bits(s.headRotationX, RotationBits); w.Bits(s.headRotationY, RotationBits); w.Bits(s.headRotationZ, RotationBits); w.Int(s.leftHandPositionX, MinPositionXZ, MaxPositionXZ); w.Int(s.leftHandPositionY, MinPositionY, MaxPositionY); w.Int(s.leftHandPositionZ, MinPositionXZ, MaxPositionXZ); w.Bits(s.leftHandRotationLargest, 2); w.Bits(s.leftHandRotationX, RotationBits); w.Bits(s.leftHandRotationY, RotationBits); w.Bits(s.leftHandRotationZ, RotationBits); w.Int(s.leftHandGripTrigger, MinTrigger, MaxTrigger); w.Int(s.leftHandIdTrigger, MinTrigger, MaxTrigger); w.Bool(s.isLeftHandPointing); w.Bool(s.areLeftHandThumbsUp); w.Bool(s.isLeftHandHoldingCube); if (s.isLeftHandHoldingCube) { w.Int(s.leftHandCubeId, 0, MaxCubes - 1); w.Bits(s.leftHandAuthoritySequence, 16); w.Bits(s.leftHandOwnershipSequence, 16); w.Int(s.leftHandCubeLocalPositionX, MinLocalPosition, MaxLocalPosition); w.Int(s.leftHandCubeLocalPositionY, MinLocalPosition, MaxLocalPosition); w.Int(s.leftHandCubeLocalPositionZ, MinLocalPosition, MaxLocalPosition); w.Bits(s.leftHandCubeLocalRotationLargest, 2); w.Bits(s.leftHandCubeLocalRotationX, RotationBits); w.Bits(s.leftHandCubeLocalRotationY, RotationBits); w.Bits(s.leftHandCubeLocalRotationZ, RotationBits); } w.Int(s.rightHandPositionX, MinPositionXZ, MaxPositionXZ); w.Int(s.rightHandPositionY, MinPositionY, MaxPositionY); w.Int(s.rightHandPositionZ, MinPositionXZ, MaxPositionXZ); w.Bits(s.rightHandRotationLargest, 2); w.Bits(s.rightHandRotationX, RotationBits); w.Bits(s.rightHandRotationY, RotationBits); w.Bits(s.rightHandRotationZ, RotationBits); w.Int(s.rightHandGripTrigger, MinTrigger, MaxTrigger); w.Int(s.rightHandIndexTrigger, MinTrigger, MaxTrigger); w.Bool(s.isRightHandPointing); w.Bool(s.areRightHandThumbsUp); w.Bool(s.isRightHandHoldingCube); if (s.isRightHandHoldingCube) { w.Int(s.rightHandCubeId, 0, MaxCubes - 1); w.Bits(s.rightHandAuthoritySequence, 16); w.Bits(s.rightHandOwnershipSequence, 16); w.Int(s.rightHandCubeLocalPositionX, MinLocalPosition, MaxLocalPosition); w.Int(s.rightHandCubeLocalPositionY, MinLocalPosition, MaxLocalPosition); w.Int(s.rightHandCubeLocalPositionZ, MinLocalPosition, MaxLocalPosition); w.Bits(s.rightHandCubeLocalRotationLargest, 2); w.Bits(s.rightHandCubeLocalRotationX, RotationBits); w.Bits(s.rightHandCubeLocalRotationY, RotationBits); w.Bits(s.rightHandCubeLocalRotationZ, RotationBits); } w.Int(s.voiceAmplitude, MinVoice, MaxVoice); }
void WriteAngularVelocityDelta(WriteStream w, int deltaX, int deltaY, int deltaZ) { Assert.IsTrue(deltaX >= -AngularVelocityDeltaMax); Assert.IsTrue(deltaX <= +AngularVelocityDeltaMax); Assert.IsTrue(deltaY >= -AngularVelocityDeltaMax); Assert.IsTrue(deltaY <= +AngularVelocityDeltaMax); Assert.IsTrue(deltaZ >= -AngularVelocityDeltaMax); Assert.IsTrue(deltaZ <= +AngularVelocityDeltaMax); var unsignedX = SignedToUnsigned(deltaX); var unsignedY = SignedToUnsigned(deltaY); var unsignedZ = SignedToUnsigned(deltaZ); var isSmallX = unsignedX <= AngularVelocityDeltaSmallThreshold; var isSmallY = unsignedY <= AngularVelocityDeltaSmallThreshold; var isSmallZ = unsignedZ <= AngularVelocityDeltaSmallThreshold; var isAllSmall = isSmallX && isSmallY && isSmallZ; w.Bool(isAllSmall); if (isAllSmall) { w.Bits(unsignedX, AngularVelocityDeltaSmallBits); w.Bits(unsignedY, AngularVelocityDeltaSmallBits); w.Bits(unsignedZ, AngularVelocityDeltaSmallBits); return; } w.Bool(isSmallX); if (isSmallX) { w.Bits(unsignedX, AngularVelocityDeltaSmallBits); } else { unsignedX -= AngularVelocityDeltaSmallThreshold; var isMediumX = unsignedX < AngularVelocityDeltaMediumThreshold; w.Bool(isMediumX); if (isMediumX) { w.Bits(unsignedX, AngularVelocityDeltaMediumBits); } else { w.Int(deltaX, -AngularVelocityDeltaMax, AngularVelocityDeltaMax); } } w.Bool(isSmallY); if (isSmallY) { w.Bits(unsignedY, AngularVelocityDeltaSmallBits); } else { unsignedY -= AngularVelocityDeltaSmallThreshold; var isMediumY = unsignedY < AngularVelocityDeltaMediumThreshold; w.Bool(isMediumY); if (isMediumY) { w.Bits(unsignedY, AngularVelocityDeltaMediumBits); } else { w.Int(deltaY, -AngularVelocityDeltaMax, AngularVelocityDeltaMax); } } w.Bool(isSmallZ); if (isSmallZ) { w.Bits(unsignedZ, AngularVelocityDeltaSmallBits); } else { unsignedZ -= AngularVelocityDeltaSmallThreshold; var isMediumZ = unsignedZ < AngularVelocityDeltaMediumThreshold; w.Bool(isMediumZ); if (isMediumZ) { w.Bits(unsignedZ, AngularVelocityDeltaMediumBits); } else { w.Int(deltaZ, -AngularVelocityDeltaMax, AngularVelocityDeltaMax); } } }
public void WriteUpdatePacket(WriteStream w, ref PacketHeader header, int avatarCount, AvatarStateQuantized[] avatars, int cubeCount, int[] cubeIds, bool[] notChanged, bool[] hasDelta, bool[] hasPerfectPrediction, bool[] hasPrediction, ushort[] baselineIds, CubeState[] cubes, CubeDelta[] deltas, CubeDelta[] predictions ) { w.Bits((byte)StateUpdate, 8); w.Bits(header.id, 16); w.Bits(header.ack, 16); w.Bits(header.ackBits, 32); w.Bits(header.frame, 32); w.Bits(header.resetId, 16); w.Float(header.timeOffset); w.Int(avatarCount, 0, MaxClients); for (int i = 0; i < avatarCount; ++i) { WriteAvatar(w, ref avatars[i]); } w.Int(cubeCount, 0, MaxStateUpdates); for (int i = 0; i < cubeCount; ++i) { w.Int(cubeIds[i], 0, MaxCubes - 1); #if DEBUG_DELTA_COMPRESSION write_int(stream, cubeDelta[i].absolute_position_x, PositionMinimumXZ, PositionMaximumXZ); write_int(stream, cubeDelta[i].absolute_position_y, PositionMinimumY, PositionMaximumY); write_int(stream, cubeDelta[i].absolute_position_z, PositionMinimumXZ, PositionMaximumXZ); #endif // #if DEBUG_DELTA_COMPRESSION w.Int(cubes[i].authorityId, 0, MaxAuthority - 1); w.Bits(cubes[i].authorityPacketId, 16); w.Bits(cubes[i].ownershipId, 16); w.Bool(notChanged[i]); if (notChanged[i]) { w.Bits(baselineIds[i], 16); continue; } w.Bool(hasPerfectPrediction[i]); if (hasPerfectPrediction[i]) { w.Bits(baselineIds[i], 16); w.Bits(cubes[i].rotationLargest, 2); w.Bits(cubes[i].rotationX, RotationBits); w.Bits(cubes[i].rotationY, RotationBits); w.Bits(cubes[i].rotationZ, RotationBits); continue; } w.Bool(hasPrediction[i]); if (hasPrediction[i]) { w.Bits(baselineIds[i], 16); w.Bool(cubes[i].isActive); WriteLinearVelocityDelta(w, predictions[i].linearVelocityX, predictions[i].linearVelocityY, predictions[i].linearVelocityZ); WriteAngularVelocityDelta(w, predictions[i].angularVelocityX, predictions[i].angularVelocityY, predictions[i].angularVelocityZ); WritePositionDelta(w, predictions[i].positionX, predictions[i].positionY, predictions[i].positionZ); w.Bits(cubes[i].rotationLargest, 2); w.Bits(cubes[i].rotationX, RotationBits); w.Bits(cubes[i].rotationY, RotationBits); w.Bits(cubes[i].rotationZ, RotationBits); continue; } w.Bool(hasDelta[i]); if (hasDelta[i]) { w.Bits(baselineIds[i], 16); w.Bool(cubes[i].isActive); WriteLinearVelocityDelta(w, deltas[i].linearVelocityX, deltas[i].linearVelocityY, deltas[i].linearVelocityZ); WriteAngularVelocityDelta(w, deltas[i].angularVelocityX, deltas[i].angularVelocityY, deltas[i].angularVelocityZ); WritePositionDelta(w, deltas[i].positionX, deltas[i].positionY, deltas[i].positionZ); w.Bits(cubes[i].rotationLargest, 2); w.Bits(cubes[i].rotationX, RotationBits); w.Bits(cubes[i].rotationY, RotationBits); w.Bits(cubes[i].rotationZ, RotationBits); continue; } w.Bool(cubes[i].isActive); w.Int(cubes[i].positionX, MinPositionXZ, MaxPositionXZ); w.Int(cubes[i].positionY, MinPositionY, MaxPositionY); w.Int(cubes[i].positionZ, MinPositionXZ, MaxPositionXZ); w.Bits(cubes[i].rotationLargest, 2); w.Bits(cubes[i].rotationX, RotationBits); w.Bits(cubes[i].rotationY, RotationBits); w.Bits(cubes[i].rotationZ, RotationBits); if (!cubes[i].isActive) { continue; } w.Int(cubes[i].linearVelocityX, LinearVelocityMinimum, LinearVelocityMaximum); w.Int(cubes[i].linearVelocityY, LinearVelocityMinimum, LinearVelocityMaximum); w.Int(cubes[i].linearVelocityZ, LinearVelocityMinimum, LinearVelocityMaximum); w.Int(cubes[i].angularVelocityX, AngularVelocityMinimum, AngularVelocityMaximum); w.Int(cubes[i].angularVelocityY, AngularVelocityMinimum, AngularVelocityMaximum); w.Int(cubes[i].angularVelocityZ, AngularVelocityMinimum, AngularVelocityMaximum); } }