Announcement

Collapse
No announcement yet.

FVector_NetQuantize100 larger than FVector

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    FVector_NetQuantize100 larger than FVector

    Hey, I'm trying to compress some data for networking. I'm just about playing around with the FVector_NetQuantize100 to see the gain of the compression. Unfortunately the resulting binary is bigger than the binary of FVector.

    Code:
    void ACompressionTest::BeginPlay()
    {
        Super::BeginPlay();
    
        bool returnValue;
        TArray<uint8> binary;
        FMemoryWriter writer = FMemoryWriter(binary);
        FVector vector;
        writer << vector;
        UE_LOG(LogTemp, Error, TEXT("SizeOfVector: %d Bytes"), binary.Num()); // Num = 12
    
        TArray<uint8> binary2;
        FMemoryWriter writer2 = FMemoryWriter(binary2);
        FVector_NetQuantize100 vector100;
        vector100.NetSerialize(writer2, nullptr, returnValue);
        UE_LOG(LogTemp, Error, TEXT("SizeOfNetQuantize100: %d Bytes"), binary2.Num()); // Num = 16
    }
    As expected, the binary of FVector is 12 Bytes, as it consists of 3 floats that are 4 Bytes each. I would assume to get less bytes with FVector_NetQuantize100, but the result of the FVector_NetQuantize100ยด::NetSerialize was 16 Bytes. Am I doing something wrong?

    Using UE 4.16
    Last edited by Rumbleball; 10-27-2017, 05:12 PM.
    NodePrefabs | PluginBuilder | NotificationBackbone | WidgetBox | DebugWidget

    #2
    Right now you aren't initializing your vectors to anything, so at best they're all 0, or at worst, they're NANs/MAX_FLOAT which could be throwing off the quantize since it bases how many bits to write out per component based on the Log2 of the highest component.

    Try setting your vector to a "real" number (e.g. FVector TestVector(100.00, 200.0f, 300.0f) ) and see if that changes the numbers around.
    Able Ability System - A high performance, robust ability system for UE4. Now Available!

    Comment


      #3
      Thanks ExtraLifeMatt, did not think about that. Unfortunately it did not do it. Still 16 Bytes for FVector_NetQantize100.

      Code:
          bool returnValue;
          TArray<uint8> binary;
          FMemoryWriter writer = FMemoryWriter(binary);
          FVector vector(100.f);
          writer << vector;
          UE_LOG(LogTemp, Error, TEXT("SizeOfVector: %d Bytes"), binary.Num());
      
          TArray<uint8> binary2;
          FMemoryWriter writer2 = FMemoryWriter(binary2);
          FVector_NetQuantize100 vector100 = FVector_NetQuantize100(FVector(100.f));
          vector100.NetSerialize(writer2, nullptr, returnValue);
          UE_LOG(LogTemp, Error, TEXT("SizeOfNetQuantize100: %d Bytes"), binary2.Num());
      NodePrefabs | PluginBuilder | NotificationBackbone | WidgetBox | DebugWidget

      Comment


        #4
        Serialization of FVector_NetQuanitze100 happens in NetSerialize. It mainly calls SerializePackedVector<100, 30> which uses Read/WritePackedVector<100, 30> depending on Ar.IsSaving(). In WritePackedVector there are four calls to Ar.SerializeInt(). SerializeInt is virtual so the behaviour also depends on the type of archive actually being used. In your case this is FMemoryWriter which derives from FMemoryArchive which again derives from FArchive. Neither FMemoryWriter nor FMemoryArchive actually overrides SerializeInt so the base FArchive implementation is used which calls ByteOrderSerialize, which in turn calls Serialize. Serialize is another virtual function and this time it is actually overridden by FMemoryWriter. Eventually for each SerializeInt call, FMemoryWriter needs sizeof(uint32&) bytes added to the Bytes array if it wasn't large enough already. This explains the 16 bytes you've observed in your tests. Try another type of writer (e.g. FBitWriter along with GetNumBits) and see what the difference is.
        Last edited by UnrealEverything; 10-28-2017, 05:20 AM.
        Youtube - UnrealEverything

        Games:
        [Android] World of Bricks Released!

        [TUTORIAL] Edge Detection Post Process Effect using World Normals

        2B || !(2B)

        Comment


          #5
          Thanks UnrealEverything. Crazy structure. Made a struct with NetSerializer and replicated it. Placed a breakpoint in NetSerialize and the Debugger showed me that Unreal uses FNetBitWriter (which is a child of FBitWriter) for net serialization. Had a go with that.

          Code:
              bool returnValue;
              TArray<uint8> binary;
              FMemoryWriter writer = FMemoryWriter(binary);
              FVector vector(100.f);
              writer << vector;
              UE_LOG(LogTemp, Error, TEXT("SizeOfVector: %d Bytes"), binary.Num()); // 12 Bytes
          
          
              FNetBitWriter writer2 = FNetBitWriter(1000000); // init with max bits
              FVector_NetQuantize vector100 = FVector_NetQuantize(FVector(100.f)); 
              vector100.NetSerialize(writer2, nullptr, returnValue);
              UE_LOG(LogTemp, Error, TEXT("SizeOfNetQuantize100: %d bits"), writer2.GetNumBits()); // 28 Bits == 3,5 Bytes
          Pretty good results. Thanks for your help guys.

          Edit: Noticed I used FVector_NetQuantize in this test, NOT FVector_NetQuantize100.
          Last edited by Rumbleball; 11-14-2017, 09:21 AM.
          NodePrefabs | PluginBuilder | NotificationBackbone | WidgetBox | DebugWidget

          Comment

          Working...
          X