diff --git a/editor/src/messages/tool/common_functionality/shapes/arc_shape.rs b/editor/src/messages/tool/common_functionality/shapes/arc_shape.rs index 7eabb3c619..a2723057aa 100644 --- a/editor/src/messages/tool/common_functionality/shapes/arc_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/arc_shape.rs @@ -8,6 +8,7 @@ use crate::messages::tool::common_functionality::gizmos::shape_gizmos::circle_ar use crate::messages::tool::common_functionality::gizmos::shape_gizmos::sweep_angle_gizmo::{SweepAngleGizmo, SweepAngleGizmoState}; use crate::messages::tool::common_functionality::graph_modification_utils; use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, arc_outline}; +use crate::messages::tool::common_functionality::utility_functions::{viewport_to_document_dimensions, viewport_zoom}; use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; @@ -158,7 +159,8 @@ impl Arc { return; }; - let dimensions = (start - end).abs(); + let dimensions = viewport_to_document_dimensions(document, start, end); + let zoom = viewport_zoom(document); let mut scale = DVec2::ONE; let radius: f64; @@ -178,7 +180,7 @@ impl Arc { responses.add(GraphOperationMessage::TransformSet { layer, - transform: DAffine2::from_scale_angle_translation(scale, 0., start.midpoint(end)), + transform: DAffine2::from_scale_angle_translation(scale * zoom, 0., start.midpoint(end)), transform_in: TransformIn::Viewport, skip_rerender: false, }); diff --git a/editor/src/messages/tool/common_functionality/shapes/circle_shape.rs b/editor/src/messages/tool/common_functionality/shapes/circle_shape.rs index 836f50f9e6..6e651bd5ec 100644 --- a/editor/src/messages/tool/common_functionality/shapes/circle_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/circle_shape.rs @@ -7,6 +7,7 @@ use crate::messages::tool::common_functionality::gizmos::shape_gizmos::circle_ar use crate::messages::tool::common_functionality::graph_modification_utils; use crate::messages::tool::common_functionality::shape_editor::ShapeState; use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, ShapeToolModifierKey}; +use crate::messages::tool::common_functionality::utility_functions::{viewport_to_document_dimensions, viewport_zoom}; use crate::messages::tool::tool_messages::shape_tool::ShapeToolData; use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; @@ -101,7 +102,8 @@ impl Circle { return; }; - let dimensions = (start - end).abs(); + let dimensions = viewport_to_document_dimensions(document, start, end); + let zoom = viewport_zoom(document); // We keep the smaller dimension's scale at 1 and scale the other dimension accordingly let radius: f64 = if dimensions.x > dimensions.y { dimensions.y / 2. } else { dimensions.x / 2. }; @@ -113,7 +115,7 @@ impl Circle { responses.add(GraphOperationMessage::TransformSet { layer, - transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., start.midpoint(end)), + transform: DAffine2::from_scale_angle_translation(DVec2::splat(zoom), 0., start.midpoint(end)), transform_in: TransformIn::Viewport, skip_rerender: false, }); diff --git a/editor/src/messages/tool/common_functionality/shapes/ellipse_shape.rs b/editor/src/messages/tool/common_functionality/shapes/ellipse_shape.rs index eb33a08427..053815023b 100644 --- a/editor/src/messages/tool/common_functionality/shapes/ellipse_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/ellipse_shape.rs @@ -5,6 +5,7 @@ use crate::messages::portfolio::document::node_graph::document_node_definitions: use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier; use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate}; use crate::messages::tool::common_functionality::graph_modification_utils; +use crate::messages::tool::common_functionality::utility_functions::{viewport_to_document_dimensions, viewport_zoom}; use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; @@ -36,17 +37,20 @@ impl Ellipse { return; }; + let dimensions = viewport_to_document_dimensions(document, start, end); + let zoom = viewport_zoom(document); + responses.add(NodeGraphMessage::SetInput { input_connector: InputConnector::node(node_id, 1), - input: NodeInput::value(TaggedValue::F64(((start.x - end.x) / 2.).abs()), false), + input: NodeInput::value(TaggedValue::F64(dimensions.x / 2.), false), }); responses.add(NodeGraphMessage::SetInput { input_connector: InputConnector::node(node_id, 2), - input: NodeInput::value(TaggedValue::F64(((start.y - end.y) / 2.).abs()), false), + input: NodeInput::value(TaggedValue::F64(dimensions.y / 2.), false), }); responses.add(GraphOperationMessage::TransformSet { layer, - transform: DAffine2::from_translation(start.midpoint(end)), + transform: DAffine2::from_scale_angle_translation(DVec2::splat(zoom), 0., start.midpoint(end)), transform_in: TransformIn::Viewport, skip_rerender: false, }); diff --git a/editor/src/messages/tool/common_functionality/shapes/grid_shape.rs b/editor/src/messages/tool/common_functionality/shapes/grid_shape.rs index 7a7f1b0b19..f8fe149237 100644 --- a/editor/src/messages/tool/common_functionality/shapes/grid_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/grid_shape.rs @@ -9,6 +9,7 @@ use crate::messages::tool::common_functionality::gizmos::shape_gizmos::grid_rows use crate::messages::tool::common_functionality::graph_modification_utils; use crate::messages::tool::common_functionality::shape_editor::ShapeState; use crate::messages::tool::common_functionality::shapes::shape_utility::ShapeGizmoHandler; +use crate::messages::tool::common_functionality::utility_functions::viewport_zoom; use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; @@ -115,7 +116,11 @@ impl Grid { let start = shape_tool_data.data.viewport_drag_start(document); let end = ipp.mouse.position; - let (translation, dimensions, angle) = calculate_grid_params(start, end, is_isometric, ipp.keyboard.key(center), ipp.keyboard.key(lock_ratio)); + let (translation, dimensions_viewport, angle) = calculate_grid_params(start, end, is_isometric, ipp.keyboard.key(center), ipp.keyboard.key(lock_ratio)); + + let document_to_viewport = document.metadata().document_to_viewport; + let dimensions = document_to_viewport.inverse().transform_vector2(dimensions_viewport).abs(); + let zoom = viewport_zoom(document); // Set dimensions/spacing responses.add(NodeGraphMessage::SetInput { @@ -134,7 +139,7 @@ impl Grid { // Set transform responses.add(GraphOperationMessage::TransformSet { layer, - transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., translation), + transform: DAffine2::from_scale_angle_translation(DVec2::splat(zoom), 0., translation), transform_in: TransformIn::Viewport, skip_rerender: false, }); diff --git a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs index 7b22144a71..8f4875aba7 100644 --- a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs @@ -10,6 +10,7 @@ use crate::messages::tool::common_functionality::gizmos::shape_gizmos::point_rad use crate::messages::tool::common_functionality::graph_modification_utils::{self, NodeGraphLayer}; use crate::messages::tool::common_functionality::shape_editor::ShapeState; use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, polygon_outline}; +use crate::messages::tool::common_functionality::utility_functions::{viewport_to_document_dimensions, viewport_zoom}; use crate::messages::tool::tool_messages::shape_tool::ShapeOptionsUpdate; use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; @@ -129,7 +130,8 @@ impl Polygon { // TODO: We need to determine how to allow the polygon node to make irregular shapes update_radius_sign(end, start, layer, document, responses); - let dimensions = (start - end).abs(); + let dimensions = viewport_to_document_dimensions(document, start, end); + let zoom = viewport_zoom(document); // We keep the smaller dimension's scale at 1 and scale the other dimension accordingly let mut scale = DVec2::ONE; @@ -153,7 +155,7 @@ impl Polygon { responses.add(GraphOperationMessage::TransformSet { layer, - transform: DAffine2::from_scale_angle_translation(scale, 0., (start + end) / 2.), + transform: DAffine2::from_scale_angle_translation(scale * zoom, 0., (start + end) / 2.), transform_in: TransformIn::Viewport, skip_rerender: false, }); diff --git a/editor/src/messages/tool/common_functionality/shapes/rectangle_shape.rs b/editor/src/messages/tool/common_functionality/shapes/rectangle_shape.rs index 787684a8fa..b128a666c3 100644 --- a/editor/src/messages/tool/common_functionality/shapes/rectangle_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/rectangle_shape.rs @@ -5,6 +5,7 @@ use crate::messages::portfolio::document::node_graph::document_node_definitions: use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier; use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate}; use crate::messages::tool::common_functionality::graph_modification_utils; +use crate::messages::tool::common_functionality::utility_functions::{viewport_to_document_dimensions, viewport_zoom}; use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; @@ -36,17 +37,20 @@ impl Rectangle { return; }; + let dimensions = viewport_to_document_dimensions(document, start, end); + let zoom = viewport_zoom(document); + responses.add(NodeGraphMessage::SetInput { input_connector: InputConnector::node(node_id, 1), - input: NodeInput::value(TaggedValue::F64((start.x - end.x).abs()), false), + input: NodeInput::value(TaggedValue::F64(dimensions.x), false), }); responses.add(NodeGraphMessage::SetInput { input_connector: InputConnector::node(node_id, 2), - input: NodeInput::value(TaggedValue::F64((start.y - end.y).abs()), false), + input: NodeInput::value(TaggedValue::F64(dimensions.y), false), }); responses.add(GraphOperationMessage::TransformSet { layer, - transform: DAffine2::from_translation(start.midpoint(end)), + transform: DAffine2::from_scale_angle_translation(DVec2::splat(zoom), 0., start.midpoint(end)), transform_in: TransformIn::Viewport, skip_rerender: false, }); diff --git a/editor/src/messages/tool/common_functionality/shapes/spiral_shape.rs b/editor/src/messages/tool/common_functionality/shapes/spiral_shape.rs index 9db94ca57f..f8ca065161 100644 --- a/editor/src/messages/tool/common_functionality/shapes/spiral_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/spiral_shape.rs @@ -5,6 +5,7 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate}; use crate::messages::tool::common_functionality::graph_modification_utils::{self, NodeGraphLayer}; use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapData, SnapTypeConfiguration}; +use crate::messages::tool::common_functionality::utility_functions::viewport_zoom; use crate::messages::tool::tool_messages::shape_tool::ShapeOptionsUpdate; use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; @@ -57,7 +58,10 @@ impl Spiral { let snapped_viewport_point = document.metadata().document_to_viewport.transform_point2(snapped.snapped_point_document); shape_tool_data.data.snap_manager.update_indicator(snapped); - let dragged_distance = (viewport_drag_start - snapped_viewport_point).length(); + // Convert viewport-space distance to document-space + let zoom = viewport_zoom(document); + let dragged_distance_viewport = (viewport_drag_start - snapped_viewport_point).length(); + let dragged_distance = dragged_distance_viewport / zoom; let Some(node_id) = graph_modification_utils::get_spiral_id(layer, &document.network_interface) else { return; @@ -79,7 +83,7 @@ impl Spiral { responses.add(GraphOperationMessage::TransformSet { layer, - transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., viewport_drag_start), + transform: DAffine2::from_scale_angle_translation(DVec2::splat(zoom), 0., viewport_drag_start), transform_in: TransformIn::Viewport, skip_rerender: false, }); diff --git a/editor/src/messages/tool/common_functionality/shapes/star_shape.rs b/editor/src/messages/tool/common_functionality/shapes/star_shape.rs index acdde2c286..620134b06a 100644 --- a/editor/src/messages/tool/common_functionality/shapes/star_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/star_shape.rs @@ -10,6 +10,7 @@ use crate::messages::tool::common_functionality::gizmos::shape_gizmos::point_rad use crate::messages::tool::common_functionality::graph_modification_utils; use crate::messages::tool::common_functionality::shape_editor::ShapeState; use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, star_outline}; +use crate::messages::tool::common_functionality::utility_functions::{viewport_to_document_dimensions, viewport_zoom}; use crate::messages::tool::tool_messages::tool_prelude::*; use core::f64; use glam::DAffine2; @@ -134,7 +135,8 @@ impl Star { // TODO: We need to determine how to allow the polygon node to make irregular shapes update_radius_sign(end, start, layer, document, responses); - let dimensions = (start - end).abs(); + let dimensions = viewport_to_document_dimensions(document, start, end); + let zoom = viewport_zoom(document); // We keep the smaller dimension's scale at 1 and scale the other dimension accordingly let mut scale = DVec2::ONE; @@ -163,7 +165,7 @@ impl Star { responses.add(GraphOperationMessage::TransformSet { layer, - transform: DAffine2::from_scale_angle_translation(scale, 0., (start + end) / 2.), + transform: DAffine2::from_scale_angle_translation(scale * zoom, 0., (start + end) / 2.), transform_in: TransformIn::Viewport, skip_rerender: false, }); diff --git a/editor/src/messages/tool/common_functionality/utility_functions.rs b/editor/src/messages/tool/common_functionality/utility_functions.rs index e8d4293721..891adab7c3 100644 --- a/editor/src/messages/tool/common_functionality/utility_functions.rs +++ b/editor/src/messages/tool/common_functionality/utility_functions.rs @@ -22,6 +22,18 @@ use graphene_std::vector::misc::{HandleId, ManipulatorPointId, dvec2_to_point}; use graphene_std::vector::{HandleExt, PointId, SegmentId, Vector, VectorModification, VectorModificationType}; use kurbo::{CubicBez, DEFAULT_ACCURACY, Line, ParamCurve, PathSeg, Point, QuadBez, Shape}; +/// Converts viewport-space dimensions (the absolute difference between two viewport points) to document-space dimensions. +pub fn viewport_to_document_dimensions(document: &DocumentMessageHandler, start: DVec2, end: DVec2) -> DVec2 { + let document_to_viewport = document.metadata().document_to_viewport; + let dimensions_viewport = (start - end).abs(); + document_to_viewport.inverse().transform_vector2(dimensions_viewport).abs() +} + +/// Returns the viewport zoom scale factor from the document-to-viewport transform. +pub fn viewport_zoom(document: &DocumentMessageHandler) -> f64 { + document.metadata().document_to_viewport.matrix2.col(0).length() +} + /// Determines if a path should be extended. Goal in viewport space. Returns the path and if it is extending from the start, if applicable. pub fn should_extend(document: &DocumentMessageHandler, goal: DVec2, tolerance: f64, layers: impl Iterator) -> Option<(LayerNodeIdentifier, PointId, DVec2)> { closest_point(document, goal, tolerance, layers, |_| false)