2
0
Эх сурвалжийг харах

Prevent cached world transform and parent data from being serialized in prefab (#2219)

Porting over @AMZN-daimini 's work to clean up unneeded data from prefabs by removing cached transform data from json serialization. This is done by writing an explicit json serializer for the Editor Transform component and opting not to store or load the cached Transform fields.

Tested by creating new prefabs, loading and as well as resaving old prefabs which included patches aimed at cached transform data.

Signed-off-by: sconel <[email protected]>
sconel 4 жил өмнө
parent
commit
b05984d4ca

+ 8 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp

@@ -17,6 +17,7 @@
 #include <AzCore/Math/Transform.h>
 #include <AzCore/RTTI/BehaviorContext.h>
 #include <AzCore/Serialization/EditContext.h>
+#include <AzCore/Serialization/Json/RegistrationContext.h>
 #include <AzCore/Serialization/SerializeContext.h>
 #include <AzFramework/API/ApplicationAPI.h>
 #include <AzFramework/Components/TransformComponent.h>
@@ -28,6 +29,7 @@
 #include <AzToolsFramework/Entity/EditorEntityContextBus.h>
 #include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
 #include <AzToolsFramework/ToolsComponents/TransformComponentBus.h>
+#include <AzToolsFramework/ToolsComponents/TransformComponentSerializer.h>
 #include <AzToolsFramework/ToolsComponents/EditorInspectorComponentBus.h>
 #include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
 #include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
@@ -1231,6 +1233,12 @@ namespace AzToolsFramework
                 // string-name differs from class-name to avoid collisions with the other "TransformComponent" (AzFramework::TransformComponent).
                 behaviorContext->Class<TransformComponent>("EditorTransformBus")->RequestBus("TransformBus");
             }
+
+            AZ::JsonRegistrationContext* jsonRegistration = azrtti_cast<AZ::JsonRegistrationContext*>(context);
+            if (jsonRegistration)
+            {
+                jsonRegistration->Serializer<JsonTransformComponentSerializer>()->HandlesType<TransformComponent>();
+            }
         }
 
         void TransformComponent::AddContextMenuActions(QMenu* menu)

+ 2 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h

