-
Notifications
You must be signed in to change notification settings - Fork 668
DYN-6738: Gizmo Display Issues #16844
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,8 @@ public abstract class NodeManipulator : INodeManipulator | |
| private string warning = string.Empty; | ||
| private Point originBeforeMove;// The manipulator position before the user moves the gizmo | ||
| private Point originAfterMove;// The manipulator position after the user moves the gizmo | ||
| private bool hasUpdatedInputNodesDuringDrag; | ||
| private readonly HashSet<NodeModel> inputNodesUpdatedDuringDrag = new HashSet<NodeModel>(); | ||
| protected const double gizmoScale = 1.2; | ||
| protected readonly int ROUND_UP_PARAM = 3; | ||
| protected readonly double MIN_OFFSET_VAL = 0.001; | ||
|
|
@@ -185,6 +187,22 @@ protected virtual void MouseDown(object sender, MouseButtonEventArgs mouseButton | |
| { | ||
| if (!IsValidNode) return; | ||
|
|
||
| // Skip processing if user is panning or orbiting the camera. | ||
| // This prevents the manipulator from capturing mouse events intended for camera navigation, | ||
| // including cases where pan/orbit tools use the left mouse button. | ||
| if (BackgroundPreviewViewModel is DefaultWatch3DViewModel viewModel) | ||
| { | ||
| if (viewModel.IsPanning || viewModel.IsOrbiting) | ||
| return; | ||
| } | ||
|
|
||
| // Only process left mouse button presses for gizmo manipulation | ||
| // Right/middle button presses are for camera navigation (pan/orbit) | ||
| if (mouseButtonEventArgs.ChangedButton != MouseButton.Left) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| active = UpdatePosition(); | ||
| if (Origin != null ) | ||
| { | ||
|
|
@@ -209,6 +227,8 @@ protected virtual void MouseDown(object sender, MouseButtonEventArgs mouseButton | |
| if (item.HitTest(originPt, dirVec, out hitObject)) | ||
| { | ||
| GizmoInAction = item; | ||
| hasUpdatedInputNodesDuringDrag = false; | ||
| inputNodesUpdatedDuringDrag.Clear(); | ||
|
|
||
| var nodes = OnGizmoClick(item, hitObject).ToList(); | ||
| if (nodes.Any()) | ||
|
|
@@ -228,19 +248,42 @@ protected virtual void MouseDown(object sender, MouseButtonEventArgs mouseButton | |
| /// <param name="e"></param> | ||
| protected virtual void MouseUp(object sender, MouseButtonEventArgs e) | ||
| { | ||
| // Skip processing if user is panning or orbiting the camera. | ||
| // This prevents the manipulator from capturing mouse events intended for camera navigation, | ||
| // including cases where pan/orbit tools use the left mouse button. | ||
| if (BackgroundPreviewViewModel is DefaultWatch3DViewModel viewModel) | ||
| { | ||
| if (viewModel.IsPanning || viewModel.IsOrbiting) | ||
| return; | ||
| } | ||
|
|
||
| // Only process left mouse button releases for gizmo manipulation | ||
| // Right/middle button releases are for camera navigation (pan/orbit) | ||
| if (e.ChangedButton != MouseButton.Left) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| GizmoInAction = null; | ||
|
|
||
| if (originBeforeMove != null && originAfterMove != null) | ||
| { | ||
| var inputNodesToManipulate = InputNodesToUpdateAfterMove(Vector.ByTwoPoints(originBeforeMove, originAfterMove)); | ||
| foreach (var (inputNode, amount) in inputNodesToManipulate) | ||
| if (hasUpdatedInputNodesDuringDrag) | ||
| { | ||
| if (inputNode == null) continue; | ||
| FinalizeInputNodesAfterDrag(); | ||
| } | ||
| else | ||
| { | ||
| var inputNodesToManipulate = InputNodesToUpdateAfterMove(Vector.ByTwoPoints(originBeforeMove, originAfterMove)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When will control reach here inside this |
||
| foreach (var (inputNode, amount) in inputNodesToManipulate) | ||
| { | ||
| if (inputNode == null) continue; | ||
|
|
||
| if (Math.Abs(amount) < MIN_OFFSET_VAL) continue; | ||
| if (Math.Abs(amount) < MIN_OFFSET_VAL) continue; | ||
|
|
||
| dynamic uiNode = inputNode; | ||
| uiNode.Value = Math.Round(amount, ROUND_UP_PARAM); | ||
| dynamic uiNode = inputNode; | ||
| uiNode.Value = Math.Round(amount, ROUND_UP_PARAM); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe a good idea here to check if the final value we are setting for |
||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -249,7 +292,15 @@ protected virtual void MouseUp(object sender, MouseButtonEventArgs e) | |
| foreach (var gizmo in gizmos) | ||
| { | ||
| gizmo.UpdateGizmoGraphics(); | ||
|
|
||
| // Clear hit state to prevent drift during subsequent camera operations | ||
| // This ensures stale axis/plane hit data doesn't affect pan/orbit movements | ||
| if (gizmo is TranslationGizmo translationGizmo) | ||
| { | ||
| translationGizmo.ClearHitState(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really necessary, even after preventing mouseup or mousedown events from doing anything after a camera change event? |
||
| } | ||
| } | ||
|
|
||
| } | ||
|
|
||
| /// <summary> | ||
|
|
@@ -284,9 +335,11 @@ protected virtual void MouseMove(object sender, MouseEventArgs mouseEventArgs) | |
| // Doing this triggers a graph update on scheduler thread | ||
| OnGizmoMoved(GizmoInAction, offset); | ||
|
|
||
| UpdateInputNodesDuringDrag(offset); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Calling this function inside |
||
|
|
||
| // redraw manipulator at new position synchronously | ||
| var packages = BuildRenderPackage(); | ||
| BackgroundPreviewViewModel.AddGeometryForRenderPackages(packages); | ||
| BackgroundPreviewViewModel.AddGeometryForRenderPackages(packages, true); | ||
| } | ||
|
|
||
| /// <summary> | ||
|
|
@@ -384,6 +437,35 @@ protected bool CanManipulateInputNode(int inputPortIndex, out NodeModel inputNod | |
| return new List<(NodeModel, double)>(); | ||
| } | ||
|
|
||
| private void UpdateInputNodesDuringDrag(Vector offset) | ||
| { | ||
| var inputNodesToManipulate = InputNodesToUpdateAfterMove(offset); | ||
| foreach (var (inputNode, amount) in inputNodesToManipulate) | ||
| { | ||
| if (inputNode == null) continue; | ||
| if (Math.Abs(amount) < MIN_OFFSET_VAL) continue; | ||
|
|
||
| dynamic uiNode = inputNode; | ||
| uiNode.Value = amount; | ||
|
Comment on lines
+448
to
+449
|
||
| inputNodesUpdatedDuringDrag.Add(inputNode); | ||
| hasUpdatedInputNodesDuringDrag = true; | ||
| } | ||
| } | ||
|
|
||
| private void FinalizeInputNodesAfterDrag() | ||
| { | ||
| foreach (var inputNode in inputNodesUpdatedDuringDrag) | ||
| { | ||
| if (inputNode == null) continue; | ||
|
|
||
| dynamic uiNode = inputNode; | ||
| uiNode.Value = Math.Round((double)uiNode.Value, ROUND_UP_PARAM); | ||
|
Comment on lines
+461
to
+462
|
||
| } | ||
|
|
||
| inputNodesUpdatedDuringDrag.Clear(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should also be called in the |
||
| hasUpdatedInputNodesDuringDrag = false; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Executes CreateAndConnectNodeCommand to create DoubleSlider and | ||
| /// connect it's output port to the input port of the node. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this condition to check if the backgroundpreview mode is on and not the graph view mode?