diff --git a/Source/Editor/Gizmo/TransformGizmo.cs b/Source/Editor/Gizmo/TransformGizmo.cs
index 4918743ce..64f969990 100644
--- a/Source/Editor/Gizmo/TransformGizmo.cs
+++ b/Source/Editor/Gizmo/TransformGizmo.cs
@@ -263,6 +263,8 @@ namespace FlaxEditor.Gizmo
// Note: because selection may contain objects and their children we have to split them and get only parents.
// Later during transformation we apply translation/scale/rotation only on them (children inherit transformations)
SceneGraphTools.BuildNodesParents(_selection, _selectionParents);
+
+ base.OnSelectionChanged(newSelection);
}
///
diff --git a/Source/Editor/Gizmo/TransformGizmoBase.cs b/Source/Editor/Gizmo/TransformGizmoBase.cs
index 99b1c8122..290795fa0 100644
--- a/Source/Editor/Gizmo/TransformGizmoBase.cs
+++ b/Source/Editor/Gizmo/TransformGizmoBase.cs
@@ -85,6 +85,7 @@ namespace FlaxEditor.Gizmo
{
InitDrawing();
ModeChanged += ResetTranslationScale;
+
}
///
@@ -437,8 +438,6 @@ namespace FlaxEditor.Gizmo
{
case Mode.Translate:
UpdateTranslateScale();
- if (Owner.SnapToVertex)
- UpdateVertexSnapping();
break;
case Mode.Scale:
UpdateTranslateScale();
@@ -447,6 +446,8 @@ namespace FlaxEditor.Gizmo
UpdateRotate(dt);
break;
}
+ if (Owner.SnapToVertex)
+ UpdateVertexSnapping();
}
else
{
@@ -553,43 +554,23 @@ namespace FlaxEditor.Gizmo
for (int i = 0; i < SelectionCount; i++)
{
var obj = GetSelectedObject(i);
- if (obj.CanVertexSnap && obj.RayCastSelf(ref ray, out var distance, out _) && distance < closestDistance)
+ if (obj.RayCastSelf(ref ray, out var distance, out _) && distance < closestDistance)
{
closestDistance = distance;
closestObject = obj;
}
}
if (closestObject == null)
- {
- // Find the closest object in selection (in case ray didn't hit anything)
- for (int i = 0; i < SelectionCount; i++)
- {
- var obj = GetSelectedObject(i);
- if (obj.CanVertexSnap)
- {
- GetSelectedObjectsBounds(out var bounds, out _);
- CollisionsHelper.ClosestPointBoxPoint(ref bounds, ref ray.Ray.Position, out var point);
- var distance = Vector3.Distance(ref point, ref ray.Ray.Position);
- if (distance < closestDistance)
- {
- closestDistance = distance;
- closestObject = obj;
- }
- }
- }
- }
+ return; // ignore it if there is nothing under the mouse closestObject is only null if ray caster missed everything or Selection Count == 0
+
_vertexSnapObject = closestObject;
- if (closestObject == null)
- return;
- // Find the closest vertex to bounding box point (collision detection approximation)
- var closestPoint = ray.Ray.GetPoint(closestDistance);
- if (!closestObject.OnVertexSnap(ref closestPoint, out _vertexSnapPoint))
+ if (!closestObject.OnVertexSnap(ref ray.Ray, closestDistance, out _vertexSnapPoint))
{
- // Failed to get the closest point
- _vertexSnapPoint = closestPoint;
+ //The OnVertexSnap is unimplemented or failed to get point return because there is nothing to do
+ _vertexSnapPoint = Vector3.Zero;
+ return;
}
-
// Transform back to the local space of the object to work when moving it
_vertexSnapPoint = closestObject.Transform.WorldToLocal(_vertexSnapPoint);
}
@@ -619,10 +600,9 @@ namespace FlaxEditor.Gizmo
for (int i = 0; i < SelectionCount; i++)
rayCast.ExcludeObjects.Add(GetSelectedObject(i));
var hit = Owner.SceneGraphRoot.RayCast(ref rayCast, out var distance, out var _);
- if (hit != null && hit.CanVertexSnap)
+ if (hit != null)
{
- var point = rayCast.Ray.GetPoint(distance);
- if (hit.OnVertexSnap(ref point, out var pointSnapped)
+ if (hit.OnVertexSnap(ref rayCast.Ray, distance, out var pointSnapped)
//&& Vector3.Distance(point, pointSnapped) <= 25.0f
)
{
@@ -712,5 +692,11 @@ namespace FlaxEditor.Gizmo
protected virtual void OnDuplicate()
{
}
+ ///
+ public override void OnSelectionChanged(List newSelection)
+ {
+ EndVertexSnapping();
+ UpdateGizmoPosition();
+ }
}
}
diff --git a/Source/Editor/SceneGraph/Actors/StaticModelNode.cs b/Source/Editor/SceneGraph/Actors/StaticModelNode.cs
index f1ab36041..0a8fd48bb 100644
--- a/Source/Editor/SceneGraph/Actors/StaticModelNode.cs
+++ b/Source/Editor/SceneGraph/Actors/StaticModelNode.cs
@@ -23,20 +23,23 @@ namespace FlaxEditor.SceneGraph.Actors
: base(actor)
{
}
+
///
- public override bool OnVertexSnap(ref Vector3 point, out Vector3 result)
+ public override bool OnVertexSnap(ref Ray ray, float hitDistance, out Vector3 result)
{
- result = point;
+ // Find the closest vertex to bounding box point (collision detection approximation)
+
+ result = ray.GetPoint(hitDistance);
var model = ((StaticModel)Actor).Model;
if (model && !model.WaitForLoaded())
{
// TODO: move to C++ and use cached vertex buffer internally inside the Mesh
if (_vertices == null)
_vertices = new();
- var pointLocal = (Float3)Actor.Transform.WorldToLocal(point);
+ var pointLocal = (Float3)Actor.Transform.WorldToLocal(result);
var minDistance = float.MaxValue;
- foreach (var lod in model.LODs)
+ foreach (var lod in model.LODs) //[ToDo] fix it [Nori_SC note] this is wrong it should get current lod level going it throw all lods will create ghost snaping points
{
var hit = false;
foreach (var mesh in lod.Meshes)
diff --git a/Source/Editor/SceneGraph/SceneGraphNode.cs b/Source/Editor/SceneGraph/SceneGraphNode.cs
index 5cf28af37..e9020592d 100644
--- a/Source/Editor/SceneGraph/SceneGraphNode.cs
+++ b/Source/Editor/SceneGraph/SceneGraphNode.cs
@@ -94,18 +94,6 @@ namespace FlaxEditor.SceneGraph
///
public virtual bool CanTransform => true;
- ///
- /// Gets a value indicating whether this node can be used for the vertex snapping feature.
- ///
- public bool CanVertexSnap
- {
- get
- {
- var v = Vector3.Zero;
- return OnVertexSnap(ref v, out _);
- }
- }
-
///
/// Gets a value indicating whether this is active.
///
@@ -365,14 +353,15 @@ namespace FlaxEditor.SceneGraph
}
///
- /// Performs the vertex snapping of a given point on the object surface that is closest to a given location.
+ /// Performs the vertex snapping for a given ray and hitDistance.
///
- /// The position to snap.
+ /// Raycasted ray
+ /// Hit distance from ray to object bounding box
/// The result point on the object mesh that is closest to the specified location.
/// True if got a valid result value, otherwise false (eg. if missing data or not initialized).
- public virtual bool OnVertexSnap(ref Vector3 point, out Vector3 result)
+ public virtual bool OnVertexSnap(ref Ray ray,float hitDistance, out Vector3 result) // [NoriSC note] ray and hit Distance will be needed for a future use, in mesh types for proper collision detection
{
- result = point;
+ result = Vector3.Zero;
return false;
}