diff --git a/Source/Editor/SceneGraph/Actors/SplineNode.cs b/Source/Editor/SceneGraph/Actors/SplineNode.cs
index a3ceb66f9..e6ff43e9f 100644
--- a/Source/Editor/SceneGraph/Actors/SplineNode.cs
+++ b/Source/Editor/SceneGraph/Actors/SplineNode.cs
@@ -294,8 +294,6 @@ namespace FlaxEditor.SceneGraph.Actors
private const Real SnapIndicatorSize = 1.7f;
private const Real SnapPointIndicatorSize = 2f;
- private static Spline _currentEditSpline;
-
///
public SplineNode(Actor actor)
: base(actor)
@@ -306,17 +304,19 @@ namespace FlaxEditor.SceneGraph.Actors
private void OnUpdate()
{
- if (Input.Keyboard.GetKey(KeyboardKeys.Shift))
+ // If this node's point is selected
+ var selection = Editor.Instance.SceneEditing.Selection;
+ if (selection.Count == 1 && selection[0] is SplinePointNode selectedPoint && selectedPoint.ParentNode == this)
{
- EditSplineWithSnap();
+ if (Input.Keyboard.GetKey(KeyboardKeys.Shift))
+ EditSplineWithSnap(selectedPoint);
+
+ var canAddSplinePoint = Input.Mouse.PositionDelta == Float2.Zero && Input.Mouse.Position != Float2.Zero;
+ var requestAddSplinePoint = Input.Keyboard.GetKey(KeyboardKeys.Control) && Input.Mouse.GetButtonDown(MouseButton.Right);
+ if (requestAddSplinePoint && canAddSplinePoint)
+ AddSplinePoint(selectedPoint);
}
- var canAddSplinePoint = Input.Mouse.PositionDelta == Float2.Zero && Input.Mouse.Position != Float2.Zero;
- var requestAddSplinePoint = Input.Keyboard.GetKey(KeyboardKeys.Control) && Input.Mouse.GetButtonDown(MouseButton.Right);
-
- if (requestAddSplinePoint && canAddSplinePoint)
- AddSplinePoint();
-
SyncSplineKeyframeWithNodes();
}
@@ -351,20 +351,15 @@ namespace FlaxEditor.SceneGraph.Actors
}
}
- private unsafe void AddSplinePoint()
+ private unsafe void AddSplinePoint(SplinePointNode selectedPoint)
{
- var selectedPoint = GetSelectedSplineNode();
- if (selectedPoint == null)
- return;
-
- // checking mouse hit on scene
+ // Check mouse hit on scene
var spline = (Spline)Actor;
var viewport = Editor.Instance.Windows.EditWin.Viewport;
var mouseRay = viewport.MouseRay;
- var viewRay = new Ray(viewport.ViewPosition, viewport.ViewDirection);
+ var viewRay = viewport.ViewRay;
var flags = RayCastData.FlagTypes.SkipColliders | RayCastData.FlagTypes.SkipEditorPrimitives;
var hit = Editor.Instance.Scene.Root.RayCast(ref mouseRay, ref viewRay, out var closest, out var normal, flags);
-
if (hit == null)
return;
@@ -373,7 +368,7 @@ namespace FlaxEditor.SceneGraph.Actors
var editAction = new EditSplineAction(spline, oldSpline);
Root.Undo.AddAction(editAction);
- // Getting spline point to duplicate
+ // Get spline point to duplicate
var hitPoint = mouseRay.Position + mouseRay.Direction * closest;
var lastPointIndex = selectedPoint.Index;
var newPointIndex = lastPointIndex > 0 ? lastPointIndex + 1 : 0;
@@ -381,24 +376,22 @@ namespace FlaxEditor.SceneGraph.Actors
var isLastPoint = lastPointIndex == spline.SplinePointsCount - 1;
var isFirstPoint = lastPointIndex == 0;
- // Getting data to create new point
-
+ // Get data to create new point
var lastPointTime = spline.GetSplineTime(lastPointIndex);
var nextPointTime = isLastPoint ? lastPointTime : spline.GetSplineTime(newPointIndex);
var newTime = isLastPoint ? lastPointTime + 1.0f : (lastPointTime + nextPointTime) * 0.5f;
var distanceFromLastPoint = Vector3.Distance(hitPoint, spline.GetSplinePoint(lastPointIndex));
var newPointDirection = spline.GetSplineTangent(lastPointIndex, false).Translation - hitPoint;
- // set correctly keyframe direction on spawn point
+ // Set correctly keyframe direction on spawn point
if (isFirstPoint)
newPointDirection = hitPoint - spline.GetSplineTangent(lastPointIndex, true).Translation;
else if (isLastPoint)
newPointDirection = spline.GetSplineTangent(lastPointIndex, false).Translation - hitPoint;
-
var newPointLocalPosition = spline.Transform.WorldToLocal(hitPoint);
var newPointLocalOrientation = Quaternion.LookRotation(newPointDirection);
- // Adding new point
+ // Add new point
spline.InsertSplinePoint(newPointIndex, newTime, Transform.Identity, false);
var newKeyframe = lastKeyframe.DeepClone();
var newKeyframeTransform = newKeyframe.Value;
@@ -406,13 +399,13 @@ namespace FlaxEditor.SceneGraph.Actors
newKeyframeTransform.Orientation = newPointLocalOrientation;
newKeyframe.Value = newKeyframeTransform;
- // Setting new point keyframe
- var newkeyframeTangentIn = Transform.Identity;
- var newkeyframeTangentOut = Transform.Identity;
- newkeyframeTangentIn.Translation = (Vector3.Forward * newPointLocalOrientation) * distanceFromLastPoint;
- newkeyframeTangentOut.Translation = (Vector3.Backward * newPointLocalOrientation) * distanceFromLastPoint;
- newKeyframe.TangentIn = newkeyframeTangentIn;
- newKeyframe.TangentOut = newkeyframeTangentOut;
+ // Set new point keyframe
+ var newKeyframeTangentIn = Transform.Identity;
+ var newKeyframeTangentOut = Transform.Identity;
+ newKeyframeTangentIn.Translation = (Vector3.Forward * newPointLocalOrientation) * distanceFromLastPoint;
+ newKeyframeTangentOut.Translation = (Vector3.Backward * newPointLocalOrientation) * distanceFromLastPoint;
+ newKeyframe.TangentIn = newKeyframeTangentIn;
+ newKeyframe.TangentOut = newKeyframeTangentOut;
spline.SetSplineKeyframe(newPointIndex, newKeyframe);
for (int i = 1; i < spline.SplinePointsCount; i++)
@@ -430,20 +423,13 @@ namespace FlaxEditor.SceneGraph.Actors
spline.UpdateSpline();
}
- private void EditSplineWithSnap()
+ private void EditSplineWithSnap(SplinePointNode selectedPoint)
{
- if (_currentEditSpline == null || _currentEditSpline != Actor)
- return;
-
- var selectedNode = GetSelectedSplineNode();
- if (selectedNode == null)
- return;
-
- var selectedNodeBounds = new BoundingSphere(selectedNode.Transform.Translation, 1f);
- var allSplinesInView = GetSplinesOnView();
- allSplinesInView.Remove(_currentEditSpline);
-
- if (allSplinesInView.Count == 0 || selectedNode == null)
+ var spline = (Spline)Actor;
+ var selectedPointBounds = new BoundingSphere(selectedPoint.Transform.Translation, 1f);
+ var allSplinesInView = GetSplinesInView();
+ allSplinesInView.Remove(spline);
+ if (allSplinesInView.Count == 0)
return;
var snappedOnSplinePoint = false;
@@ -456,9 +442,9 @@ namespace FlaxEditor.SceneGraph.Actors
var keyframeBounds = new BoundingSphere(keyframePosition, pointIndicatorSize);
DebugDraw.DrawSphere(keyframeBounds, Color.Red, 0, false);
- if (keyframeBounds.Intersects(selectedNodeBounds))
+ if (keyframeBounds.Intersects(selectedPointBounds))
{
- _currentEditSpline.SetSplinePoint(selectedNode.Index, keyframeBounds.Center);
+ spline.SetSplinePoint(selectedPoint.Index, keyframeBounds.Center);
snappedOnSplinePoint = true;
break;
}
@@ -467,15 +453,13 @@ namespace FlaxEditor.SceneGraph.Actors
if (!snappedOnSplinePoint)
{
- var nearSplineSnapPoint = GetNearSplineSnapPosition(selectedNode.Transform.Translation, allSplinesInView);
+ var nearSplineSnapPoint = GetNearSplineSnapPosition(selectedPoint.Transform.Translation, allSplinesInView);
var snapIndicatorSize = NodeSizeByDistance(nearSplineSnapPoint, SnapIndicatorSize);
var snapBounds = new BoundingSphere(nearSplineSnapPoint, snapIndicatorSize);
-
- if (snapBounds.Intersects(selectedNodeBounds))
+ if (snapBounds.Intersects(selectedPointBounds))
{
- _currentEditSpline.SetSplinePoint(selectedNode.Index, snapBounds.Center);
+ spline.SetSplinePoint(selectedPoint.Index, snapBounds.Center);
}
-
DebugDraw.DrawSphere(snapBounds, Color.Yellow, 0, true);
}
}
@@ -494,14 +478,12 @@ namespace FlaxEditor.SceneGraph.Actors
var spline = (Spline)Actor;
spline.AddSplineLocalPoint(Vector3.Zero, false);
spline.AddSplineLocalPoint(new Vector3(0, 0, 100.0f));
-
spline.SetSplineKeyframe(0, new BezierCurve.Keyframe()
{
Value = new Transform(Vector3.Zero, Quaternion.Identity, Vector3.One),
TangentIn = new Transform(Vector3.Backward * 100, Quaternion.Identity, Vector3.One),
TangentOut = new Transform(Vector3.Forward * 100, Quaternion.Identity, Vector3.One),
});
-
spline.SetSplineKeyframe(1, new BezierCurve.Keyframe()
{
Value = new Transform(Vector3.Forward * 100, Quaternion.Identity, Vector3.One),
@@ -553,7 +535,6 @@ namespace FlaxEditor.SceneGraph.Actors
internal static void OnSplineEdited(Spline spline)
{
- _currentEditSpline = spline;
var collider = spline.GetChild();
if (collider && collider.Scene && collider.IsActiveInHierarchy && collider.HasStaticFlag(StaticFlags.Navigation) && !Editor.IsPlayMode)
{
@@ -565,39 +546,18 @@ namespace FlaxEditor.SceneGraph.Actors
}
}
- private static SplinePointNode GetSelectedSplineNode()
+ private static List GetSplinesInView()
{
- var selection = Editor.Instance.SceneEditing.Selection;
- if (selection.Count != 1)
- return null;
- if (selection[0] is not SplineNode.SplinePointNode)
- return null;
-
- return (SplinePointNode)selection[0];
- }
-
- private static List GetSplinesOnView()
- {
- var splines = Level.GetActors();
- var splinesOnView = new List();
-
- var viewTransform = Editor.Instance.Windows.EditWin.Viewport.ViewTransform;
- var viewFov = Editor.Instance.Windows.EditWin.Viewport.FieldOfView;
- var viewNear = Editor.Instance.Windows.EditWin.Viewport.NearPlane;
- var viewFar = Editor.Instance.Windows.EditWin.Viewport.FarPlane;
- var viewAspect = Editor.Instance.Windows.EditWin.Width / Editor.Instance.Windows.EditWin.Height;
- var viewBounds = BoundingFrustum.FromCamera(viewTransform.Translation, viewTransform.Forward, viewTransform.Up, viewFov, viewNear, viewFar, viewAspect);
-
+ var splines = Level.GetActors(true);
+ var result = new List();
+ var viewBounds = Editor.Instance.Windows.EditWin.Viewport.ViewFrustum;
foreach (var s in splines)
{
var contains = viewBounds.Contains(s.EditorBox);
if (contains == ContainmentType.Contains || contains == ContainmentType.Intersects)
- {
- splinesOnView.Add(s);
- }
+ result.Add(s);
}
-
- return splinesOnView;
+ return result;
}
private static Vector3 GetNearSplineSnapPosition(Vector3 position, List splines)
diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs
index 526a84c45..759c3736a 100644
--- a/Source/Editor/Viewport/EditorViewport.cs
+++ b/Source/Editor/Viewport/EditorViewport.cs
@@ -334,6 +334,22 @@ namespace FlaxEditor.Viewport
}
}
+ ///
+ /// Gets the bounding frustum of the current viewport camera.
+ ///
+ public BoundingFrustum ViewFrustum
+ {
+ get
+ {
+ Vector3 viewOrigin = Task.View.Origin;
+ Float3 position = ViewPosition - viewOrigin;
+ CreateViewMatrix(position, out var view);
+ CreateProjectionMatrix(out var projection);
+ Matrix.Multiply(ref view, ref projection, out var viewProjection);
+ return new BoundingFrustum(ref viewProjection);
+ }
+ }
+
///
/// Gets or sets the yaw angle (in degrees).
///
diff --git a/Source/Engine/Core/Math/BoundingFrustum.cs b/Source/Engine/Core/Math/BoundingFrustum.cs
index 970957fbb..25cd0c33b 100644
--- a/Source/Engine/Core/Math/BoundingFrustum.cs
+++ b/Source/Engine/Core/Math/BoundingFrustum.cs
@@ -104,6 +104,16 @@ namespace FlaxEngine
GetPlanesFromMatrix(ref pMatrix, out pNear, out pFar, out pLeft, out pRight, out pTop, out pBottom);
}
+ ///
+ /// Creates a new instance of BoundingFrustum.
+ ///
+ /// Combined matrix that usually takes view × projection matrix.
+ public BoundingFrustum(ref Matrix matrix)
+ {
+ pMatrix = matrix;
+ GetPlanesFromMatrix(ref pMatrix, out pNear, out pFar, out pLeft, out pRight, out pTop, out pBottom);
+ }
+
///
/// Returns a hash code for this instance.
///
diff --git a/Source/Engine/Graphics/RenderView.cs b/Source/Engine/Graphics/RenderView.cs
index b770037a3..72cfe3577 100644
--- a/Source/Engine/Graphics/RenderView.cs
+++ b/Source/Engine/Graphics/RenderView.cs
@@ -27,7 +27,7 @@ namespace FlaxEngine
Matrix.Invert(ref View, out IV);
Matrix.Invert(ref Projection, out IP);
Matrix.Multiply(ref View, ref Projection, out var viewProjection);
- Frustum = new BoundingFrustum(viewProjection);
+ Frustum = new BoundingFrustum(ref viewProjection);
Matrix.Invert(ref viewProjection, out IVP);
CullingFrustum = Frustum;
}
diff --git a/Source/Engine/UI/UICanvas.cs b/Source/Engine/UI/UICanvas.cs
index bc8c360d1..dda941745 100644
--- a/Source/Engine/UI/UICanvas.cs
+++ b/Source/Engine/UI/UICanvas.cs
@@ -450,7 +450,7 @@ namespace FlaxEngine
{
camera.GetMatrices(out tmp1, out var tmp3, ref viewport);
Matrix.Multiply(ref tmp1, ref tmp3, out tmp2);
- var frustum = new BoundingFrustum(tmp2);
+ var frustum = new BoundingFrustum(ref tmp2);
_guiRoot.Size = new Float2(frustum.GetWidthAtDepth(Distance), frustum.GetHeightAtDepth(Distance));
}
else