Merge remote-tracking branch 'origin/master' into 1.7
This commit is contained in:
@@ -33,7 +33,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
[CustomEditor(typeof(Asset)), DefaultEditor]
|
[CustomEditor(typeof(Asset)), DefaultEditor]
|
||||||
public class AssetRefEditor : CustomEditor
|
public class AssetRefEditor : CustomEditor
|
||||||
{
|
{
|
||||||
private AssetPicker _picker;
|
/// <summary>
|
||||||
|
/// The asset picker used to get a reference to an asset.
|
||||||
|
/// </summary>
|
||||||
|
public AssetPicker Picker;
|
||||||
|
|
||||||
|
private bool _isRefreshing;
|
||||||
private ScriptType _valueType;
|
private ScriptType _valueType;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -44,7 +49,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
if (HasDifferentTypes)
|
if (HasDifferentTypes)
|
||||||
return;
|
return;
|
||||||
_picker = layout.Custom<AssetPicker>().CustomControl;
|
Picker = layout.Custom<AssetPicker>().CustomControl;
|
||||||
|
|
||||||
_valueType = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
|
_valueType = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
|
||||||
var assetType = _valueType;
|
var assetType = _valueType;
|
||||||
@@ -66,7 +71,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
// Generic file picker
|
// Generic file picker
|
||||||
assetType = ScriptType.Null;
|
assetType = ScriptType.Null;
|
||||||
_picker.FileExtension = assetReference.TypeName;
|
Picker.FileExtension = assetReference.TypeName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -78,23 +83,25 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_picker.AssetType = assetType;
|
Picker.AssetType = assetType;
|
||||||
_picker.Height = height;
|
Picker.Height = height;
|
||||||
_picker.SelectedItemChanged += OnSelectedItemChanged;
|
Picker.SelectedItemChanged += OnSelectedItemChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSelectedItemChanged()
|
private void OnSelectedItemChanged()
|
||||||
{
|
{
|
||||||
|
if (_isRefreshing)
|
||||||
|
return;
|
||||||
if (typeof(AssetItem).IsAssignableFrom(_valueType.Type))
|
if (typeof(AssetItem).IsAssignableFrom(_valueType.Type))
|
||||||
SetValue(_picker.SelectedItem);
|
SetValue(Picker.SelectedItem);
|
||||||
else if (_valueType.Type == typeof(Guid))
|
else if (_valueType.Type == typeof(Guid))
|
||||||
SetValue(_picker.SelectedID);
|
SetValue(Picker.SelectedID);
|
||||||
else if (_valueType.Type == typeof(SceneReference))
|
else if (_valueType.Type == typeof(SceneReference))
|
||||||
SetValue(new SceneReference(_picker.SelectedID));
|
SetValue(new SceneReference(Picker.SelectedID));
|
||||||
else if (_valueType.Type == typeof(string))
|
else if (_valueType.Type == typeof(string))
|
||||||
SetValue(_picker.SelectedPath);
|
SetValue(Picker.SelectedPath);
|
||||||
else
|
else
|
||||||
SetValue(_picker.SelectedAsset);
|
SetValue(Picker.SelectedAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -104,16 +111,18 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
if (!HasDifferentValues)
|
if (!HasDifferentValues)
|
||||||
{
|
{
|
||||||
|
_isRefreshing = true;
|
||||||
if (Values[0] is AssetItem assetItem)
|
if (Values[0] is AssetItem assetItem)
|
||||||
_picker.SelectedItem = assetItem;
|
Picker.SelectedItem = assetItem;
|
||||||
else if (Values[0] is Guid guid)
|
else if (Values[0] is Guid guid)
|
||||||
_picker.SelectedID = guid;
|
Picker.SelectedID = guid;
|
||||||
else if (Values[0] is SceneReference sceneAsset)
|
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)
|
else if (Values[0] is string path)
|
||||||
_picker.SelectedPath = path;
|
Picker.SelectedPath = path;
|
||||||
else
|
else
|
||||||
_picker.SelectedAsset = Values[0] as Asset;
|
Picker.SelectedAsset = Values[0] as Asset;
|
||||||
|
_isRefreshing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using FlaxEditor.CustomEditors.Elements;
|
using FlaxEditor.CustomEditors.Elements;
|
||||||
|
using FlaxEditor.CustomEditors.GUI;
|
||||||
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
|
||||||
namespace FlaxEditor.CustomEditors.Editors
|
namespace FlaxEditor.CustomEditors.Editors
|
||||||
@@ -13,6 +15,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
private GroupElement _group;
|
private GroupElement _group;
|
||||||
private bool _updateName;
|
private bool _updateName;
|
||||||
|
private int _entryIndex;
|
||||||
|
private bool _isRefreshing;
|
||||||
|
private MaterialBase _material;
|
||||||
|
private ModelInstanceActor _modelInstance;
|
||||||
|
private AssetRefEditor _materialEditor;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
@@ -21,47 +28,122 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var group = layout.Group("Entry");
|
var group = layout.Group("Entry");
|
||||||
_group = group;
|
_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);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Refresh()
|
public override void Refresh()
|
||||||
{
|
{
|
||||||
|
// Update panel title to match material slot name
|
||||||
if (_updateName &&
|
if (_updateName &&
|
||||||
_group != null &&
|
_group != null &&
|
||||||
ParentEditor?.ParentEditor != null &&
|
ParentEditor?.ParentEditor != null &&
|
||||||
ParentEditor.ParentEditor.Values.Count > 0)
|
ParentEditor.ParentEditor.Values.Count > 0)
|
||||||
{
|
{
|
||||||
var entryIndex = ParentEditor.ChildrenEditors.IndexOf(this);
|
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;
|
var slots = modelInstance.MaterialSlots;
|
||||||
if (model && model.IsLoaded)
|
if (slots != null && slots.Length > entryIndex)
|
||||||
{
|
{
|
||||||
var slots = model.MaterialSlots;
|
_updateName = false;
|
||||||
if (slots != null && slots.Length > entryIndex)
|
_group.Panel.HeaderText = "Entry " + slots[entryIndex].Name;
|
||||||
{
|
|
||||||
_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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Refresh currently selected material
|
||||||
|
_material = _modelInstance.GetMaterial(_entryIndex);
|
||||||
|
|
||||||
base.Refresh();
|
base.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Deinitialize()
|
||||||
|
{
|
||||||
|
_material = null;
|
||||||
|
_modelInstance = null;
|
||||||
|
_materialEditor = null;
|
||||||
|
|
||||||
|
base.Deinitialize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,8 @@ namespace FlaxEditor.Gizmo
|
|||||||
if (selection[i] is ActorNode actorNode && actorNode.Actor != null)
|
if (selection[i] is ActorNode actorNode && actorNode.Actor != null)
|
||||||
CollectActors(actorNode.Actor);
|
CollectActors(actorNode.Actor);
|
||||||
}
|
}
|
||||||
|
if (_actors.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// Render selected objects depth
|
// Render selected objects depth
|
||||||
Renderer.DrawSceneDepth(context, task, customDepth, _actors);
|
Renderer.DrawSceneDepth(context, task, customDepth, _actors);
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if material is an material instance.
|
/// Returns true if material is an material instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if it's a material instance, otherwise false.</returns>
|
|
||||||
virtual bool IsMaterialInstance() const = 0;
|
virtual bool IsMaterialInstance() const = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -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)
|
bool Variant::CanCast(const Variant& v, const VariantType& to)
|
||||||
{
|
{
|
||||||
if (v.Type == to)
|
if (v.Type == to)
|
||||||
@@ -3682,6 +3798,7 @@ void Variant::AllocStructure()
|
|||||||
const ScriptingType& type = typeHandle.GetType();
|
const ScriptingType& type = typeHandle.GetType();
|
||||||
AsBlob.Length = type.Size;
|
AsBlob.Length = type.Size;
|
||||||
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
|
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
|
||||||
|
Platform::MemoryClear(AsBlob.Data, AsBlob.Length);
|
||||||
type.Struct.Ctor(AsBlob.Data);
|
type.Struct.Ctor(AsBlob.Data);
|
||||||
}
|
}
|
||||||
else if (typeName == "System.Int16" || typeName == "System.UInt16")
|
else if (typeName == "System.Int16" || typeName == "System.UInt16")
|
||||||
|
|||||||
@@ -359,6 +359,9 @@ public:
|
|||||||
void SetAsset(Asset* asset);
|
void SetAsset(Asset* asset);
|
||||||
String ToString() const;
|
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
|
FORCE_INLINE Variant Cast(const VariantType& to) const
|
||||||
{
|
{
|
||||||
return Cast(*this, to);
|
return Cast(*this, to);
|
||||||
|
|||||||
@@ -244,7 +244,25 @@ namespace FlaxEngine.Interop
|
|||||||
@namespace = NativeAllocStringAnsi(type.Namespace ?? ""),
|
@namespace = NativeAllocStringAnsi(type.Namespace ?? ""),
|
||||||
typeAttributes = (uint)type.Attributes,
|
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]
|
[UnmanagedCallersOnly]
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the default material.
|
/// Gets the default material.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MaterialBase* GetDefaultMaterial() const;
|
API_PROPERTY() MaterialBase* GetDefaultMaterial() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the default material (Deformable domain).
|
/// Gets the default material (Deformable domain).
|
||||||
|
|||||||
@@ -1066,6 +1066,14 @@ void AnimatedModel::Deserialize(DeserializeStream& stream, ISerializeModifier* m
|
|||||||
DrawModes |= DrawPass::GlobalSurfaceAtlas;
|
DrawModes |= DrawPass::GlobalSurfaceAtlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Span<MaterialSlot> AnimatedModel::GetMaterialSlots() const
|
||||||
|
{
|
||||||
|
const auto model = SkinnedModel.Get();
|
||||||
|
if (model && !model->WaitForLoaded())
|
||||||
|
return ToSpan(model->MaterialSlots);
|
||||||
|
return Span<MaterialSlot>();
|
||||||
|
}
|
||||||
|
|
||||||
MaterialBase* AnimatedModel::GetMaterial(int32 entryIndex)
|
MaterialBase* AnimatedModel::GetMaterial(int32 entryIndex)
|
||||||
{
|
{
|
||||||
if (SkinnedModel)
|
if (SkinnedModel)
|
||||||
|
|||||||
@@ -384,6 +384,7 @@ public:
|
|||||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
|
const Span<MaterialSlot> GetMaterialSlots() const override;
|
||||||
MaterialBase* GetMaterial(int32 entryIndex) override;
|
MaterialBase* GetMaterial(int32 entryIndex) override;
|
||||||
bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) 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;
|
bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override;
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_PROPERTY() void SetEntries(const Array<ModelInstanceEntry>& value);
|
API_PROPERTY() void SetEntries(const Array<ModelInstanceEntry>& value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the material slots array set on the asset (eg. model or skinned model asset).
|
||||||
|
/// </summary>
|
||||||
|
API_PROPERTY(Sealed) virtual const Span<class MaterialSlot> GetMaterialSlots() const = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the material used to draw the meshes which are assigned to that slot (set in Entries or model's default).
|
/// Gets the material used to draw the meshes which are assigned to that slot (set in Entries or model's default).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -341,6 +341,14 @@ void SplineModel::OnParentChanged()
|
|||||||
OnSplineUpdated();
|
OnSplineUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Span<MaterialSlot> SplineModel::GetMaterialSlots() const
|
||||||
|
{
|
||||||
|
const auto model = Model.Get();
|
||||||
|
if (model && !model->WaitForLoaded())
|
||||||
|
return ToSpan(model->MaterialSlots);
|
||||||
|
return Span<MaterialSlot>();
|
||||||
|
}
|
||||||
|
|
||||||
MaterialBase* SplineModel::GetMaterial(int32 entryIndex)
|
MaterialBase* SplineModel::GetMaterial(int32 entryIndex)
|
||||||
{
|
{
|
||||||
if (Model)
|
if (Model)
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ public:
|
|||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
void OnParentChanged() override;
|
void OnParentChanged() override;
|
||||||
|
const Span<MaterialSlot> GetMaterialSlots() const override;
|
||||||
MaterialBase* GetMaterial(int32 entryIndex) override;
|
MaterialBase* GetMaterial(int32 entryIndex) override;
|
||||||
void UpdateBounds() override;
|
void UpdateBounds() override;
|
||||||
|
|
||||||
|
|||||||
@@ -543,6 +543,14 @@ void StaticModel::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Span<MaterialSlot> StaticModel::GetMaterialSlots() const
|
||||||
|
{
|
||||||
|
const auto model = Model.Get();
|
||||||
|
if (model && !model->WaitForLoaded())
|
||||||
|
return ToSpan(model->MaterialSlots);
|
||||||
|
return Span<MaterialSlot>();
|
||||||
|
}
|
||||||
|
|
||||||
MaterialBase* StaticModel::GetMaterial(int32 entryIndex)
|
MaterialBase* StaticModel::GetMaterial(int32 entryIndex)
|
||||||
{
|
{
|
||||||
if (Model)
|
if (Model)
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ public:
|
|||||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
|
const Span<MaterialSlot> GetMaterialSlots() const override;
|
||||||
MaterialBase* GetMaterial(int32 entryIndex) override;
|
MaterialBase* GetMaterial(int32 entryIndex) override;
|
||||||
bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) 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;
|
bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override;
|
||||||
|
|||||||
@@ -17,10 +17,13 @@ namespace FlaxEngine
|
|||||||
[Unmanaged]
|
[Unmanaged]
|
||||||
public static void DrawSceneDepth(GPUContext context, SceneRenderTask task, GPUTexture output, List<Actor> customActors)
|
public static void DrawSceneDepth(GPUContext context, SceneRenderTask task, GPUTexture output, List<Actor> customActors)
|
||||||
{
|
{
|
||||||
if (customActors.Count == 0)
|
Actor[] temp = null;
|
||||||
return;
|
int tempCount = 0;
|
||||||
var temp = CollectionsMarshal.AsSpan(customActors).ToArray(); // FIXME
|
if (customActors != null && customActors.Count != 0)
|
||||||
var tempCount = temp.Length;
|
{
|
||||||
|
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);
|
Internal_DrawSceneDepth(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(output), temp, ref tempCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +35,14 @@ namespace FlaxEngine
|
|||||||
[Unmanaged]
|
[Unmanaged]
|
||||||
public static void DrawActors(ref RenderContext renderContext, List<Actor> customActors)
|
public static void DrawActors(ref RenderContext renderContext, List<Actor> 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -476,12 +476,28 @@ bool Scripting::Load()
|
|||||||
|
|
||||||
// Load FlaxEngine
|
// Load FlaxEngine
|
||||||
const String flaxEnginePath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll");
|
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.");
|
LOG(Error, "Failed to load FlaxEngine C# assembly.");
|
||||||
return true;
|
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
|
#if USE_EDITOR
|
||||||
// Skip loading game modules in Editor on startup - Editor loads them later during splash screen (eg. after first compilation)
|
// Skip loading game modules in Editor on startup - Editor loads them later during splash screen (eg. after first compilation)
|
||||||
static bool SkipFirstLoad = true;
|
static bool SkipFirstLoad = true;
|
||||||
|
|||||||
@@ -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;
|
break;
|
||||||
}
|
}
|
||||||
// Unpack Structure
|
// Unpack Structure
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ public:
|
|||||||
void ProcessGroupCollections(Box* box, Node* node, Value& value);
|
void ProcessGroupCollections(Box* box, Node* node, Value& value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void InlineVariantStruct(Variant& v);
|
||||||
virtual Value eatBox(Node* caller, Box* box) = 0;
|
virtual Value eatBox(Node* caller, Box* box) = 0;
|
||||||
virtual Graph* GetCurrentGraph() const = 0;
|
virtual Graph* GetCurrentGraph() const = 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user