diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index df044b299..952e648e6 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -2821,7 +2821,10 @@ void Variant::Inline() type = VariantType::Types::Vector4; } if (type != VariantType::Null) + { + ASSERT(sizeof(data) >= AsBlob.Length); Platform::MemoryCopy(data, AsBlob.Data, AsBlob.Length); + } } if (type != VariantType::Null) { @@ -2912,6 +2915,60 @@ void Variant::Inline() } } +void Variant::InvertInline() +{ + byte data[sizeof(Matrix)]; + switch (Type.Type) + { + case VariantType::Bool: + case VariantType::Int: + case VariantType::Uint: + case VariantType::Int64: + case VariantType::Uint64: + case VariantType::Float: + case VariantType::Double: + case VariantType::Pointer: + case VariantType::String: + case VariantType::Float2: + case VariantType::Float3: + case VariantType::Float4: + case VariantType::Color: +#if !USE_LARGE_WORLDS + case VariantType::BoundingSphere: + case VariantType::BoundingBox: + case VariantType::Ray: +#endif + case VariantType::Guid: + case VariantType::Quaternion: + case VariantType::Rectangle: + case VariantType::Int2: + case VariantType::Int3: + case VariantType::Int4: + case VariantType::Int16: + case VariantType::Uint16: + case VariantType::Double2: + case VariantType::Double3: + case VariantType::Double4: + static_assert(sizeof(data) >= sizeof(AsData), "Invalid memory size."); + Platform::MemoryCopy(data, AsData, sizeof(AsData)); + break; +#if USE_LARGE_WORLDS + case VariantType::BoundingSphere: + case VariantType::BoundingBox: + case VariantType::Ray: +#endif + case VariantType::Transform: + case VariantType::Matrix: + ASSERT(sizeof(data) >= AsBlob.Length); + Platform::MemoryCopy(data, AsBlob.Data, AsBlob.Length); + break; + default: + return; // Not used + } + SetType(VariantType(VariantType::Structure, InBuiltTypesTypeNames[Type.Type])); + CopyStructure(data); +} + Variant Variant::NewValue(const StringAnsiView& typeName) { Variant v; diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h index 8cc1e133b..adb49249f 100644 --- a/Source/Engine/Core/Types/Variant.h +++ b/Source/Engine/Core/Types/Variant.h @@ -372,6 +372,9 @@ public: // Inlines potential value type into in-built format (eg. Vector3 stored as Structure, or String stored as ManagedObject). void Inline(); + // Inverts the inlined value from in-built format into generic storage (eg. Float3 from inlined format into Structure). + void InvertInline(); + // Allocates the Variant of the specific type (eg. structure or object or value). static Variant NewValue(const StringAnsiView& typeName); diff --git a/Source/Engine/Visject/VisjectGraph.cpp b/Source/Engine/Visject/VisjectGraph.cpp index 1cee5d46e..4e94473f6 100644 --- a/Source/Engine/Visject/VisjectGraph.cpp +++ b/Source/Engine/Visject/VisjectGraph.cpp @@ -685,7 +685,7 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value) case 36: { // Get value with structure data - const Variant structureValue = eatBox(node, node->GetBox(0)->FirstConnection()); + Variant structureValue = eatBox(node, node->GetBox(0)->FirstConnection()); if (!node->GetBox(0)->HasConnection()) return; @@ -741,7 +741,9 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value) return; } const ScriptingType& type = typeHandle.GetType(); - if (structureValue.Type.Type != VariantType::Structure || StringUtils::Compare(typeNameAnsi.Get(), structureValue.Type.TypeName) != 0) + structureValue.InvertInline(); // Extract any Float3/Int32 into Structure type from inlined format + const ScriptingTypeHandle structureValueTypeHandle = Scripting::FindScriptingType(structureValue.Type.GetTypeName()); + if (structureValue.Type.Type != VariantType::Structure || typeHandle != structureValueTypeHandle) { OnError(node, box, String::Format(TEXT("Cannot unpack value of type {0} to structure of type {1}"), structureValue.Type, typeName)); return;