Merge branch 'master' into AnimationSampleNode-AnimationAssetReferencePort
This commit is contained in:
@@ -125,6 +125,8 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
fov = cam.FieldOfView;
|
||||
customAspectRatio = cam.CustomAspectRatio;
|
||||
view.RenderLayersMask = cam.RenderLayersMask;
|
||||
view.Flags = cam.RenderFlags;
|
||||
view.Mode = cam.RenderMode;
|
||||
}
|
||||
|
||||
// Try to evaluate camera properties based on the animated tracks
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.SceneGraph.Actors
|
||||
@@ -22,9 +23,9 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnContextMenu(ContextMenu contextMenu)
|
||||
public override void OnContextMenu(ContextMenu contextMenu, EditorWindow window)
|
||||
{
|
||||
base.OnContextMenu(contextMenu);
|
||||
base.OnContextMenu(contextMenu, window);
|
||||
|
||||
var actor = (AnimatedModel)Actor;
|
||||
if (actor && actor.SkinnedModel)
|
||||
|
||||
@@ -6,6 +6,8 @@ using Real = System.Double;
|
||||
using Real = System.Single;
|
||||
#endif
|
||||
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.SceneGraph.Actors
|
||||
@@ -23,6 +25,25 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnContextMenu(ContextMenu contextMenu, EditorWindow window)
|
||||
{
|
||||
base.OnContextMenu(contextMenu, window);
|
||||
if (window is not SceneTreeWindow win)
|
||||
return;
|
||||
var button = new ContextMenuButton(contextMenu, "Move Camera to View");
|
||||
button.Parent = contextMenu.ItemsContainer;
|
||||
contextMenu.ItemsContainer.Children.Remove(button);
|
||||
contextMenu.ItemsContainer.Children.Insert(4, button);
|
||||
button.Clicked += () =>
|
||||
{
|
||||
var c = Actor as Camera;
|
||||
var viewport = Editor.Instance.Windows.EditWin.Viewport;
|
||||
c.Position = viewport.ViewPosition;
|
||||
c.Orientation = viewport.ViewOrientation;
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool RayCastSelf(ref RayCastData ray, out Real distance, out Vector3 normal)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System.IO;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.SceneGraph.GUI;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.SceneGraph.Actors
|
||||
@@ -65,7 +66,7 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
public override SceneNode ParentScene => this;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnContextMenu(ContextMenu contextMenu)
|
||||
public override void OnContextMenu(ContextMenu contextMenu, EditorWindow window)
|
||||
{
|
||||
contextMenu.AddSeparator();
|
||||
var path = Scene.Path;
|
||||
@@ -80,7 +81,7 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
if (Level.ScenesCount > 1)
|
||||
contextMenu.AddButton("Unload all but this scene", OnUnloadAllButSelectedScene).LinkTooltip("Unloads all of the active scenes except for the selected scene.").Enabled = Editor.Instance.StateMachine.CurrentState.CanChangeScene;
|
||||
|
||||
base.OnContextMenu(contextMenu);
|
||||
base.OnContextMenu(contextMenu, window);
|
||||
}
|
||||
|
||||
private void OnSelect()
|
||||
|
||||
@@ -9,6 +9,7 @@ using Real = System.Single;
|
||||
using System;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.Modules;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.Json;
|
||||
using Object = FlaxEngine.Object;
|
||||
@@ -203,9 +204,9 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnContextMenu(ContextMenu contextMenu)
|
||||
public override void OnContextMenu(ContextMenu contextMenu, EditorWindow window)
|
||||
{
|
||||
ParentNode.OnContextMenu(contextMenu);
|
||||
ParentNode.OnContextMenu(contextMenu, window);
|
||||
}
|
||||
|
||||
public static SceneGraphNode Create(StateData state)
|
||||
@@ -272,9 +273,9 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
DebugDraw.DrawSphere(new BoundingSphere(pos, tangentSize), Color.YellowGreen, 0, false);
|
||||
}
|
||||
|
||||
public override void OnContextMenu(ContextMenu contextMenu)
|
||||
public override void OnContextMenu(ContextMenu contextMenu, EditorWindow window)
|
||||
{
|
||||
ParentNode.OnContextMenu(contextMenu);
|
||||
ParentNode.OnContextMenu(contextMenu, window);
|
||||
}
|
||||
|
||||
public override void OnDispose()
|
||||
@@ -354,9 +355,9 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnContextMenu(ContextMenu contextMenu)
|
||||
public override void OnContextMenu(ContextMenu contextMenu, EditorWindow window)
|
||||
{
|
||||
base.OnContextMenu(contextMenu);
|
||||
base.OnContextMenu(contextMenu, window);
|
||||
|
||||
contextMenu.AddButton("Add spline model", OnAddSplineModel);
|
||||
contextMenu.AddButton("Add spline collider", OnAddSplineCollider);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.SceneGraph.Actors
|
||||
@@ -21,9 +22,9 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnContextMenu(ContextMenu contextMenu)
|
||||
public override void OnContextMenu(ContextMenu contextMenu, EditorWindow window)
|
||||
{
|
||||
base.OnContextMenu(contextMenu);
|
||||
base.OnContextMenu(contextMenu, window);
|
||||
|
||||
contextMenu.AddButton("Add collider", OnAddMeshCollider).Enabled = ((StaticModel)Actor).Model != null;
|
||||
}
|
||||
|
||||
@@ -599,7 +599,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
// Drag scripts
|
||||
else if (_dragScripts != null && _dragScripts.HasValidDrag)
|
||||
{
|
||||
foreach(var script in _dragScripts.Objects)
|
||||
foreach (var script in _dragScripts.Objects)
|
||||
{
|
||||
var customAction = script.HasPrefabLink ? new ReparentAction(script) : null;
|
||||
using (new UndoBlock(ActorNode.Root.Undo, script, "Change script parent", customAction))
|
||||
@@ -616,7 +616,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
var spawnParent = myActor;
|
||||
if (DragOverMode == DragItemPositioning.Above || DragOverMode == DragItemPositioning.Below)
|
||||
spawnParent = newParent;
|
||||
|
||||
|
||||
for (int i = 0; i < _dragAssets.Objects.Count; i++)
|
||||
{
|
||||
var item = _dragAssets.Objects[i];
|
||||
@@ -720,7 +720,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
for (var i = 0; i < tree.Selection.Count; i++)
|
||||
{
|
||||
var e = tree.Selection[i];
|
||||
|
||||
|
||||
// Skip if parent is already selected to keep correct parenting
|
||||
if (tree.Selection.Contains(e.Parent))
|
||||
continue;
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Modules;
|
||||
using FlaxEditor.SceneGraph.Actors;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.SceneGraph
|
||||
@@ -339,7 +340,7 @@ namespace FlaxEditor.SceneGraph
|
||||
/// <summary>
|
||||
/// Called when scene tree window wants to show the context menu. Allows to add custom options.
|
||||
/// </summary>
|
||||
public virtual void OnContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu contextMenu)
|
||||
public virtual void OnContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu contextMenu, EditorWindow window)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -787,7 +787,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
}
|
||||
}
|
||||
|
||||
private class AsNode : SurfaceNode
|
||||
internal class AsNode : SurfaceNode
|
||||
{
|
||||
private TypePickerControl _picker;
|
||||
|
||||
@@ -838,6 +838,15 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
box.CurrentType = type ? type : ScriptType.FlaxObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the type of the picker and the type of the output box
|
||||
/// </summary>
|
||||
/// <param name="type">Target Type</param>
|
||||
public void SetPickerValue(ScriptType type)
|
||||
{
|
||||
_picker.Value = type;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
@@ -999,6 +1008,15 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
GetBox(4).CurrentType = type ? type : _picker.Type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the type of the picker and the type of the output box
|
||||
/// </summary>
|
||||
/// <param name="type">Target Type</param>
|
||||
public void SetPickerValue(ScriptType type)
|
||||
{
|
||||
_picker.Value = type;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
|
||||
@@ -721,9 +721,7 @@ namespace FlaxEditor.Surface.ContextMenu
|
||||
SelectedItem = previousSelectedItem;
|
||||
|
||||
// Scroll into view (without smoothing)
|
||||
_panel1.VScrollBar.SmoothingScale = 0;
|
||||
_panel1.ScrollViewTo(SelectedItem);
|
||||
_panel1.VScrollBar.SmoothingScale = 1;
|
||||
_panel1.ScrollViewTo(SelectedItem, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -820,8 +820,62 @@ namespace FlaxEditor.Surface.Elements
|
||||
if (useCaster)
|
||||
{
|
||||
// Connect via Caster
|
||||
//AddCaster(oB, iB);
|
||||
throw new NotImplementedException("AddCaster(..) function");
|
||||
const float casterXOffset = 250;
|
||||
if (Surface.Undo != null && Surface.Undo.Enabled)
|
||||
{
|
||||
bool undoEnabled = Surface.Undo.Enabled;
|
||||
Surface.Undo.Enabled = false;
|
||||
SurfaceNode node = Surface.Context.SpawnNode(7, 22, Float2.Zero); // 22 AsNode, 25 CastNode
|
||||
Surface.Undo.Enabled = undoEnabled;
|
||||
if (node is not Archetypes.Tools.AsNode castNode)
|
||||
throw new Exception("Node is not a casting node!");
|
||||
|
||||
// Set the type of the casting node
|
||||
undoEnabled = castNode.Surface.Undo.Enabled;
|
||||
castNode.Surface.Undo.Enabled = false;
|
||||
castNode.SetPickerValue(iB.CurrentType);
|
||||
castNode.Surface.Undo.Enabled = undoEnabled;
|
||||
if (node.GetBox(0) is not OutputBox castOutputBox || node.GetBox(1) is not InputBox castInputBox)
|
||||
throw new NullReferenceException("Casting failed. Cast node is invalid!");
|
||||
|
||||
// We set the position of the cast node here to set it relative to the target nodes input box
|
||||
undoEnabled = castNode.Surface.Undo.Enabled;
|
||||
castNode.Surface.Undo.Enabled = false;
|
||||
var wantedOffset = iB.ParentNode.Location - new Float2(casterXOffset, -(iB.LocalY - castOutputBox.LocalY));
|
||||
castNode.Location = Surface.Root.PointFromParent(ref wantedOffset);
|
||||
castNode.Surface.Undo.Enabled = undoEnabled;
|
||||
|
||||
var spawnNodeAction = new AddRemoveNodeAction(castNode, true);
|
||||
|
||||
var connectToCastNodeAction = new ConnectBoxesAction(castInputBox, oB, true);
|
||||
castInputBox.CreateConnection(oB);
|
||||
connectToCastNodeAction.End();
|
||||
|
||||
var connectCastToTargetNodeAction = new ConnectBoxesAction(iB, castOutputBox, true);
|
||||
iB.CreateConnection(castOutputBox);
|
||||
connectCastToTargetNodeAction.End();
|
||||
|
||||
Surface.AddBatchedUndoAction(new MultiUndoAction(spawnNodeAction, connectToCastNodeAction, connectCastToTargetNodeAction));
|
||||
}
|
||||
else
|
||||
{
|
||||
SurfaceNode node = Surface.Context.SpawnNode(7, 22, Float2.Zero); // 22 AsNode, 25 CastNode
|
||||
if (node is not Archetypes.Tools.AsNode castNode)
|
||||
throw new Exception("Node is not a casting node!");
|
||||
|
||||
// Set the type of the casting node
|
||||
castNode.SetPickerValue(iB.CurrentType);
|
||||
if (node.GetBox(0) is not OutputBox castOutputBox || node.GetBox(1) is not InputBox castInputBox)
|
||||
throw new NullReferenceException("Casting failed. Cast node is invalid!");
|
||||
|
||||
// We set the position of the cast node here to set it relative to the target nodes input box
|
||||
var wantedOffset = iB.ParentNode.Location - new Float2(casterXOffset, -(iB.LocalY - castOutputBox.LocalY));
|
||||
castNode.Location = Surface.Root.PointFromParent(ref wantedOffset);
|
||||
|
||||
castInputBox.CreateConnection(oB);
|
||||
iB.CreateConnection(castOutputBox);
|
||||
}
|
||||
Surface.MarkAsEdited();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.GUI.Input;
|
||||
using FlaxEditor.Options;
|
||||
@@ -9,6 +10,8 @@ using FlaxEditor.Viewport.Cameras;
|
||||
using FlaxEditor.Viewport.Widgets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using Newtonsoft.Json;
|
||||
using JsonSerializer = FlaxEngine.Json.JsonSerializer;
|
||||
|
||||
namespace FlaxEditor.Viewport
|
||||
{
|
||||
@@ -486,10 +489,63 @@ namespace FlaxEditor.Viewport
|
||||
}
|
||||
}
|
||||
|
||||
// View Layers
|
||||
{
|
||||
var viewLayers = ViewWidgetButtonMenu.AddChildMenu("View Layers").ContextMenu;
|
||||
viewLayers.AddButton("Copy layers", () => Clipboard.Text = JsonSerializer.Serialize(Task.View.RenderLayersMask));
|
||||
viewLayers.AddButton("Paste layers", () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Task.ViewLayersMask = JsonSerializer.Deserialize<LayersMask>(Clipboard.Text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
});
|
||||
viewLayers.AddButton("Reset layers", () => Task.ViewLayersMask = LayersMask.Default).Icon = Editor.Instance.Icons.Rotate32;
|
||||
viewLayers.AddButton("Disable layers", () => Task.ViewLayersMask = new LayersMask(0)).Icon = Editor.Instance.Icons.Rotate32;
|
||||
viewLayers.AddSeparator();
|
||||
var layers = LayersAndTagsSettings.GetCurrentLayers();
|
||||
if (layers != null && layers.Length > 0)
|
||||
{
|
||||
for (int i = 0; i < layers.Length; i++)
|
||||
{
|
||||
var layer = layers[i];
|
||||
var button = viewLayers.AddButton(layer);
|
||||
button.CloseMenuOnClick = false;
|
||||
button.Tag = 1 << i;
|
||||
}
|
||||
}
|
||||
viewLayers.ButtonClicked += button =>
|
||||
{
|
||||
if (button.Tag != null)
|
||||
{
|
||||
int layerIndex = (int)button.Tag;
|
||||
LayersMask mask = new LayersMask(layerIndex);
|
||||
Task.ViewLayersMask ^= mask;
|
||||
button.Icon = (Task.ViewLayersMask & mask) != 0 ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
|
||||
}
|
||||
};
|
||||
viewLayers.VisibleChanged += WidgetViewLayersShowHide;
|
||||
}
|
||||
|
||||
// View Flags
|
||||
{
|
||||
var viewFlags = ViewWidgetButtonMenu.AddChildMenu("View Flags").ContextMenu;
|
||||
viewFlags.AddButton("Copy flags", () => Clipboard.Text = JsonSerializer.Serialize(Task.ViewFlags));
|
||||
viewFlags.AddButton("Paste flags", () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Task.ViewFlags = JsonSerializer.Deserialize<ViewFlags>(Clipboard.Text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
});
|
||||
viewFlags.AddButton("Reset flags", () => Task.ViewFlags = ViewFlags.DefaultEditor).Icon = Editor.Instance.Icons.Rotate32;
|
||||
viewFlags.AddButton("Disable flags", () => Task.ViewFlags = ViewFlags.None).Icon = Editor.Instance.Icons.Rotate32;
|
||||
viewFlags.AddSeparator();
|
||||
for (int i = 0; i < EditorViewportViewFlagsValues.Length; i++)
|
||||
{
|
||||
@@ -504,7 +560,7 @@ namespace FlaxEditor.Viewport
|
||||
{
|
||||
var v = (ViewFlags)button.Tag;
|
||||
Task.ViewFlags ^= v;
|
||||
button.Icon = (Task.View.Flags & v) != 0 ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
|
||||
button.Icon = (Task.ViewFlags & v) != 0 ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
|
||||
}
|
||||
};
|
||||
viewFlags.VisibleChanged += WidgetViewFlagsShowHide;
|
||||
@@ -513,6 +569,18 @@ namespace FlaxEditor.Viewport
|
||||
// Debug View
|
||||
{
|
||||
var debugView = ViewWidgetButtonMenu.AddChildMenu("Debug View").ContextMenu;
|
||||
debugView.AddButton("Copy view", () => Clipboard.Text = JsonSerializer.Serialize(Task.ViewMode));
|
||||
debugView.AddButton("Paste view", () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Task.ViewMode = JsonSerializer.Deserialize<ViewMode>(Clipboard.Text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
});
|
||||
debugView.AddSeparator();
|
||||
for (int i = 0; i < EditorViewportViewModeValues.Length; i++)
|
||||
{
|
||||
ref var v = ref EditorViewportViewModeValues[i];
|
||||
@@ -1084,9 +1152,9 @@ namespace FlaxEditor.Viewport
|
||||
_isVirtualMouseRightDown = false; // Cancel when mouse right or escape is pressed
|
||||
if (_wasVirtualMouseRightDown)
|
||||
wasControllingMouse = true;
|
||||
if (_isVirtualMouseRightDown)
|
||||
if (_isVirtualMouseRightDown)
|
||||
_isControllingMouse = _isVirtualMouseRightDown;
|
||||
|
||||
|
||||
if (wasControllingMouse != _isControllingMouse)
|
||||
{
|
||||
if (_isControllingMouse)
|
||||
@@ -1591,6 +1659,24 @@ namespace FlaxEditor.Viewport
|
||||
}
|
||||
}
|
||||
|
||||
private void WidgetViewLayersShowHide(Control cm)
|
||||
{
|
||||
if (cm.Visible == false)
|
||||
return;
|
||||
|
||||
var ccm = (ContextMenu)cm;
|
||||
var layersMask = Task.ViewLayersMask;
|
||||
foreach (var e in ccm.Items)
|
||||
{
|
||||
if (e is ContextMenuButton b && b != null && b.Tag != null)
|
||||
{
|
||||
int layerIndex = (int)b.Tag;
|
||||
LayersMask mask = new LayersMask(layerIndex);
|
||||
b.Icon = (layersMask & mask) != 0 ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float GetGamepadAxis(GamepadAxis axis)
|
||||
{
|
||||
var value = FlaxEngine.Input.GetGamepadAxis(InputGamepadIndex.All, axis);
|
||||
|
||||
@@ -313,7 +313,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
if (showCustomNodeOptions)
|
||||
{
|
||||
Selection[0].OnContextMenu(contextMenu);
|
||||
Selection[0].OnContextMenu(contextMenu, this);
|
||||
}
|
||||
ContextMenuShow?.Invoke(contextMenu);
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
Graph = new LocalSceneGraph(new CustomRootNode(this));
|
||||
_tree = new PrefabTree
|
||||
{
|
||||
Margin = new Margin(0.0f, 0.0f, -16.0f, 0.0f), // Hide root node
|
||||
Margin = new Margin(0.0f, 0.0f, -16.0f, _treePanel.ScrollBarsSize), // Hide root node
|
||||
IsScrollable = true,
|
||||
};
|
||||
_tree.AddChild(Graph.Root.TreeNode);
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace FlaxEditor.Windows
|
||||
}
|
||||
if (showCustomNodeOptions)
|
||||
{
|
||||
Editor.SceneEditing.Selection[0].OnContextMenu(contextMenu);
|
||||
Editor.SceneEditing.Selection[0].OnContextMenu(contextMenu, this);
|
||||
}
|
||||
|
||||
ContextMenuShow?.Invoke(contextMenu);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace FlaxEditor.Windows
|
||||
root.TreeNode.Expand();
|
||||
_tree = new Tree(true)
|
||||
{
|
||||
Margin = new Margin(0.0f, 0.0f, -16.0f, 0.0f), // Hide root node
|
||||
Margin = new Margin(0.0f, 0.0f, -16.0f, _sceneTreePanel.ScrollBarsSize), // Hide root node
|
||||
IsScrollable = true,
|
||||
};
|
||||
_tree.AddChild(root.TreeNode);
|
||||
|
||||
@@ -54,9 +54,7 @@ namespace FlaxEditor.Windows.Search
|
||||
_selectedItem.BackgroundColor = Style.Current.BackgroundSelected;
|
||||
if (_matchedItems.Count > VisibleItemCount)
|
||||
{
|
||||
_resultPanel.VScrollBar.SmoothingScale = 0;
|
||||
_resultPanel.ScrollViewTo(_selectedItem);
|
||||
_resultPanel.VScrollBar.SmoothingScale = 1;
|
||||
_resultPanel.ScrollViewTo(_selectedItem, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +171,8 @@ int32 FindVertex(const MeshData& mesh, int32 vertexIndex, int32 startIndex, int3
|
||||
const Float3 vNormal = mesh.Normals.HasItems() ? mesh.Normals[vertexIndex] : Float3::Zero;
|
||||
const Float3 vTangent = mesh.Tangents.HasItems() ? mesh.Tangents[vertexIndex] : Float3::Zero;
|
||||
const Float2 vLightmapUV = mesh.LightmapUVs.HasItems() ? mesh.LightmapUVs[vertexIndex] : Float2::Zero;
|
||||
const Color vColor = mesh.Colors.HasItems() ? mesh.Colors[vertexIndex] : Color::Black; // Assuming Color::Black as a default color
|
||||
|
||||
const int32 end = startIndex + searchRange;
|
||||
|
||||
for (size_t i = 0; i < sparialSortCache.size(); i++)
|
||||
@@ -184,6 +186,8 @@ int32 FindVertex(const MeshData& mesh, int32 vertexIndex, int32 startIndex, int3
|
||||
const Float3 vNormal = mesh.Normals.HasItems() ? mesh.Normals[vertexIndex] : Float3::Zero;
|
||||
const Float3 vTangent = mesh.Tangents.HasItems() ? mesh.Tangents[vertexIndex] : Float3::Zero;
|
||||
const Float2 vLightmapUV = mesh.LightmapUVs.HasItems() ? mesh.LightmapUVs[vertexIndex] : Float2::Zero;
|
||||
const Color vColor = mesh.Colors.HasItems() ? mesh.Colors[vertexIndex] : Color::Black; // Assuming Color::Black as a default color
|
||||
|
||||
const int32 end = startIndex + searchRange;
|
||||
|
||||
for (int32 v = startIndex; v < end; v++)
|
||||
@@ -201,6 +205,8 @@ int32 FindVertex(const MeshData& mesh, int32 vertexIndex, int32 startIndex, int3
|
||||
continue;
|
||||
if (mesh.LightmapUVs.HasItems() && (vLightmapUV - mesh.LightmapUVs[v]).LengthSquared() > uvEpsSqr)
|
||||
continue;
|
||||
if (mesh.Colors.HasItems() && vColor != mesh.Colors[v])
|
||||
continue;
|
||||
// TODO: check more components?
|
||||
|
||||
return v;
|
||||
|
||||
@@ -39,5 +39,19 @@ namespace FlaxEngine
|
||||
View = view;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The rendering mask for layers. Used to exclude objects from rendering (via <see cref="View"/> property).
|
||||
/// </summary>
|
||||
public LayersMask ViewLayersMask
|
||||
{
|
||||
get => View.RenderLayersMask;
|
||||
set
|
||||
{
|
||||
var view = View;
|
||||
view.RenderLayersMask = value;
|
||||
View = view;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ void RenderView::SetProjector(float nearPlane, float farPlane, const Float3& pos
|
||||
CullingFrustum = Frustum;
|
||||
}
|
||||
|
||||
void RenderView::CopyFrom(Camera* camera, Viewport* viewport)
|
||||
void RenderView::CopyFrom(const Camera* camera, const Viewport* viewport)
|
||||
{
|
||||
const Vector3 cameraPos = camera->GetPosition();
|
||||
LargeWorlds::UpdateOrigin(Origin, cameraPos);
|
||||
@@ -192,6 +192,8 @@ void RenderView::CopyFrom(Camera* camera, Viewport* viewport)
|
||||
Frustum.GetInvMatrix(IVP);
|
||||
CullingFrustum = Frustum;
|
||||
RenderLayersMask = camera->RenderLayersMask;
|
||||
Flags = camera->RenderFlags;
|
||||
Mode = camera->RenderMode;
|
||||
}
|
||||
|
||||
void RenderView::GetWorldMatrix(const Transform& transform, Matrix& world) const
|
||||
|
||||
@@ -102,6 +102,8 @@ namespace FlaxEngine
|
||||
NonJitteredProjection = Projection;
|
||||
TemporalAAJitter = Float4.Zero;
|
||||
RenderLayersMask = camera.RenderLayersMask;
|
||||
Flags = camera.RenderFlags;
|
||||
Mode = camera.RenderMode;
|
||||
|
||||
UpdateCachedData();
|
||||
}
|
||||
|
||||
@@ -295,10 +295,12 @@ public:
|
||||
/// <param name="angle">Camera's FOV angle (in degrees)</param>
|
||||
void SetProjector(float nearPlane, float farPlane, const Float3& position, const Float3& direction, const Float3& up, float angle);
|
||||
|
||||
// Copy view data from camera
|
||||
// @param camera Camera to copy its data
|
||||
// @param camera The custom viewport to use for view/projection matrices override.
|
||||
void CopyFrom(Camera* camera, Viewport* viewport = nullptr);
|
||||
/// <summary>
|
||||
/// Copies view data from camera to the view.
|
||||
/// </summary>
|
||||
/// <param name="camera">The camera to copy its data.</param>
|
||||
/// <param name="viewport">The custom viewport to use for view/projection matrices override.</param>
|
||||
void CopyFrom(const Camera* camera, const Viewport* viewport = nullptr);
|
||||
|
||||
public:
|
||||
FORCE_INLINE DrawPass GetShadowsDrawPassMask(ShadowsCastingMode shadowsMode) const
|
||||
|
||||
@@ -415,6 +415,8 @@ void Camera::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
SERIALIZE_MEMBER(Far, _far);
|
||||
SERIALIZE_MEMBER(OrthoScale, _orthoScale);
|
||||
SERIALIZE(RenderLayersMask);
|
||||
SERIALIZE(RenderFlags);
|
||||
SERIALIZE(RenderMode);
|
||||
}
|
||||
|
||||
void Camera::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
@@ -429,6 +431,8 @@ void Camera::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier
|
||||
DESERIALIZE_MEMBER(Far, _far);
|
||||
DESERIALIZE_MEMBER(OrthoScale, _orthoScale);
|
||||
DESERIALIZE(RenderLayersMask);
|
||||
DESERIALIZE(RenderFlags);
|
||||
DESERIALIZE(RenderMode);
|
||||
}
|
||||
|
||||
void Camera::OnEnable()
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Core/Math/Viewport.h"
|
||||
#include "Engine/Core/Math/Ray.h"
|
||||
#include "Engine/Core/Types/LayersMask.h"
|
||||
#include "Engine/Graphics/Enums.h"
|
||||
#include "Engine/Scripting/ScriptingObjectReference.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Content/AssetReference.h"
|
||||
@@ -134,6 +135,18 @@ public:
|
||||
API_FIELD(Attributes="EditorOrder(100), EditorDisplay(\"Camera\")")
|
||||
LayersMask RenderLayersMask;
|
||||
|
||||
/// <summary>
|
||||
/// Frame rendering flags used to switch between graphics features for this camera.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes = "EditorOrder(110), EditorDisplay(\"Camera\")")
|
||||
ViewFlags RenderFlags = ViewFlags::DefaultGame;
|
||||
|
||||
/// <summary>
|
||||
/// Describes frame rendering modes for this camera.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes = "EditorOrder(120), EditorDisplay(\"Camera\")")
|
||||
ViewMode RenderMode = ViewMode::Default;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Projects the point from 3D world-space to game window coordinates (in screen pixels for default viewport calculated from <see cref="Viewport"/>).
|
||||
|
||||
@@ -79,6 +79,7 @@ public:
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -127,7 +128,6 @@ public:
|
||||
{
|
||||
return (input[2] << 24) | (input[1] << 16) | (input[0] << 8);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -314,6 +314,28 @@ namespace FlaxEngine.GUI
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||
{
|
||||
if (base.OnMouseDoubleClick(location, button))
|
||||
return true;
|
||||
|
||||
if (button == MouseButton.Left && _isPressed)
|
||||
{
|
||||
OnPressEnd();
|
||||
OnClick();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (button == MouseButton.Left && !_isPressed)
|
||||
{
|
||||
OnPressBegin();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnTouchDown(Float2 location, int pointerId)
|
||||
{
|
||||
|
||||
@@ -277,6 +277,27 @@ namespace FlaxEngine.GUI
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && !_isPressed)
|
||||
{
|
||||
OnPressBegin();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (button == MouseButton.Left && _isPressed)
|
||||
{
|
||||
OnPressEnd();
|
||||
if (_box.Contains(ref location))
|
||||
{
|
||||
OnClick();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return base.OnMouseDoubleClick(location, button);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
|
||||
@@ -666,6 +666,30 @@ namespace FlaxEngine.GUI
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||
{
|
||||
if (base.OnMouseDoubleClick(location, button))
|
||||
return true;
|
||||
|
||||
if (_touchDown && button == MouseButton.Left)
|
||||
{
|
||||
_touchDown = false;
|
||||
ShowPopup();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (button == MouseButton.Left)
|
||||
{
|
||||
_touchDown = true;
|
||||
if (!IsPopupOpened)
|
||||
Focus();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnTouchDown(Float2 location, int pointerId)
|
||||
{
|
||||
|
||||
@@ -501,6 +501,29 @@ namespace FlaxEngine.GUI
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||
{
|
||||
if (base.OnMouseDoubleClick(location, button))
|
||||
return true;
|
||||
|
||||
_mouseOverHeader = HeaderRectangle.Contains(location);
|
||||
if (button == MouseButton.Left && _mouseOverHeader)
|
||||
{
|
||||
_mouseButtonLeftDown = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (button == MouseButton.Left && _mouseButtonLeftDown)
|
||||
{
|
||||
_mouseButtonLeftDown = false;
|
||||
if (_mouseOverHeader)
|
||||
Toggle();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseLeave()
|
||||
{
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace FlaxEngine.GUI
|
||||
|
||||
// Scrolling
|
||||
|
||||
private float _clickChange = 20, _scrollChange = 100;
|
||||
private float _clickChange = 20, _scrollChange = 50;
|
||||
private float _minimum, _maximum = 100;
|
||||
private float _value, _targetValue;
|
||||
private float _startValue, _value, _targetValue;
|
||||
private readonly Orientation _orientation;
|
||||
private RootControl.UpdateDelegate _update;
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace FlaxEngine.GUI
|
||||
// Smoothing
|
||||
|
||||
private float _thumbOpacity = DefaultMinimumOpacity;
|
||||
private float _scrollAnimationProgress = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the orientation.
|
||||
@@ -59,14 +60,19 @@ namespace FlaxEngine.GUI
|
||||
public float TrackThickness { get; set; } = 2.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value smoothing scale (0 to not use it).
|
||||
/// The maximum time it takes to animate from current to target scroll position
|
||||
/// </summary>
|
||||
public float SmoothingScale { get; set; } = 0.6f;
|
||||
public float ScrollAnimationDuration { get; set; } = 0.18f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether use scroll value smoothing.
|
||||
/// </summary>
|
||||
public bool UseSmoothing => !Mathf.IsZero(SmoothingScale);
|
||||
public bool UseSmoothing => EnableSmoothing && !Mathf.IsZero(ScrollAnimationDuration);
|
||||
|
||||
/// <summary>
|
||||
/// Enables scroll smoothing
|
||||
/// </summary>
|
||||
public bool EnableSmoothing { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum value.
|
||||
@@ -112,11 +118,15 @@ namespace FlaxEngine.GUI
|
||||
if (!Mathf.NearEqual(value, _targetValue))
|
||||
{
|
||||
_targetValue = value;
|
||||
_startValue = _value;
|
||||
_scrollAnimationProgress = 0f;
|
||||
|
||||
// Check if skip smoothing
|
||||
if (!UseSmoothing)
|
||||
{
|
||||
_value = value;
|
||||
_startValue = value;
|
||||
_scrollAnimationProgress = 1f;
|
||||
OnValueChanged();
|
||||
}
|
||||
else
|
||||
@@ -208,7 +218,8 @@ namespace FlaxEngine.GUI
|
||||
{
|
||||
if (!Mathf.NearEqual(_value, _targetValue))
|
||||
{
|
||||
_value = _targetValue;
|
||||
_value = _targetValue = _startValue;
|
||||
_scrollAnimationProgress = 0f;
|
||||
SetUpdate(ref _update, null);
|
||||
OnValueChanged();
|
||||
}
|
||||
@@ -274,7 +285,8 @@ namespace FlaxEngine.GUI
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
_value = _targetValue = 0;
|
||||
_value = _targetValue = _startValue = 0;
|
||||
_scrollAnimationProgress = 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -296,22 +308,39 @@ namespace FlaxEngine.GUI
|
||||
_thumbOpacity = isDeltaSlow ? targetOpacity : Mathf.Lerp(_thumbOpacity, targetOpacity, deltaTime * 10.0f);
|
||||
bool needUpdate = Mathf.Abs(_thumbOpacity - targetOpacity) > 0.001f;
|
||||
|
||||
// Ensure scroll bar is visible
|
||||
if (Visible)
|
||||
// Ensure scroll bar is visible and smoothing is required
|
||||
if (Visible && Mathf.Abs(_targetValue - _value) > 0.01f)
|
||||
{
|
||||
// Value smoothing
|
||||
if (Mathf.Abs(_targetValue - _value) > 0.01f)
|
||||
// Interpolate or not if running slow
|
||||
float value;
|
||||
if (!isDeltaSlow && UseSmoothing)
|
||||
{
|
||||
// Interpolate or not if running slow
|
||||
float value;
|
||||
if (!isDeltaSlow && UseSmoothing)
|
||||
value = Mathf.Lerp(_value, _targetValue, deltaTime * 20.0f * SmoothingScale);
|
||||
else
|
||||
value = _targetValue;
|
||||
_value = value;
|
||||
OnValueChanged();
|
||||
needUpdate = true;
|
||||
// percentage of scroll from 0 to _scrollChange, ex. 0.5 at _scrollChange / 2
|
||||
var minScrollChangeRatio = Mathf.Clamp(Mathf.Abs(_targetValue - _startValue) / _scrollChange, 0, 1);
|
||||
|
||||
// shorten the duration if we scrolled less than _scrollChange
|
||||
var actualDuration = ScrollAnimationDuration * minScrollChangeRatio;
|
||||
var step = deltaTime / actualDuration;
|
||||
|
||||
var progress = _scrollAnimationProgress;
|
||||
progress = Mathf.Clamp(progress + step, 0, 1);
|
||||
|
||||
// https://easings.net/#easeOutSine
|
||||
var easedProgress = Mathf.Sin((progress * Mathf.Pi) / 2);
|
||||
value = Mathf.Lerp(_startValue, _targetValue, easedProgress);
|
||||
|
||||
_scrollAnimationProgress = progress;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = _targetValue;
|
||||
_startValue = _targetValue;
|
||||
_scrollAnimationProgress = 0f;
|
||||
}
|
||||
|
||||
_value = value;
|
||||
OnValueChanged();
|
||||
needUpdate = true;
|
||||
}
|
||||
|
||||
// End updating if all animations are done
|
||||
@@ -371,7 +400,7 @@ namespace FlaxEngine.GUI
|
||||
float mousePosition = _orientation == Orientation.Vertical ? slidePosition.Y : slidePosition.X;
|
||||
|
||||
float percentage = (mousePosition - _mouseOffset - _thumbSize / 2) / (TrackSize - _thumbSize);
|
||||
Value = _minimum + percentage * (_maximum - _minimum);
|
||||
TargetValue = _minimum + percentage * (_maximum - _minimum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,7 +410,7 @@ namespace FlaxEngine.GUI
|
||||
if (ThumbEnabled)
|
||||
{
|
||||
// Scroll
|
||||
Value = _value - delta * _scrollChange;
|
||||
Value = _targetValue - delta * _scrollChange;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user