diff --git a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs index 17999d772..e89c80372 100644 --- a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs +++ b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs @@ -33,7 +33,12 @@ namespace FlaxEditor.CustomEditors.Editors [CustomEditor(typeof(Asset)), DefaultEditor] public class AssetRefEditor : CustomEditor { - private AssetPicker _picker; + /// + /// The asset picker used to get a reference to an asset. + /// + public AssetPicker Picker; + + private bool _isRefreshing; private ScriptType _valueType; /// @@ -44,7 +49,7 @@ namespace FlaxEditor.CustomEditors.Editors { if (HasDifferentTypes) return; - _picker = layout.Custom().CustomControl; + Picker = layout.Custom().CustomControl; _valueType = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]); var assetType = _valueType; @@ -66,7 +71,7 @@ namespace FlaxEditor.CustomEditors.Editors { // Generic file picker assetType = ScriptType.Null; - _picker.FileExtension = assetReference.TypeName; + Picker.FileExtension = assetReference.TypeName; } else { @@ -78,23 +83,25 @@ namespace FlaxEditor.CustomEditors.Editors } } - _picker.AssetType = assetType; - _picker.Height = height; - _picker.SelectedItemChanged += OnSelectedItemChanged; + Picker.AssetType = assetType; + Picker.Height = height; + Picker.SelectedItemChanged += OnSelectedItemChanged; } private void OnSelectedItemChanged() { + if (_isRefreshing) + return; if (typeof(AssetItem).IsAssignableFrom(_valueType.Type)) - SetValue(_picker.SelectedItem); + SetValue(Picker.SelectedItem); else if (_valueType.Type == typeof(Guid)) - SetValue(_picker.SelectedID); + SetValue(Picker.SelectedID); else if (_valueType.Type == typeof(SceneReference)) - SetValue(new SceneReference(_picker.SelectedID)); + SetValue(new SceneReference(Picker.SelectedID)); else if (_valueType.Type == typeof(string)) - SetValue(_picker.SelectedPath); + SetValue(Picker.SelectedPath); else - SetValue(_picker.SelectedAsset); + SetValue(Picker.SelectedAsset); } /// @@ -104,16 +111,18 @@ namespace FlaxEditor.CustomEditors.Editors if (!HasDifferentValues) { + _isRefreshing = true; if (Values[0] is AssetItem assetItem) - _picker.SelectedItem = assetItem; + Picker.SelectedItem = assetItem; else if (Values[0] is Guid guid) - _picker.SelectedID = guid; + Picker.SelectedID = guid; else if (Values[0] is SceneReference sceneAsset) - _picker.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID); + Picker.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID); else if (Values[0] is string path) - _picker.SelectedPath = path; + Picker.SelectedPath = path; else - _picker.SelectedAsset = Values[0] as Asset; + Picker.SelectedAsset = Values[0] as Asset; + _isRefreshing = false; } } } diff --git a/Source/Editor/CustomEditors/Editors/ModelInstanceEntryEditor.cs b/Source/Editor/CustomEditors/Editors/ModelInstanceEntryEditor.cs index a08a254d4..277f9ecb0 100644 --- a/Source/Editor/CustomEditors/Editors/ModelInstanceEntryEditor.cs +++ b/Source/Editor/CustomEditors/Editors/ModelInstanceEntryEditor.cs @@ -1,6 +1,8 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using FlaxEditor.CustomEditors.Elements; +using FlaxEditor.CustomEditors.GUI; +using FlaxEditor.Scripting; using FlaxEngine; namespace FlaxEditor.CustomEditors.Editors @@ -13,6 +15,11 @@ namespace FlaxEditor.CustomEditors.Editors { private GroupElement _group; private bool _updateName; + private int _entryIndex; + private bool _isRefreshing; + private MaterialBase _material; + private ModelInstanceActor _modelInstance; + private AssetRefEditor _materialEditor; /// public override void Initialize(LayoutElementsContainer layout) @@ -21,47 +28,122 @@ namespace FlaxEditor.CustomEditors.Editors var group = layout.Group("Entry"); _group = group; + if (ParentEditor == null) + return; + var entry = (ModelInstanceEntry)Values[0]; + var entryIndex = ParentEditor.ChildrenEditors.IndexOf(this); + var materialLabel = new PropertyNameLabel("Material"); + materialLabel.TooltipText = "The mesh surface material used for the rendering."; + if (ParentEditor.ParentEditor?.Values[0] is ModelInstanceActor modelInstance) + { + _entryIndex = entryIndex; + _modelInstance = modelInstance; + var slots = modelInstance.MaterialSlots; + if (entry.Material == slots[entryIndex].Material) + { + // Ensure that entry with default material set is set back to null + modelInstance.SetMaterial(entryIndex, null); + } + _material = modelInstance.GetMaterial(entryIndex); + var defaultValue = GPUDevice.Instance.DefaultMaterial; + if (slots[entryIndex].Material) + { + // Use default value set on asset (eg. Model Asset) + defaultValue = slots[entryIndex].Material; + } + + // Create material picker + var materialValue = new CustomValueContainer(new ScriptType(typeof(MaterialBase)), _material, (instance, index) => _material, (instance, index, value) => _material = value as MaterialBase); + var materialEditor = (AssetRefEditor)_group.Property(materialLabel, materialValue); + materialEditor.Values.SetDefaultValue(defaultValue); + materialEditor.RefreshDefaultValue(); + materialEditor.Picker.SelectedItemChanged += OnSelectedMaterialChanged; + _materialEditor = materialEditor; + } + base.Initialize(group); } + private void OnSelectedMaterialChanged() + { + if (_isRefreshing) + return; + _isRefreshing = true; + var slots = _modelInstance.MaterialSlots; + var material = _materialEditor.Picker.SelectedAsset as MaterialBase; + var defaultMaterial = GPUDevice.Instance.DefaultMaterial; + var value = (ModelInstanceEntry)Values[0]; + var prevMaterial = value.Material; + if (!material) + { + // Fallback to default material + _materialEditor.Picker.SelectedAsset = defaultMaterial; + value.Material = defaultMaterial; + } + else if (material == slots[_entryIndex].Material) + { + // Asset default material + value.Material = null; + } + else if (material == defaultMaterial && !slots[_entryIndex].Material) + { + // Default material while asset has no set as well + value.Material = null; + } + else + { + // Custom material + value.Material = material; + } + if (prevMaterial != value.Material) + SetValue(value); + _isRefreshing = false; + } + + /// + protected override void SpawnProperty(LayoutElementsContainer itemLayout, ValueContainer itemValues, ItemInfo item) + { + // Skip material member as it is overridden + if (item.Info.Name == "Material" && _materialEditor != null) + return; + base.SpawnProperty(itemLayout, itemValues, item); + } + /// public override void Refresh() { + // Update panel title to match material slot name if (_updateName && _group != null && ParentEditor?.ParentEditor != null && ParentEditor.ParentEditor.Values.Count > 0) { var entryIndex = ParentEditor.ChildrenEditors.IndexOf(this); - if (ParentEditor.ParentEditor.Values[0] is StaticModel staticModel) + if (ParentEditor.ParentEditor.Values[0] is ModelInstanceActor modelInstance) { - var model = staticModel.Model; - if (model && model.IsLoaded) + var slots = modelInstance.MaterialSlots; + if (slots != null && slots.Length > entryIndex) { - var slots = model.MaterialSlots; - if (slots != null && slots.Length > entryIndex) - { - _group.Panel.HeaderText = "Entry " + slots[entryIndex].Name; - _updateName = false; - } - } - } - else if (ParentEditor.ParentEditor.Values[0] is AnimatedModel animatedModel) - { - var model = animatedModel.SkinnedModel; - if (model && model.IsLoaded) - { - var slots = model.MaterialSlots; - if (slots != null && slots.Length > entryIndex) - { - _group.Panel.HeaderText = "Entry " + slots[entryIndex].Name; - _updateName = false; - } + _updateName = false; + _group.Panel.HeaderText = "Entry " + slots[entryIndex].Name; } } } + // Refresh currently selected material + _material = _modelInstance.GetMaterial(_entryIndex); + base.Refresh(); } + + /// + protected override void Deinitialize() + { + _material = null; + _modelInstance = null; + _materialEditor = null; + + base.Deinitialize(); + } } } diff --git a/Source/Editor/Gizmo/SelectionOutline.cs b/Source/Editor/Gizmo/SelectionOutline.cs index ccc4bdd27..1374c7247 100644 --- a/Source/Editor/Gizmo/SelectionOutline.cs +++ b/Source/Editor/Gizmo/SelectionOutline.cs @@ -178,6 +178,8 @@ namespace FlaxEditor.Gizmo if (selection[i] is ActorNode actorNode && actorNode.Actor != null) CollectActors(actorNode.Actor); } + if (_actors.Count == 0) + return; // Render selected objects depth Renderer.DrawSceneDepth(context, task, customDepth, _actors); diff --git a/Source/Engine/Content/Assets/MaterialBase.h b/Source/Engine/Content/Assets/MaterialBase.h index bca70b6da..070347348 100644 --- a/Source/Engine/Content/Assets/MaterialBase.h +++ b/Source/Engine/Content/Assets/MaterialBase.h @@ -27,7 +27,6 @@ public: /// /// Returns true if material is an material instance. /// - /// True if it's a material instance, otherwise false. virtual bool IsMaterialInstance() const = 0; public: diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index 8232d415f..973e494f1 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -2796,6 +2796,122 @@ String Variant::ToString() const } } +void Variant::Inline() +{ + VariantType::Types type = VariantType::Null; + byte data[sizeof(Matrix)]; + if (Type.Type == VariantType::Structure && AsBlob.Data && AsBlob.Length <= sizeof(Matrix)) + { + for (int32 i = 2; i < VariantType::MAX; i++) + { + if (StringUtils::Compare(Type.TypeName, InBuiltTypesTypeNames[i]) == 0) + { + type = (VariantType::Types)i; + break; + } + } + if (type == VariantType::Null) + { + // Aliases + if (StringUtils::Compare(Type.TypeName, "FlaxEngine.Vector2") == 0) + type = VariantType::Types::Vector2; + else if (StringUtils::Compare(Type.TypeName, "FlaxEngine.Vector3") == 0) + type = VariantType::Types::Vector3; + else if (StringUtils::Compare(Type.TypeName, "FlaxEngine.Vector4") == 0) + type = VariantType::Types::Vector4; + } + if (type != VariantType::Null) + Platform::MemoryCopy(data, AsBlob.Data, AsBlob.Length); + } + if (type != VariantType::Null) + { + switch (type) + { + case VariantType::Bool: + *this = *(bool*)data; + break; + case VariantType::Int: + *this = *(int32*)data; + break; + case VariantType::Uint: + *this = *(uint32*)data; + break; + case VariantType::Int64: + *this = *(int64*)data; + break; + case VariantType::Uint64: + *this = *(uint64*)data; + break; + case VariantType::Float: + *this = *(float*)data; + break; + case VariantType::Double: + *this = *(double*)data; + break; + case VariantType::Float2: + *this = *(Float2*)data; + break; + case VariantType::Float3: + *this = *(Float3*)data; + break; + case VariantType::Float4: + *this = *(Float4*)data; + break; + case VariantType::Color: + *this = *(Color*)data; + break; + case VariantType::Guid: + *this = *(Guid*)data; + break; + case VariantType::BoundingBox: + *this = Variant(*(BoundingBox*)data); + break; + case VariantType::BoundingSphere: + *this = *(BoundingSphere*)data; + break; + case VariantType::Quaternion: + *this = *(Quaternion*)data; + break; + case VariantType::Transform: + *this = Variant(*(Transform*)data); + break; + case VariantType::Rectangle: + *this = *(Rectangle*)data; + break; + case VariantType::Ray: + *this = Variant(*(Ray*)data); + break; + case VariantType::Matrix: + *this = Variant(*(Matrix*)data); + break; + case VariantType::Int2: + *this = *(Int2*)data; + break; + case VariantType::Int3: + *this = *(Int3*)data; + break; + case VariantType::Int4: + *this = *(Int4*)data; + break; + case VariantType::Int16: + *this = *(int16*)data; + break; + case VariantType::Uint16: + *this = *(uint16*)data; + break; + case VariantType::Double2: + *this = *(Double2*)data; + break; + case VariantType::Double3: + *this = *(Double3*)data; + break; + case VariantType::Double4: + *this = *(Double4*)data; + break; + } + } +} + bool Variant::CanCast(const Variant& v, const VariantType& to) { if (v.Type == to) @@ -3682,6 +3798,7 @@ void Variant::AllocStructure() const ScriptingType& type = typeHandle.GetType(); AsBlob.Length = type.Size; AsBlob.Data = Allocator::Allocate(AsBlob.Length); + Platform::MemoryClear(AsBlob.Data, AsBlob.Length); type.Struct.Ctor(AsBlob.Data); } else if (typeName == "System.Int16" || typeName == "System.UInt16") diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h index 7745307c3..9776c8e0b 100644 --- a/Source/Engine/Core/Types/Variant.h +++ b/Source/Engine/Core/Types/Variant.h @@ -359,6 +359,9 @@ public: void SetAsset(Asset* asset); String ToString() const; + // Inlines potential value type into in-built format (eg. Vector3 stored as Structure, or String stored as ManagedObject). + void Inline(); + FORCE_INLINE Variant Cast(const VariantType& to) const { return Cast(*this, to); diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index 17b8b73af..57454ad1e 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -244,7 +244,25 @@ namespace FlaxEngine.Interop @namespace = NativeAllocStringAnsi(type.Namespace ?? ""), typeAttributes = (uint)type.Attributes, }; - *assemblyHandle = GetAssemblyHandle(type.Assembly); + + Assembly assembly = null; + if (type.IsGenericType && !type.Assembly.IsCollectible) + { + // The owning assembly of a generic type with type arguments referencing + // collectible assemblies must be one of the collectible assemblies. + foreach (var genericType in type.GetGenericArguments()) + { + if (genericType.Assembly.IsCollectible) + { + assembly = genericType.Assembly; + break; + } + } + } + if (assembly == null) + assembly = type.Assembly; + + *assemblyHandle = GetAssemblyHandle(assembly); } [UnmanagedCallersOnly] diff --git a/Source/Engine/Graphics/GPUDevice.h b/Source/Engine/Graphics/GPUDevice.h index 4dbcf6d06..422e554a0 100644 --- a/Source/Engine/Graphics/GPUDevice.h +++ b/Source/Engine/Graphics/GPUDevice.h @@ -238,7 +238,7 @@ public: /// /// Gets the default material. /// - MaterialBase* GetDefaultMaterial() const; + API_PROPERTY() MaterialBase* GetDefaultMaterial() const; /// /// Gets the default material (Deformable domain). diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index 5a7150bac..2ff681628 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -1066,6 +1066,14 @@ void AnimatedModel::Deserialize(DeserializeStream& stream, ISerializeModifier* m DrawModes |= DrawPass::GlobalSurfaceAtlas; } +const Span AnimatedModel::GetMaterialSlots() const +{ + const auto model = SkinnedModel.Get(); + if (model && !model->WaitForLoaded()) + return ToSpan(model->MaterialSlots); + return Span(); +} + MaterialBase* AnimatedModel::GetMaterial(int32 entryIndex) { if (SkinnedModel) diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h index 8fe85d114..d070d99a2 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.h +++ b/Source/Engine/Level/Actors/AnimatedModel.h @@ -384,6 +384,7 @@ public: bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override; void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; + const Span GetMaterialSlots() const override; MaterialBase* GetMaterial(int32 entryIndex) override; bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) override; bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override; diff --git a/Source/Engine/Level/Actors/ModelInstanceActor.h b/Source/Engine/Level/Actors/ModelInstanceActor.h index 346a13b0d..e92b7cba6 100644 --- a/Source/Engine/Level/Actors/ModelInstanceActor.h +++ b/Source/Engine/Level/Actors/ModelInstanceActor.h @@ -52,6 +52,11 @@ public: /// API_PROPERTY() void SetEntries(const Array& value); + /// + /// Gets the material slots array set on the asset (eg. model or skinned model asset). + /// + API_PROPERTY(Sealed) virtual const Span GetMaterialSlots() const = 0; + /// /// Gets the material used to draw the meshes which are assigned to that slot (set in Entries or model's default). /// diff --git a/Source/Engine/Level/Actors/SplineModel.cpp b/Source/Engine/Level/Actors/SplineModel.cpp index 44f0676d4..2640bd84b 100644 --- a/Source/Engine/Level/Actors/SplineModel.cpp +++ b/Source/Engine/Level/Actors/SplineModel.cpp @@ -341,6 +341,14 @@ void SplineModel::OnParentChanged() OnSplineUpdated(); } +const Span SplineModel::GetMaterialSlots() const +{ + const auto model = Model.Get(); + if (model && !model->WaitForLoaded()) + return ToSpan(model->MaterialSlots); + return Span(); +} + MaterialBase* SplineModel::GetMaterial(int32 entryIndex) { if (Model) diff --git a/Source/Engine/Level/Actors/SplineModel.h b/Source/Engine/Level/Actors/SplineModel.h index 238e1cc5a..654268ec6 100644 --- a/Source/Engine/Level/Actors/SplineModel.h +++ b/Source/Engine/Level/Actors/SplineModel.h @@ -115,6 +115,7 @@ public: void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; void OnParentChanged() override; + const Span GetMaterialSlots() const override; MaterialBase* GetMaterial(int32 entryIndex) override; void UpdateBounds() override; diff --git a/Source/Engine/Level/Actors/StaticModel.cpp b/Source/Engine/Level/Actors/StaticModel.cpp index 75c272cce..d5c7e0e3e 100644 --- a/Source/Engine/Level/Actors/StaticModel.cpp +++ b/Source/Engine/Level/Actors/StaticModel.cpp @@ -543,6 +543,14 @@ void StaticModel::Deserialize(DeserializeStream& stream, ISerializeModifier* mod } } +const Span StaticModel::GetMaterialSlots() const +{ + const auto model = Model.Get(); + if (model && !model->WaitForLoaded()) + return ToSpan(model->MaterialSlots); + return Span(); +} + MaterialBase* StaticModel::GetMaterial(int32 entryIndex) { if (Model) diff --git a/Source/Engine/Level/Actors/StaticModel.h b/Source/Engine/Level/Actors/StaticModel.h index 78a0440fd..2e932096e 100644 --- a/Source/Engine/Level/Actors/StaticModel.h +++ b/Source/Engine/Level/Actors/StaticModel.h @@ -166,6 +166,7 @@ public: bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override; void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; + const Span GetMaterialSlots() const override; MaterialBase* GetMaterial(int32 entryIndex) override; bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) override; bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override; diff --git a/Source/Engine/Renderer/Renderer.cs b/Source/Engine/Renderer/Renderer.cs index bfb81a84c..71dca424b 100644 --- a/Source/Engine/Renderer/Renderer.cs +++ b/Source/Engine/Renderer/Renderer.cs @@ -17,10 +17,13 @@ namespace FlaxEngine [Unmanaged] public static void DrawSceneDepth(GPUContext context, SceneRenderTask task, GPUTexture output, List customActors) { - if (customActors.Count == 0) - return; - var temp = CollectionsMarshal.AsSpan(customActors).ToArray(); // FIXME - var tempCount = temp.Length; + Actor[] temp = null; + int tempCount = 0; + if (customActors != null && customActors.Count != 0) + { + temp = CollectionsMarshal.AsSpan(customActors).ToArray(); // FIXME + tempCount = temp.Length; + } Internal_DrawSceneDepth(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(output), temp, ref tempCount); } @@ -32,7 +35,14 @@ namespace FlaxEngine [Unmanaged] public static void DrawActors(ref RenderContext renderContext, List customActors) { - DrawActors(ref renderContext, Utils.ExtractArrayFromList(customActors)); + Actor[] temp = null; + int tempCount = 0; + if (customActors != null && customActors.Count != 0) + { + temp = CollectionsMarshal.AsSpan(customActors).ToArray(); // FIXME + tempCount = temp.Length; + } + Internal_DrawActors(ref renderContext, temp, ref tempCount); } } } diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index e2d709653..bbfa802f1 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -476,12 +476,28 @@ bool Scripting::Load() // Load FlaxEngine const String flaxEnginePath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll"); - if (((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->Load(flaxEnginePath)) + auto* flaxEngineModule = (NativeBinaryModule*)GetBinaryModuleFlaxEngine(); + if (flaxEngineModule->Assembly->Load(flaxEnginePath)) { LOG(Error, "Failed to load FlaxEngine C# assembly."); return true; } + // Insert type aliases for vector types that don't exist in C++ but are just typedef (properly redirect them to actual types) + // TODO: add support for automatic typedef aliases setup for scripting module to properly lookup type from the alias typename +#if USE_LARGE_WORLDS + flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector2"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Double2"]; + flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector3"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Double3"]; + flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector4"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Double4"]; +#else + flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector2"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Float2"]; + flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector3"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Float3"]; + flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector4"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Float4"]; +#endif + flaxEngineModule->ClassToTypeIndex[flaxEngineModule->Assembly->GetClass("FlaxEngine.Vector2")] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector2"]; + flaxEngineModule->ClassToTypeIndex[flaxEngineModule->Assembly->GetClass("FlaxEngine.Vector3")] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector3"]; + flaxEngineModule->ClassToTypeIndex[flaxEngineModule->Assembly->GetClass("FlaxEngine.Vector4")] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector4"]; + #if USE_EDITOR // Skip loading game modules in Editor on startup - Editor loads them later during splash screen (eg. after first compilation) static bool SkipFirstLoad = true; diff --git a/Source/Engine/Visject/VisjectGraph.cpp b/Source/Engine/Visject/VisjectGraph.cpp index 37154e09f..ca4495f67 100644 --- a/Source/Engine/Visject/VisjectGraph.cpp +++ b/Source/Engine/Visject/VisjectGraph.cpp @@ -675,6 +675,10 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value) } } } + + // For in-built structures try to convert it into internal format for better comparability with the scripting + value.Inline(); + break; } // Unpack Structure diff --git a/Source/Engine/Visject/VisjectGraph.h b/Source/Engine/Visject/VisjectGraph.h index 238823afd..0d841f3d4 100644 --- a/Source/Engine/Visject/VisjectGraph.h +++ b/Source/Engine/Visject/VisjectGraph.h @@ -246,6 +246,7 @@ public: void ProcessGroupCollections(Box* box, Node* node, Value& value); protected: + void InlineVariantStruct(Variant& v); virtual Value eatBox(Node* caller, Box* box) = 0; virtual Graph* GetCurrentGraph() const = 0;