@@ -38,6 +38,8 @@ namespace AzToolsFramework
             , private AZ::TransformNotificationBus::MultiHandler
             , private AZ::TransformHierarchyInformationBus::Handler
         {
+            friend class JsonTransformComponentSerializer;
+
         public:
             friend class TransformComponentFactory;
 

+ 218 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponentSerializer.cpp

@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzToolsFramework/ToolsComponents/TransformComponentSerializer.h>
+#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
+
+namespace AzToolsFramework
+{
+    namespace Components
+    {
+        AZ_CLASS_ALLOCATOR_IMPL(JsonTransformComponentSerializer, AZ::SystemAllocator, 0);
+
+        AZ::JsonSerializationResult::Result JsonTransformComponentSerializer::Load(
+            void* outputValue, [[maybe_unused]] const AZ::Uuid& outputValueTypeId, const rapidjson::Value& inputValue, AZ::JsonDeserializerContext& context)
+        {
+            namespace JSR = AZ::JsonSerializationResult;
+
+            AZ_Assert(
+                azrtti_typeid<TransformComponent>() == outputValueTypeId, "Unable to deserialize TransformComponent from json because the provided type is %s.",
+                outputValueTypeId.ToString<AZStd::string>().c_str());
+
+            TransformComponent* transformComponentInstance = reinterpret_cast<TransformComponent*>(outputValue);
+            AZ_Assert(transformComponentInstance, "Output value for JsonTransformComponentSerializer can't be null.");
+
+            JSR::ResultCode result(JSR::Tasks::ReadField);
+            {
+                JSR::ResultCode componentIdLoadResult = ContinueLoadingFromJsonObjectField(
+                    &transformComponentInstance->m_id, azrtti_typeid<decltype(transformComponentInstance->m_id)>(),
+                    inputValue, "Id", context);
+
+                result.Combine(componentIdLoadResult);
+            }
+
+            {
+                JSR::ResultCode parentEntityIdLoadResult = ContinueLoadingFromJsonObjectField(
+                    &transformComponentInstance->m_parentEntityId, azrtti_typeid<decltype(transformComponentInstance->m_parentEntityId)>(),
+                    inputValue, "Parent Entity", context);
+
+                result.Combine(parentEntityIdLoadResult);
+            }
+
+            {
+                JSR::ResultCode transformDataLoadResult = ContinueLoadingFromJsonObjectField(
+                    &transformComponentInstance->m_editorTransform, azrtti_typeid<decltype(transformComponentInstance->m_editorTransform)>(),
+                    inputValue, "Transform Data", context);
+
+                result.Combine(transformDataLoadResult);
+            }
+
+            {
+                JSR::ResultCode parentActivationTransformModeLoadResult = ContinueLoadingFromJsonObjectField(
+                    &transformComponentInstance->m_parentActivationTransformMode, azrtti_typeid<decltype(transformComponentInstance->m_parentActivationTransformMode)>(),
+                    inputValue, "Parent Activation Transform Mode", context);
+
+                result.Combine(parentActivationTransformModeLoadResult);
+            }
+
+            {
+                JSR::ResultCode isStaticLoadResult = ContinueLoadingFromJsonObjectField(
+                    &transformComponentInstance->m_isStatic, azrtti_typeid<decltype(transformComponentInstance->m_isStatic)>(),
+                    inputValue, "IsStatic", context);
+
+                result.Combine(isStaticLoadResult);
+            }
+
+            {
+                JSR::ResultCode netSyncEnabledLoadResult = ContinueLoadingFromJsonObjectField(
+                    &transformComponentInstance->m_netSyncEnabled, azrtti_typeid<decltype(transformComponentInstance->m_netSyncEnabled)>(),
+                    inputValue, "Sync Enabled", context);
+
+                result.Combine(netSyncEnabledLoadResult);
+            }
+
+            {
+                JSR::ResultCode interpolatePositionLoadResult = ContinueLoadingFromJsonObjectField(
+                    &transformComponentInstance->m_interpolatePosition, azrtti_typeid<decltype(transformComponentInstance->m_interpolatePosition)>(),
+                    inputValue, "InterpolatePosition", context);
+
+                result.Combine(interpolatePositionLoadResult);
+            }
+
+            {
+                JSR::ResultCode interpolateRotationLoadResult = ContinueLoadingFromJsonObjectField(
+                    &transformComponentInstance->m_interpolateRotation, azrtti_typeid<decltype(transformComponentInstance->m_interpolateRotation)>(),
+                    inputValue, "InterpolateRotation", context);
+
+                result.Combine(interpolateRotationLoadResult);
+            }
+
+            return context.Report(
+                result,
+                result.GetProcessing() != JSR::Processing::Halted ? "Successfully loaded TransformComponent information."
+                                                                  : "Failed to load TransformComponent information.");
+        }
+
+        AZ::JsonSerializationResult::Result JsonTransformComponentSerializer::Store(
+            rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const AZ::Uuid& valueTypeId,
+            AZ::JsonSerializerContext& context)
+        {
+            namespace JSR = AZ::JsonSerializationResult;
+
+            AZ_Assert(
+                azrtti_typeid<TransformComponent>() == valueTypeId, "Unable to Serialize TransformComponent because the provided type is %s.",
+                valueTypeId.ToString<AZStd::string>().c_str());
+
+            const TransformComponent* transformComponentInstance = reinterpret_cast<const TransformComponent*>(inputValue);
+            AZ_Assert(transformComponentInstance, "Input value for JsonTransformComponentSerializer can't be null.");
+            const TransformComponent* defaultTransformComponentInstance = reinterpret_cast<const TransformComponent*>(defaultValue);
+
+            JSR::ResultCode result(JSR::Tasks::WriteValue);
+            {
+                AZ::ScopedContextPath subPathName(context, "m_id");
+                const AZ::ComponentId* componentId = &transformComponentInstance->m_id;
+                const AZ::ComponentId* defaultComponentId = defaultTransformComponentInstance ? &defaultTransformComponentInstance->m_id : nullptr;
+
+                JSR::ResultCode resultComponentId = ContinueStoringToJsonObjectField(
+                    outputValue, "Id", componentId, defaultComponentId, azrtti_typeid<decltype(transformComponentInstance->m_id)>(), context);
+
+                result.Combine(resultComponentId);
+            }
+
+            {
+                AZ::ScopedContextPath subPathName(context, "m_parentEntityId");
+                const AZ::EntityId* parentEntityId = &transformComponentInstance->m_parentEntityId;
+                const AZ::EntityId* defaultParentEntityId = defaultTransformComponentInstance ? &defaultTransformComponentInstance->m_parentEntityId : nullptr;
+
+                JSR::ResultCode resultParentEntityId = ContinueStoringToJsonObjectField(
+                    outputValue, "Parent Entity", parentEntityId, defaultParentEntityId, azrtti_typeid<decltype(transformComponentInstance->m_parentEntityId)>(), context);
+
+                result.Combine(resultParentEntityId);
+            }
+
+            {
+                AZ::ScopedContextPath subPathName(context, "m_editorTransform");
+                const EditorTransform* editorTransform = &transformComponentInstance->m_editorTransform;
+                const EditorTransform* defaultEditorTransform =
+                    defaultTransformComponentInstance ? &defaultTransformComponentInstance->m_editorTransform : nullptr;
+
+                JSR::ResultCode resultEditorTransform = ContinueStoringToJsonObjectField(
+                    outputValue, "Transform Data", editorTransform, defaultEditorTransform,
+                    azrtti_typeid<decltype(transformComponentInstance->m_editorTransform)>(), context);
+
+                result.Combine(resultEditorTransform);
+            }
+
+            {
+                AZ::ScopedContextPath subPathName(context, "m_parentActivationTransformMode");
+                const AZ::TransformConfig::ParentActivationTransformMode* parentActivationTransformMode = &transformComponentInstance->m_parentActivationTransformMode;
+                const AZ::TransformConfig::ParentActivationTransformMode* defaultParentActivationTransformMode =
+                    defaultTransformComponentInstance ? &defaultTransformComponentInstance->m_parentActivationTransformMode : nullptr;
+
+                JSR::ResultCode resultParentActivationTransformMode = ContinueStoringToJsonObjectField(
+                    outputValue, "Parent Activation Transform Mode", parentActivationTransformMode, defaultParentActivationTransformMode,
+                    azrtti_typeid<decltype(transformComponentInstance->m_parentActivationTransformMode)>(), context);
+
+                result.Combine(resultParentActivationTransformMode);
+            }
+
+            {
+                AZ::ScopedContextPath subPathName(context, "m_isStatic");
+                const bool* isStatic = &transformComponentInstance->m_isStatic;
+                const bool* defaultIsStatic = defaultTransformComponentInstance ? &defaultTransformComponentInstance->m_isStatic : nullptr;
+
+                JSR::ResultCode resultIsStatic = ContinueStoringToJsonObjectField(
+                    outputValue, "IsStatic", isStatic, defaultIsStatic,
+                    azrtti_typeid<decltype(transformComponentInstance->m_isStatic)>(), context);
+
+                result.Combine(resultIsStatic);
+            }
+
+            {
+                AZ::ScopedContextPath subPathName(context, "m_netSyncEnabled");
+                const bool* netSyncEnabled = &transformComponentInstance->m_netSyncEnabled;
+                const bool* defaultNetSyncEnabled = defaultTransformComponentInstance ? &defaultTransformComponentInstance->m_netSyncEnabled : nullptr;
+
+                JSR::ResultCode resultNetSyncEnabled = ContinueStoringToJsonObjectField(
+                    outputValue, "Sync Enabled", netSyncEnabled, defaultNetSyncEnabled, azrtti_typeid<decltype(transformComponentInstance->m_netSyncEnabled)>(),
+                    context);
+
+                result.Combine(resultNetSyncEnabled);
+            }
+
+            {
+                AZ::ScopedContextPath subPathName(context, "m_interpolatePosition");
+                const AZ::InterpolationMode* interpolatePosition = &transformComponentInstance->m_interpolatePosition;
+                const AZ::InterpolationMode* defaultInterpolatePosition = defaultTransformComponentInstance ? &defaultTransformComponentInstance->m_interpolatePosition : nullptr;
+
+                JSR::ResultCode resultInterpolatePosition = ContinueStoringToJsonObjectField(
+                    outputValue, "InterpolatePosition", interpolatePosition, defaultInterpolatePosition, azrtti_typeid<decltype(transformComponentInstance->m_interpolatePosition)>(),
+                    context);
+
+                result.Combine(resultInterpolatePosition);
+            }
+
+            {
+                AZ::ScopedContextPath subPathName(context, "m_interpolateRotation");
+                const AZ::InterpolationMode* interpolateRotation = &transformComponentInstance->m_interpolateRotation;
+                const AZ::InterpolationMode* defaultInterpolateRotation = defaultTransformComponentInstance ? &defaultTransformComponentInstance->m_interpolateRotation : nullptr;
+
+                JSR::ResultCode resultInterpolateRotation = ContinueStoringToJsonObjectField(
+                    outputValue, "InterpolateRotation", interpolateRotation, defaultInterpolateRotation, azrtti_typeid<decltype(transformComponentInstance->m_interpolateRotation)>(),
+                    context);
+
+                result.Combine(resultInterpolateRotation);
+            }
+
+            return context.Report(
+                result,
+                result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored TransformComponent information."
+                                                                  : "Failed to store TransformComponent information.");
+        }
+
+    } // namespace Components
+} // namespace AzToolsFramework

+ 34 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponentSerializer.h

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Memory/Memory.h>
+#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
+
+namespace AzToolsFramework
+{
+    namespace Components
+    {
+        class JsonTransformComponentSerializer
+            : public AZ::BaseJsonSerializer
+        {
+        public:
+            AZ_RTTI(JsonTransformComponentSerializer, "{F8BA0E22-1DD5-4BCC-A371-0988F8815CF4}", BaseJsonSerializer);
+            AZ_CLASS_ALLOCATOR_DECL;
+
+            AZ::JsonSerializationResult::Result Load(
+                void* outputValue, const AZ::Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
+                AZ::JsonDeserializerContext& context) override;
+
+            AZ::JsonSerializationResult::Result Store(
+                rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const AZ::Uuid& valueTypeId,
+                AZ::JsonSerializerContext& context) override;
+        };
+
+    } // namespace Components
+} // namespace AzToolsFramework

+ 2 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake

@@ -289,6 +289,8 @@ set(FILES
     ToolsComponents/TransformComponent.h
     ToolsComponents/TransformComponent.cpp
     ToolsComponents/TransformComponentBus.h
+    ToolsComponents/TransformComponentSerializer.h
+    ToolsComponents/TransformComponentSerializer.cpp
     ToolsComponents/ScriptEditorComponent.cpp
     ToolsComponents/ScriptEditorComponent.h
     ToolsComponents/ToolsAssetCatalogComponent.cpp