Add support for spline point duplicate via Transform gizmo

This commit is contained in:
Wojtek Figat
2021-02-01 16:04:20 +01:00
parent b22805f866
commit c3d9c52f1f
3 changed files with 80 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System;
using FlaxEditor.Modules;
using FlaxEngine;
using FlaxEngine.Json;
using Object = FlaxEngine.Object;
@@ -27,6 +28,8 @@ namespace FlaxEditor.SceneGraph.Actors
public override bool CanBeSelectedDirectly => true;
public override bool CanDuplicate => true;
public override bool CanDelete => true;
public override bool CanUseState => true;
@@ -45,7 +48,7 @@ namespace FlaxEditor.SceneGraph.Actors
}
}
private struct Data
struct Data
{
public Guid Spline;
public int Index;
@@ -78,6 +81,69 @@ namespace FlaxEditor.SceneGraph.Actors
actor.RemoveSplinePoint(Index);
}
class DuplicateUndoAction : IUndoAction, ISceneEditAction
{
public Guid SplineId;
public int Index;
public float Time;
public Transform Value;
public string ActionString => "Duplicate spline point";
public void Dispose()
{
}
public void Do()
{
var spline = Object.Find<Spline>(ref SplineId);
spline.InsertSplineLocalPoint(Index, Time, Value);
}
public void Undo()
{
var spline = Object.Find<Spline>(ref SplineId);
spline.RemoveSplinePoint(Index);
}
public void MarkSceneEdited(SceneModule sceneModule)
{
var spline = Object.Find<Spline>(ref SplineId);
sceneModule.MarkSceneEdited(spline.Scene);
}
}
public override SceneGraphNode Duplicate(out IUndoAction undoAction)
{
var actor = (Spline)_node.Actor;
int newIndex;
float newTime;
if (Index == actor.SplinePointsCount - 1)
{
// Append to the end
newIndex = actor.SplinePointsCount;
newTime = actor.GetSplineTime(newIndex - 1) + 1.0f;
}
else
{
// Insert between this and next point
newIndex = Index + 1;
newTime = (actor.GetSplineTime(Index) + actor.GetSplineTime(Index + 1)) * 0.5f;
}
var action = new DuplicateUndoAction
{
SplineId = actor.ID,
Index = newIndex,
Time = newTime,
Value = actor.GetSplineLocalTransform(Index),
};
actor.InsertSplineLocalPoint(newIndex, newTime, action.Value);
undoAction = action;
var splineNode = (SplineNode)SceneGraphFactory.FindNode(action.SplineId);
splineNode.OnUpdate();
return splineNode.ActorChildNodes[newIndex];
}
public override bool RayCastSelf(ref RayCastData ray, out float distance, out Vector3 normal)
{
var actor = (Spline)_node.Actor;

View File

@@ -169,6 +169,12 @@ float Spline::GetSplineLength() const
return Math::Sqrt(sum);
}
float Spline::GetSplineTime(int32 index) const
{
CHECK_RETURN(index >= 0 && index < GetSplinePointsCount(), 0.0f)
return Curve[index].Time;
}
namespace
{
void FindTimeClosestToPoint(const Vector3& point, const Spline::Keyframe& start, const Spline::Keyframe& end, float& bestDistanceSquared, float& bestTime)

View File

@@ -171,6 +171,13 @@ public:
/// </summary>
API_PROPERTY() float GetSplineLength() const;
/// <summary>
/// Gets the time of the spline keyframe.
/// </summary>
/// <param name="index">The curve keyframe index. Zero-based, smaller than GetSplinePointsCount().</param>
/// <returns>The spline time.</returns>
API_FUNCTION() float GetSplineTime(int32 index) const;
/// <summary>
/// Calculates the closest point to the given location and returns the spline time at that point.
/// </summary>