diff --git a/editor/src/messages/portfolio/document/node_graph/node_properties.rs b/editor/src/messages/portfolio/document/node_graph/node_properties.rs index ec06c8a6b6..54acaf8419 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_properties.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_properties.rs @@ -334,6 +334,15 @@ pub fn reference_point_widget(parameter_widgets_info: ParameterWidgetsInfo, disa if let Some(&TaggedValue::ReferencePoint(reference_point)) = input.as_non_exposed_value() { widgets.extend_from_slice(&[ Separator::new(SeparatorType::Unrelated).widget_holder(), + CheckboxInput::new(reference_point != ReferencePoint::None) + .on_update(update_value( + move |x: &CheckboxInput| TaggedValue::ReferencePoint(if x.checked { ReferencePoint::Center } else { ReferencePoint::None }), + node_id, + index, + )) + .disabled(disabled) + .widget_holder(), + Separator::new(SeparatorType::Related).widget_holder(), ReferencePointInput::new(reference_point) .on_update(update_value(move |x: &ReferencePointInput| TaggedValue::ReferencePoint(x.value), node_id, index)) .disabled(disabled) diff --git a/node-graph/gcore/src/vector/vector_nodes.rs b/node-graph/gcore/src/vector/vector_nodes.rs index fb4668ba4c..e0ebfdc634 100644 --- a/node-graph/gcore/src/vector/vector_nodes.rs +++ b/node-graph/gcore/src/vector/vector_nodes.rs @@ -357,20 +357,19 @@ where result_table } -// TODO: Make this node return Instances instead of GraphicGroupTable, while preserving the current transform behavior as the `reference_point` and `offset` parameters are varied #[node_macro::node(category("Vector"), path(graphene_core::vector))] async fn mirror( _: impl Ctx, #[implementations(GraphicGroupTable, VectorDataTable, RasterDataTable)] instance: Instances, - #[default(ReferencePoint::Center)] reference_point: ReferencePoint, + #[default(ReferencePoint::Center)] relative_to_bounds: ReferencePoint, offset: f64, #[range((-90., 90.))] angle: Angle, #[default(true)] keep_original: bool, -) -> GraphicGroupTable +) -> Instances where Instances: GraphicElementRendered, { - let mut result_table = GraphicGroupTable::default(); + let mut result_table = Instances::default(); // Normalize the direction vector let normal = DVec2::from_angle(angle.to_radians()); @@ -380,12 +379,8 @@ where return result_table; }; - // TODO: If the reference point is not None, use the current behavior but make it work correctly with local pivot origins of each Instances row - let reference_point_location = reference_point.point_in_bounding_box((bounding_box[0], bounding_box[1]).into()).unwrap_or_else(|| { - // TODO: In this None case, use the input's local pivot origin point instead of a point relative to its bounding box - (bounding_box[0] + bounding_box[1]) / 2. - }); - let mirror_reference_point = reference_point_location + normal * offset; + let reference_point_location = relative_to_bounds.point_in_bounding_box((bounding_box[0], bounding_box[1]).into()); + let mirror_reference_point = reference_point_location.map(|point| point + normal * offset); // Create the reflection matrix let reflection = DAffine2::from_mat2_translation( @@ -397,25 +392,25 @@ where ); // Apply reflection around the reference point - let transform = DAffine2::from_translation(mirror_reference_point) * reflection * DAffine2::from_translation(-mirror_reference_point); + let reflected_transform = if let Some(mirror_reference_point) = mirror_reference_point { + DAffine2::from_translation(mirror_reference_point) * reflection * DAffine2::from_translation(-mirror_reference_point) + } else { + reflection * DAffine2::from_translation(DVec2::from_angle(angle.to_radians()) * DVec2::splat(-offset)) + }; // Add original instance depending on the keep_original flag if keep_original { - result_table.push(Instance { - instance: instance.to_graphic_element().clone(), - transform: DAffine2::IDENTITY, - alpha_blending: Default::default(), - source_node_id: None, - }); + for instance in instance.clone().instance_iter() { + result_table.push(instance); + } } // Create and add mirrored instance - result_table.push(Instance { - instance: instance.to_graphic_element(), - transform, - alpha_blending: Default::default(), - source_node_id: None, - }); + for mut instance in instance.instance_iter() { + instance.transform = reflected_transform * instance.transform; + instance.source_node_id = None; + result_table.push(instance); + } result_table }