Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
41 changes: 18 additions & 23 deletions node-graph/gcore/src/vector/vector_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,20 +357,19 @@ where
result_table
}

// TODO: Make this node return Instances<I> 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<I: 'n + Send + Clone>(
_: impl Ctx,
#[implementations(GraphicGroupTable, VectorDataTable, RasterDataTable<Color>)] instance: Instances<I>,
#[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<I>
where
Instances<I>: 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());
Expand All @@ -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<I> 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(
Expand All @@ -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
}
Expand Down
Loading