Merge commit '272ffe2ea22eecb8f7cd6662efc1cadbe5593feb' into dotnet7
This commit is contained in:
@@ -174,9 +174,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
for (int i = 0; i < subInputs.Length; i++)
|
||||
{
|
||||
if (string.IsNullOrEmpty(subInputs[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check all entered subtags and create any that dont exist
|
||||
for (int j = 0; j <= i; j++)
|
||||
@@ -296,6 +294,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
settingsObj.Tags.Add(tagName);
|
||||
settingsObj.Tags.Sort();
|
||||
settingsAsset.SetInstance(settingsObj);
|
||||
settingsAsset.Save();
|
||||
|
||||
// Reload editor window to reflect new tag
|
||||
assetWindow?.RefreshAsset();
|
||||
@@ -417,7 +416,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
if (!uniqueText)
|
||||
return;
|
||||
|
||||
OnAddTagButtonClicked(nameTextBox.Text, tree, nameTextBox, addTagDropPanel, pickerData);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#if PLATFORM_WINDOWS
|
||||
#define USE_IS_FOREGROUND
|
||||
#else
|
||||
#endif
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
@@ -326,6 +330,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
#if USE_IS_FOREGROUND
|
||||
/// <summary>
|
||||
/// Returns true if context menu is in foreground (eg. context window or any child window has user focus or user opened additional popup within this context).
|
||||
/// </summary>
|
||||
@@ -385,6 +390,57 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
private void OnWindowGotFocus()
|
||||
{
|
||||
}
|
||||
|
||||
private void OnWindowLostFocus()
|
||||
{
|
||||
// Skip for parent menus (child should handle lost of focus)
|
||||
if (_childCM != null)
|
||||
return;
|
||||
|
||||
if (_parentCM != null)
|
||||
{
|
||||
if (IsMouseOver)
|
||||
return;
|
||||
|
||||
// Check if any external popup is focused
|
||||
foreach (var externalPopup in ExternalPopups)
|
||||
{
|
||||
if (externalPopup && externalPopup.IsFocused)
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if mouse is over any of the parents
|
||||
ContextMenuBase focusCM = null;
|
||||
var cm = _parentCM;
|
||||
while (cm != null)
|
||||
{
|
||||
if (cm.IsMouseOver)
|
||||
focusCM = cm;
|
||||
cm = cm._parentCM;
|
||||
}
|
||||
|
||||
if (focusCM != null)
|
||||
{
|
||||
// Focus on the clicked parent and hide any open sub-menus
|
||||
focusCM.HideChild();
|
||||
focusCM._window?.Focus();
|
||||
}
|
||||
else
|
||||
{
|
||||
// User clicked outside the context menus, hide the whole context menu tree
|
||||
TopmostCM.Hide();
|
||||
}
|
||||
}
|
||||
else if (!IsMouseOver)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsMouseOver
|
||||
@@ -405,6 +461,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_IS_FOREGROUND
|
||||
/// <inheritdoc />
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
@@ -416,6 +473,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw()
|
||||
|
||||
@@ -55,8 +55,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseEnter(Float2 location)
|
||||
{
|
||||
base.OnMouseEnter(location);
|
||||
|
||||
// Skip if has no children
|
||||
if (ContextMenu.HasChildren == false)
|
||||
return;
|
||||
@@ -66,8 +64,28 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
if (parentContextMenu == ContextMenu)
|
||||
return;
|
||||
|
||||
if (ContextMenu.IsOpened)
|
||||
return;
|
||||
|
||||
base.OnMouseEnter(location);
|
||||
|
||||
// Hide parent CM popups and set itself as child
|
||||
parentContextMenu.ShowChild(ContextMenu, PointToParent(ParentContextMenu, new Float2(Width, 0)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
// Skip if already shown
|
||||
var parentContextMenu = ParentContextMenu;
|
||||
if (parentContextMenu == ContextMenu)
|
||||
return true;
|
||||
if (ContextMenu.IsOpened)
|
||||
return true;
|
||||
|
||||
// Hide parent CM popups and set itself as child
|
||||
parentContextMenu.ShowChild(ContextMenu, PointToParent(ParentContextMenu, new Float2(Width, 0)));
|
||||
return base.OnMouseUp(location, button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,6 +700,8 @@ namespace FlaxEditor.GUI.Tree
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
UpdateMouseOverFlags(location);
|
||||
|
||||
// Check if mouse hits bar and node isn't a root
|
||||
if (_mouseOverHeader)
|
||||
{
|
||||
@@ -728,6 +730,8 @@ namespace FlaxEditor.GUI.Tree
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
UpdateMouseOverFlags(location);
|
||||
|
||||
// Clear flag for left button
|
||||
if (button == MouseButton.Left)
|
||||
{
|
||||
@@ -815,21 +819,7 @@ namespace FlaxEditor.GUI.Tree
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMove(Float2 location)
|
||||
{
|
||||
// Cache flags
|
||||
_mouseOverArrow = HasAnyVisibleChild && ArrowRect.Contains(location);
|
||||
_mouseOverHeader = new Rectangle(0, 0, Width, _headerHeight - 1).Contains(location);
|
||||
if (_mouseOverHeader)
|
||||
{
|
||||
// Allow non-scrollable controls to stay on top of the header and override the mouse behaviour
|
||||
for (int i = 0; i < Children.Count; i++)
|
||||
{
|
||||
if (!Children[i].IsScrollable && IntersectsChildContent(Children[i], location, out _))
|
||||
{
|
||||
_mouseOverHeader = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateMouseOverFlags(location);
|
||||
|
||||
// Check if start drag and drop
|
||||
if (_isMouseDown && Float2.Distance(_mouseDownPos, location) > 10.0f)
|
||||
@@ -852,6 +842,25 @@ namespace FlaxEditor.GUI.Tree
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMouseOverFlags(Vector2 location)
|
||||
{
|
||||
// Cache flags
|
||||
_mouseOverArrow = HasAnyVisibleChild && ArrowRect.Contains(location);
|
||||
_mouseOverHeader = new Rectangle(0, 0, Width, _headerHeight - 1).Contains(location);
|
||||
if (_mouseOverHeader)
|
||||
{
|
||||
// Allow non-scrollable controls to stay on top of the header and override the mouse behaviour
|
||||
for (int i = 0; i < Children.Count; i++)
|
||||
{
|
||||
if (!Children[i].IsScrollable && IntersectsChildContent(Children[i], location, out _))
|
||||
{
|
||||
_mouseOverHeader = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseLeave()
|
||||
{
|
||||
|
||||
@@ -6,44 +6,48 @@ namespace FlaxEditor.Gizmo
|
||||
{
|
||||
public partial class TransformGizmoBase
|
||||
{
|
||||
private Model _modelTranslateAxis;
|
||||
// Models
|
||||
private Model _modelTranslationAxis;
|
||||
private Model _modelScaleAxis;
|
||||
private Model _modelBox;
|
||||
private Model _modelCircle;
|
||||
private Model _modelRotationAxis;
|
||||
private Model _modelSphere;
|
||||
private Model _modelCube;
|
||||
|
||||
// Materials
|
||||
private MaterialInstance _materialAxisX;
|
||||
private MaterialInstance _materialAxisY;
|
||||
private MaterialInstance _materialAxisZ;
|
||||
private MaterialInstance _materialAxisFocus;
|
||||
private MaterialBase _materialWire;
|
||||
private MaterialBase _materialWireFocus;
|
||||
private MaterialBase _materialSphere;
|
||||
|
||||
private void InitDrawing()
|
||||
{
|
||||
// Load content (but async - don't wait and don't block execution)
|
||||
_modelTranslateAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/TranslateAxis");
|
||||
// Axis Models
|
||||
_modelTranslationAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/TranslationAxis");
|
||||
_modelScaleAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/ScaleAxis");
|
||||
_modelBox = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/WireBox");
|
||||
_modelCircle = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/WireCircle");
|
||||
_modelRotationAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/RotationAxis");
|
||||
_modelSphere = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Primitives/Sphere");
|
||||
_modelCube = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Primitives/Cube");
|
||||
|
||||
// Axis Materials
|
||||
_materialAxisX = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisX");
|
||||
_materialAxisY = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisY");
|
||||
_materialAxisZ = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisZ");
|
||||
_materialAxisFocus = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisFocus");
|
||||
_materialWire = FlaxEngine.Content.LoadAsyncInternal<MaterialBase>("Editor/Gizmo/MaterialWire");
|
||||
_materialWireFocus = FlaxEngine.Content.LoadAsyncInternal<MaterialBase>("Editor/Gizmo/MaterialWireFocus");
|
||||
_materialSphere = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialSphere");
|
||||
|
||||
// Ensure that every asset was loaded
|
||||
if (_modelTranslateAxis == null ||
|
||||
if (_modelTranslationAxis == null ||
|
||||
_modelScaleAxis == null ||
|
||||
_modelBox == null ||
|
||||
_modelCircle == null ||
|
||||
_modelRotationAxis == null ||
|
||||
_modelSphere == null ||
|
||||
_modelCube == null ||
|
||||
_materialAxisX == null ||
|
||||
_materialAxisY == null ||
|
||||
_materialAxisZ == null ||
|
||||
_materialAxisFocus == null ||
|
||||
_materialWire == null ||
|
||||
_materialWireFocus == null)
|
||||
_materialSphere == null)
|
||||
{
|
||||
// Error
|
||||
Platform.Fatal("Failed to load transform gizmo resources.");
|
||||
}
|
||||
}
|
||||
@@ -58,6 +62,8 @@ namespace FlaxEditor.Gizmo
|
||||
// https://github.com/FlaxEngine/FlaxEngine/issues/680
|
||||
|
||||
Matrix m1, m2, m3, mx1;
|
||||
float boxScale = 300f;
|
||||
float boxSize = 0.085f;
|
||||
bool isXAxis = _activeAxis == Axis.X || _activeAxis == Axis.XY || _activeAxis == Axis.ZX;
|
||||
bool isYAxis = _activeAxis == Axis.Y || _activeAxis == Axis.XY || _activeAxis == Axis.YZ;
|
||||
bool isZAxis = _activeAxis == Axis.Z || _activeAxis == Axis.YZ || _activeAxis == Axis.ZX;
|
||||
@@ -65,114 +71,137 @@ namespace FlaxEditor.Gizmo
|
||||
renderContext.View.GetWorldMatrix(ref _gizmoWorld, out Matrix world);
|
||||
|
||||
const float gizmoModelsScale2RealGizmoSize = 0.075f;
|
||||
Mesh sphereMesh, cubeMesh;
|
||||
switch (_activeMode)
|
||||
{
|
||||
case Mode.Translate:
|
||||
{
|
||||
if (!_modelTranslateAxis || !_modelTranslateAxis.IsLoaded || !_modelBox || !_modelBox.IsLoaded)
|
||||
if (!_modelTranslationAxis || !_modelTranslationAxis.IsLoaded || !_modelCube || !_modelCube.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded)
|
||||
break;
|
||||
var transAxisMesh = _modelTranslationAxis.LODs[0].Meshes[0];
|
||||
cubeMesh = _modelCube.LODs[0].Meshes[0];
|
||||
sphereMesh = _modelSphere.LODs[0].Meshes[0];
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
|
||||
Matrix.Multiply(ref m3, ref world, out m1);
|
||||
mx1 = m1;
|
||||
mx1.M41 += 0.05f;
|
||||
var axisMesh = _modelTranslateAxis.LODs[0].Meshes[0];
|
||||
var boxMesh = _modelBox.LODs[0].Meshes[0];
|
||||
var boxSize = 10.0f;
|
||||
|
||||
// XY plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, 1.0f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * 0.5f, boxSize * 0.5f, 0.0f));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
boxMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialWireFocus : _materialWire, ref m3);
|
||||
|
||||
// ZX plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, 1.0f, boxSize), Quaternion.Identity, new Vector3(boxSize * 0.5f, 0.0f, boxSize * 0.5f));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
boxMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialWireFocus : _materialWire, ref m3);
|
||||
|
||||
// YZ plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, 1.0f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * 0.5f, boxSize * 0.5f));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
boxMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialWireFocus : _materialWire, ref m3);
|
||||
|
||||
// X axis
|
||||
axisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref mx1);
|
||||
|
||||
// Y axis
|
||||
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
axisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3);
|
||||
|
||||
// Z axis
|
||||
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
axisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
|
||||
transAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3);
|
||||
|
||||
// Y axis
|
||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
transAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3);
|
||||
|
||||
// Z axis
|
||||
Matrix.RotationX(Mathf.Pi, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
transAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
|
||||
|
||||
// XY plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3);
|
||||
|
||||
// ZX plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3);
|
||||
|
||||
// YZ plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3);
|
||||
|
||||
// Center sphere
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Mode.Rotate:
|
||||
{
|
||||
if (!_modelCircle || !_modelCircle.IsLoaded || !_modelBox || !_modelBox.IsLoaded)
|
||||
if (!_modelRotationAxis || !_modelRotationAxis.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded)
|
||||
break;
|
||||
var circleMesh = _modelCircle.LODs[0].Meshes[0];
|
||||
var boxMesh = _modelBox.LODs[0].Meshes[0];
|
||||
Matrix.Scaling(8.0f, out m3);
|
||||
var rotationAxisMesh = _modelRotationAxis.LODs[0].Meshes[0];
|
||||
sphereMesh = _modelSphere.LODs[0].Meshes[0];
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
|
||||
Matrix.Multiply(ref m3, ref world, out m1);
|
||||
mx1 = m1;
|
||||
mx1.M41 += 0.05f;
|
||||
|
||||
// X axis
|
||||
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
circleMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3);
|
||||
rotationAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3);
|
||||
|
||||
// Y axis
|
||||
circleMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m1);
|
||||
rotationAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m1);
|
||||
|
||||
// Z axis
|
||||
Matrix.RotationX(-Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
circleMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
|
||||
rotationAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
|
||||
|
||||
// Center box
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
|
||||
Matrix.Multiply(ref m3, ref world, out m1);
|
||||
Matrix.Scaling(1.0f, out m2);
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
boxMesh.Draw(ref renderContext, isCenter ? _materialWireFocus : _materialWire, ref m3);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Mode.Scale:
|
||||
{
|
||||
if (!_modelScaleAxis || !_modelScaleAxis.IsLoaded || !_modelBox || !_modelBox.IsLoaded)
|
||||
if (!_modelScaleAxis || !_modelScaleAxis.IsLoaded || !_modelCube || !_modelCube.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded)
|
||||
break;
|
||||
var scaleAxisMesh = _modelScaleAxis.LODs[0].Meshes[0];
|
||||
cubeMesh = _modelCube.LODs[0].Meshes[0];
|
||||
sphereMesh = _modelSphere.LODs[0].Meshes[0];
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
|
||||
Matrix.Multiply(ref m3, ref world, out m1);
|
||||
mx1 = m1;
|
||||
mx1.M41 -= 0.05f;
|
||||
|
||||
var axisMesh = _modelScaleAxis.LODs[0].Meshes[0];
|
||||
var boxMesh = _modelBox.LODs[0].Meshes[0];
|
||||
|
||||
// X axis
|
||||
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref mx1, out m3);
|
||||
axisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3);
|
||||
scaleAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3);
|
||||
|
||||
// Y axis
|
||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
axisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3);
|
||||
scaleAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3);
|
||||
|
||||
// Z axis
|
||||
Matrix.RotationX(Mathf.Pi, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
axisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
|
||||
scaleAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
|
||||
|
||||
// XY plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3);
|
||||
|
||||
// ZX plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3);
|
||||
|
||||
// YZ plane
|
||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3);
|
||||
|
||||
// Center box
|
||||
Matrix.Scaling(10.0f, out m2);
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
boxMesh.Draw(ref renderContext, isCenter ? _materialWireFocus : _materialWire, ref m3);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -102,9 +102,15 @@ namespace FlaxEditor.Gizmo
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
|
||||
/*// Center
|
||||
if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
||||
{
|
||||
_activeAxis = Axis.Center;
|
||||
closestIntersection = intersection;
|
||||
}*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Mode.Rotate:
|
||||
{
|
||||
// Circles
|
||||
@@ -124,41 +130,53 @@ namespace FlaxEditor.Gizmo
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
|
||||
// Center
|
||||
/*if (CenterSphere.Intersects(ref ray, out intersection) && intersection < closestintersection)
|
||||
{
|
||||
_activeAxis = Axis.Center;
|
||||
closestintersection = intersection;
|
||||
}*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Mode.Scale:
|
||||
{
|
||||
// Spheres collision
|
||||
if (ScaleXSphere.Intersects(ref ray, out intersection) && intersection < closestIntersection)
|
||||
// Boxes collision
|
||||
if (XAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
|
||||
{
|
||||
_activeAxis = Axis.X;
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
if (ScaleYSphere.Intersects(ref ray, out intersection) && intersection < closestIntersection)
|
||||
if (YAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
|
||||
{
|
||||
_activeAxis = Axis.Y;
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
if (ScaleZSphere.Intersects(ref ray, out intersection) && intersection < closestIntersection)
|
||||
if (ZAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
|
||||
{
|
||||
_activeAxis = Axis.Z;
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
|
||||
// Center
|
||||
if (CenterBox.Intersects(ref ray, out intersection) && intersection < closestIntersection)
|
||||
// Quad planes collision
|
||||
if (closestIntersection >= float.MaxValue)
|
||||
closestIntersection = float.MinValue;
|
||||
|
||||
if (XYBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
||||
{
|
||||
_activeAxis = Axis.XY;
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
if (XZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
||||
{
|
||||
_activeAxis = Axis.ZX;
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
if (YZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
||||
{
|
||||
_activeAxis = Axis.YZ;
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
|
||||
/*// Center
|
||||
if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
|
||||
{
|
||||
_activeAxis = Axis.Center;
|
||||
closestIntersection = intersection;
|
||||
}
|
||||
}*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7,56 +7,53 @@ namespace FlaxEditor.Gizmo
|
||||
{
|
||||
public partial class TransformGizmoBase
|
||||
{
|
||||
private const float GizmoScaleFactor = 18;
|
||||
private const float LineLength = 3.0f;
|
||||
private const float LineOffset = 1.0f;
|
||||
private const float MultiAxisThickness = 0.05f;
|
||||
private const float SingleAxisThickness = 0.3f;
|
||||
private const float ScaleSpheresRadius = 0.7f;
|
||||
private const float CenterBoxSize = 0.8f;
|
||||
private const float CenterSphereRadius = 0.1f;
|
||||
private const float HalfLineOffset = LineOffset / 2;
|
||||
/// <summary>
|
||||
/// Scale of the gizmo itself
|
||||
/// </summary>
|
||||
private const float GizmoScaleFactor = 24;
|
||||
|
||||
private readonly Vector3[] _translationLineVertices =
|
||||
{
|
||||
// -- X Axis -- // index 0 - 5
|
||||
new Vector3(HalfLineOffset, 0, 0),
|
||||
new Vector3(LineLength, 0, 0),
|
||||
new Vector3(LineOffset, 0, 0),
|
||||
new Vector3(LineOffset, LineOffset, 0),
|
||||
new Vector3(LineOffset, 0, 0),
|
||||
new Vector3(LineOffset, 0, LineOffset),
|
||||
/// <summary>
|
||||
/// The length of each axis (outwards)
|
||||
/// </summary>
|
||||
private const float AxisLength = 3.5f;
|
||||
|
||||
// -- Y Axis -- // index 6 - 11
|
||||
new Vector3(0, HalfLineOffset, 0),
|
||||
new Vector3(0, LineLength, 0),
|
||||
new Vector3(0, LineOffset, 0),
|
||||
new Vector3(LineOffset, LineOffset, 0),
|
||||
new Vector3(0, LineOffset, 0),
|
||||
new Vector3(0, LineOffset, LineOffset),
|
||||
/// <summary>
|
||||
/// Offset to move axis away from center
|
||||
/// </summary>
|
||||
private const float AxisOffset = 0.8f;
|
||||
|
||||
// -- Z Axis -- // index 12 - 17
|
||||
new Vector3(0, 0, HalfLineOffset),
|
||||
new Vector3(0, 0, LineLength),
|
||||
new Vector3(0, 0, LineOffset),
|
||||
new Vector3(LineOffset, 0, LineOffset),
|
||||
new Vector3(0, 0, LineOffset),
|
||||
new Vector3(0, LineOffset, LineOffset)
|
||||
};
|
||||
/// <summary>
|
||||
/// How thick the axis should be
|
||||
/// </summary>
|
||||
private const float AxisThickness = 0.3f;
|
||||
|
||||
private BoundingBox XAxisBox = new BoundingBox(new Vector3(LineOffset, -SingleAxisThickness, -SingleAxisThickness), new Vector3(LineOffset + LineLength, SingleAxisThickness, SingleAxisThickness));
|
||||
private BoundingBox YAxisBox = new BoundingBox(new Vector3(-SingleAxisThickness, LineOffset, -SingleAxisThickness), new Vector3(SingleAxisThickness, LineOffset + LineLength, SingleAxisThickness));
|
||||
private BoundingBox ZAxisBox = new BoundingBox(new Vector3(-SingleAxisThickness, -SingleAxisThickness, LineOffset), new Vector3(SingleAxisThickness, SingleAxisThickness, LineOffset + LineLength));
|
||||
private BoundingBox XZBox = new BoundingBox(Vector3.Zero, new Vector3(LineOffset, MultiAxisThickness, LineOffset));
|
||||
private BoundingBox XYBox = new BoundingBox(Vector3.Zero, new Vector3(LineOffset, LineOffset, MultiAxisThickness));
|
||||
private BoundingBox YZBox = new BoundingBox(Vector3.Zero, new Vector3(MultiAxisThickness, LineOffset, LineOffset));
|
||||
private BoundingBox CenterBoxRaw = new BoundingBox(new Vector3(-0.5f * CenterBoxSize), new Vector3(0.5f * CenterBoxSize));
|
||||
private float RotateRadiusRaw = 4.0f;
|
||||
/// <summary>
|
||||
/// Center box scale
|
||||
/// </summary>
|
||||
private const float CenterBoxScale = 0.8f;
|
||||
|
||||
private BoundingSphere ScaleXSphere => new BoundingSphere(Vector3.Transform(_translationLineVertices[1], _gizmoWorld), ScaleSpheresRadius * _screenScale);
|
||||
private BoundingSphere ScaleYSphere => new BoundingSphere(Vector3.Transform(_translationLineVertices[7], _gizmoWorld), ScaleSpheresRadius * _screenScale);
|
||||
private BoundingSphere ScaleZSphere => new BoundingSphere(Vector3.Transform(_translationLineVertices[13], _gizmoWorld), ScaleSpheresRadius * _screenScale);
|
||||
/// <summary>
|
||||
/// The inner minimum of the multiscale
|
||||
/// </summary>
|
||||
private const float InnerExtend = AxisOffset + 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// The outer maximum of the multiscale
|
||||
/// </summary>
|
||||
private const float OuterExtend = AxisOffset * 3.5f;
|
||||
|
||||
// Cube with the size AxisThickness, then moves it along the axis (AxisThickness) and finally makes it really long (AxisLength)
|
||||
private BoundingBox XAxisBox = new BoundingBox(new Vector3(-AxisThickness), new Vector3(AxisThickness)).MakeOffsetted(AxisOffset * Vector3.UnitX).Merge(AxisLength * Vector3.UnitX);
|
||||
private BoundingBox YAxisBox = new BoundingBox(new Vector3(-AxisThickness), new Vector3(AxisThickness)).MakeOffsetted(AxisOffset * Vector3.UnitY).Merge(AxisLength * Vector3.UnitY);
|
||||
private BoundingBox ZAxisBox = new BoundingBox(new Vector3(-AxisThickness), new Vector3(AxisThickness)).MakeOffsetted(AxisOffset * Vector3.UnitZ).Merge(AxisLength * Vector3.UnitZ);
|
||||
|
||||
private BoundingBox XZBox = new BoundingBox(new Vector3(InnerExtend, 0, InnerExtend), new Vector3(OuterExtend, 0, OuterExtend));
|
||||
private BoundingBox XYBox = new BoundingBox(new Vector3(InnerExtend, InnerExtend, 0), new Vector3(OuterExtend, OuterExtend, 0));
|
||||
private BoundingBox YZBox = new BoundingBox(new Vector3(0, InnerExtend, InnerExtend), new Vector3(0, OuterExtend, OuterExtend));
|
||||
|
||||
private BoundingBox CenterBoxRaw = new BoundingBox(new Vector3(-0.5f * CenterBoxScale), new Vector3(0.5f * CenterBoxScale));
|
||||
private OrientedBoundingBox CenterBox => new OrientedBoundingBox(CenterBoxRaw) * _gizmoWorld;
|
||||
private const float RotateRadiusRaw = 4.0f;
|
||||
|
||||
private Mode _activeMode = Mode.Translate;
|
||||
private Axis _activeAxis = Axis.None;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace
|
||||
// Load product info
|
||||
Array<byte> productInfoData;
|
||||
const String productInfoPath = directory / TEXT("product-info.json");
|
||||
if (File::ReadAllBytes(productInfoPath, productInfoData))
|
||||
if (!FileSystem::FileExists(productInfoPath) || File::ReadAllBytes(productInfoPath, productInfoData))
|
||||
return;
|
||||
rapidjson_flax::Document document;
|
||||
document.Parse((char*)productInfoData.Get(), productInfoData.Count());
|
||||
@@ -193,6 +193,7 @@ void RiderCodeEditor::FindEditors(Array<CodeEditor*>* output)
|
||||
// TODO: detect Snap installations
|
||||
// TODO: detect by reading the jetbrains-rider.desktop file from ~/.local/share/applications and /usr/share/applications?
|
||||
|
||||
SearchDirectory(&installations, TEXT("/usr/share/rider/"));
|
||||
FileSystem::GetChildDirectories(subDirectories, TEXT("/usr/share/rider"));
|
||||
|
||||
// Default suggested location for standalone installations
|
||||
|
||||
@@ -543,19 +543,22 @@ bool EditorUtilities::GetTexture(const Guid& textureId, TextureData& textureData
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: disable streaming for a texture or set max quality override
|
||||
int32 waits = 1000;
|
||||
const auto targetResidency = texture->StreamingTexture()->GetMaxResidency();
|
||||
ASSERT(targetResidency > 0);
|
||||
while (targetResidency != texture->StreamingTexture()->GetCurrentResidency() && waits-- > 0)
|
||||
const bool useGPU = texture->IsVirtual();
|
||||
if (useGPU)
|
||||
{
|
||||
Platform::Sleep(10);
|
||||
int32 waits = 1000;
|
||||
const auto targetResidency = texture->StreamingTexture()->GetMaxResidency();
|
||||
ASSERT(targetResidency > 0);
|
||||
while (targetResidency != texture->StreamingTexture()->GetCurrentResidency() && waits-- > 0)
|
||||
{
|
||||
Platform::Sleep(10);
|
||||
}
|
||||
|
||||
// Get texture data from GPU
|
||||
if (!texture->GetTexture()->DownloadData(textureData))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get texture data from GPU
|
||||
if (!texture->GetTexture()->DownloadData(textureData))
|
||||
return false;
|
||||
|
||||
// Get texture data from asset
|
||||
if (!texture->GetTextureData(textureData))
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user