// Copyright (c) Meta Platforms, Inc. and affiliates. #pragma once #include "Dom/JsonObject.h" #include "OculusXRAnchorTypes.h" #include "OculusXRRoomLayoutManagerComponent.h" TSharedPtr MRUKSerialize(const FString& String); void MRUKDeserialize(const FJsonValue& Value, FString& String); TSharedPtr MRUKSerialize(const FOculusXRUUID& UUID); void MRUKDeserialize(const FJsonValue& Value, FOculusXRUUID& UUID); TSharedPtr MRUKSerialize(const double& Number); void MRUKDeserialize(const FJsonValue& Value, double& Number); TSharedPtr MRUKSerialize(const FOculusXRRoomLayout& RoomLayout); void MRUKDeserialize(const FJsonValue& Value, FOculusXRRoomLayout& RoomLayout); template TSharedPtr MRUKSerialize(const UE::Math::TVector2& Vector) { return MakeShareable(new FJsonValueArray({ MakeShareable(new FJsonValueNumber(Vector.X)), MakeShareable(new FJsonValueNumber(Vector.Y)) })); } template void MRUKDeserialize(const FJsonValue& Value, UE::Math::TVector2& Vector) { if (auto Array = Value.AsArray(); Array.Num() == 2) { MRUKDeserialize(*Array[0], Vector.X); MRUKDeserialize(*Array[1], Vector.Y); } else { UE_LOG(LogJson, Error, TEXT("Json Array is of length %d (expected 2) when deserializing TVector2"), Array.Num()); Vector = UE::Math::TVector2::ZeroVector; } } template TSharedPtr MRUKSerialize(const UE::Math::TVector& Vector) { return MakeShareable(new FJsonValueArray({ MakeShareable(new FJsonValueNumber(Vector.X)), MakeShareable(new FJsonValueNumber(Vector.Y)), MakeShareable(new FJsonValueNumber(Vector.Z)) })); } template void MRUKDeserialize(const FJsonValue& Value, UE::Math::TVector& Vector) { auto Array = Value.AsArray(); if (Array.Num() == 3) { MRUKDeserialize(*Array[0], Vector.X); MRUKDeserialize(*Array[1], Vector.Y); MRUKDeserialize(*Array[2], Vector.Z); } else { UE_LOG(LogJson, Error, TEXT("Json Array is of length %d (expected 3) when deserializing TVector"), Array.Num()); Vector = UE::Math::TVector::ZeroVector; } } template TSharedPtr MRUKSerialize(const UE::Math::TRotator& Rotation) { return MakeShareable(new FJsonValueArray({ MakeShareable(new FJsonValueNumber(Rotation.Pitch)), MakeShareable(new FJsonValueNumber(Rotation.Yaw)), MakeShareable(new FJsonValueNumber(Rotation.Roll)) })); } template void MRUKDeserialize(const FJsonValue& Value, UE::Math::TRotator& Rotation) { auto Array = Value.AsArray(); if (Array.Num() == 3) { MRUKDeserialize(*Array[0], Rotation.Pitch); MRUKDeserialize(*Array[1], Rotation.Yaw); MRUKDeserialize(*Array[2], Rotation.Roll); } else { UE_LOG(LogJson, Error, TEXT("Json Array is of length %d (expected 3) when deserializing TRotator"), Array.Num()); Rotation = UE::Math::TRotator::ZeroRotator; } } template TSharedPtr MRUKSerialize(const UE::Math::TBox2& Box) { if (Box.bIsValid) { const TSharedRef JsonObject = MakeShareable(new FJsonObject); JsonObject->SetField(TEXT("Min"), MRUKSerialize(Box.Min)); JsonObject->SetField(TEXT("Max"), MRUKSerialize(Box.Max)); return MakeShareable(new FJsonValueObject(JsonObject)); } else { return MakeShareable(new FJsonValueNull()); } } template void MRUKDeserialize(const FJsonValue& Value, UE::Math::TBox2& Box) { if (Value.IsNull()) { Box.Init(); } else { const auto Object = Value.AsObject(); MRUKDeserialize(*Object->GetField(TEXT("Min")), Box.Min); MRUKDeserialize(*Object->GetField(TEXT("Max")), Box.Max); Box.bIsValid = true; } } template TSharedPtr MRUKSerialize(const UE::Math::TBox& Box) { if (Box.IsValid) { const TSharedRef JsonObject = MakeShareable(new FJsonObject); JsonObject->SetField(TEXT("Min"), MRUKSerialize(Box.Min)); JsonObject->SetField(TEXT("Max"), MRUKSerialize(Box.Max)); return MakeShareable(new FJsonValueObject(JsonObject)); } else { return MakeShareable(new FJsonValueNull()); } } template void MRUKDeserialize(const FJsonValue& Value, UE::Math::TBox& Box) { if (Value.IsNull()) { Box.Init(); } else { const auto Object = Value.AsObject(); MRUKDeserialize(*Object->GetField(TEXT("Min")), Box.Min); MRUKDeserialize(*Object->GetField(TEXT("Max")), Box.Max); Box.IsValid = 1; } } template TSharedPtr MRUKSerialize(const UE::Math::TTransform& Transform) { const TSharedRef JsonObject = MakeShareable(new FJsonObject); JsonObject->SetField(TEXT("Translation"), MRUKSerialize(Transform.GetTranslation())); JsonObject->SetField(TEXT("Rotation"), MRUKSerialize(Transform.Rotator())); JsonObject->SetField(TEXT("Scale"), MRUKSerialize(Transform.GetScale3D())); return MakeShareable(new FJsonValueObject(JsonObject)); } template void MRUKDeserialize(const FJsonValue& Value, UE::Math::TTransform& Transform) { const auto Object = Value.AsObject(); UE::Math::TVector Translation; UE::Math::TRotator Rotation; UE::Math::TVector Scale; MRUKDeserialize(*Object->GetField(TEXT("Translation")), Translation); MRUKDeserialize(*Object->GetField(TEXT("Rotation")), Rotation); MRUKDeserialize(*Object->GetField(TEXT("Scale")), Scale); Transform.SetComponents(UE::Math::TQuat(Rotation), Translation, Scale); } template TSharedPtr MRUKSerialize(const TArray& Array) { TArray> JsonArray; JsonArray.Reserve(Array.Num()); for (const auto& Item : Array) { JsonArray.Add(MRUKSerialize(Item)); } return MakeShareable(new FJsonValueArray(JsonArray)); } template void MRUKDeserialize(const FJsonValue& Value, TArray& OutArray) { auto Array = Value.AsArray(); OutArray.Empty(); OutArray.Reserve(Array.Num()); for (const auto& Item : Array) { T ItemDeserialized; MRUKDeserialize(*Item, ItemDeserialized); OutArray.Push(ItemDeserialized); } }