mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 22:48:12 +08:00
Make the Transform node use angles in degrees instead of radians for Rotation and Skew (#3160)
* Make the Transform node use degrees not radians * Migration script * Migrate skew value input to store degrees * Add comments * Fix migrations to account for the old deprecated "Pivot" parameter * Fix tooling interactions with degrees-based transforms * Upgrade demo art --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
c51967384f
commit
332088bce1
@@ -5,7 +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, OutputConnector};
|
||||
use crate::messages::prelude::DocumentMessageHandler;
|
||||
use glam::IVec2;
|
||||
use glam::{DVec2, IVec2};
|
||||
use graph_craft::document::DocumentNode;
|
||||
use graph_craft::document::{DocumentNodeImplementation, NodeInput, value::TaggedValue};
|
||||
use graphene_std::ProtoNodeIdentifier;
|
||||
@@ -16,6 +16,7 @@ use graphene_std::uuid::NodeId;
|
||||
use graphene_std::vector::Vector;
|
||||
use graphene_std::vector::style::{PaintOrder, StrokeAlign};
|
||||
use std::collections::HashMap;
|
||||
use std::f64::consts::PI;
|
||||
|
||||
const TEXT_REPLACEMENTS: &[(&str, &str)] = &[
|
||||
("graphene_core::vector::vector_nodes::SamplePointsNode", "graphene_core::vector::SamplePolylineNode"),
|
||||
@@ -1051,14 +1052,80 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||
document.network_interface.add_import(TaggedValue::U32(0), false, 1, "Loop Level", "TODO", &node_path);
|
||||
}
|
||||
|
||||
// Add context features to nodes that don't have them (fine-grained context caching migration)
|
||||
if node.context_features == graphene_std::ContextDependencies::default() {
|
||||
if let Some(reference) = document.network_interface.reference(node_id, network_path).cloned().flatten() {
|
||||
if let Some(node_definition) = resolve_document_node_type(&reference) {
|
||||
let context_features = node_definition.node_template.document_node.context_features;
|
||||
document.network_interface.set_context_features(node_id, network_path, context_features);
|
||||
// Migrate the Transform node to use degrees instead of radians
|
||||
if reference == "Transform" && node.inputs.get(6).is_none() {
|
||||
// Migrate rotation from radians to degrees
|
||||
match node.inputs.get(2)? {
|
||||
NodeInput::Value { tagged_value, exposed } => {
|
||||
// Read the existing Properties panel number value, which used to be in radians
|
||||
let TaggedValue::F64(radians) = *tagged_value.clone().into_inner() else { return None };
|
||||
|
||||
// Convert the radians to degrees and set it back as the new input value
|
||||
let degrees = NodeInput::value(TaggedValue::F64(radians.to_degrees()), *exposed);
|
||||
document.network_interface.set_input(&InputConnector::node(*node_id, 2), degrees, network_path);
|
||||
}
|
||||
NodeInput::Node { .. } => {
|
||||
// Construct a new Multiply node for converting from degrees to radians
|
||||
let Some(multiply_node) = resolve_document_node_type("Multiply") else {
|
||||
log::error!("Could not get multiply node from definition when upgrading transform");
|
||||
return None;
|
||||
};
|
||||
let mut multiply_template = multiply_node.default_node_template();
|
||||
multiply_template.document_node.inputs[1] = NodeInput::value(TaggedValue::F64(180. / PI), false);
|
||||
|
||||
// Decide on the placement position of the new Multiply node
|
||||
let multiply_node_id = NodeId::new();
|
||||
let Some(transform_position) = document.network_interface.position_from_downstream_node(node_id, network_path) else {
|
||||
log::error!("Could not get positon for transform node {node_id}");
|
||||
return None;
|
||||
};
|
||||
let multiply_position = transform_position + IVec2::new(-7, 1);
|
||||
|
||||
// Insert the new Multiply node into the network directly before it's used
|
||||
document.network_interface.insert_node(multiply_node_id, multiply_template, network_path);
|
||||
document.network_interface.shift_absolute_node_position(&multiply_node_id, multiply_position, network_path);
|
||||
document.network_interface.insert_node_between(&multiply_node_id, &InputConnector::node(*node_id, 2), 0, network_path);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
// Migrate skew from radians to degrees
|
||||
if let NodeInput::Value { tagged_value, exposed } = node.inputs.get(4)? {
|
||||
// Read the existing Properties panel number value, which used to be in radians
|
||||
let TaggedValue::DVec2(old_value) = *tagged_value.clone().into_inner() else { return None };
|
||||
|
||||
// The previous value stored the tangent of the displayed degrees. Now it stores the degrees, so take the arctan of it and convert to degrees.
|
||||
let new_value = DVec2::new(old_value.x.atan().to_degrees(), old_value.y.atan().to_degrees());
|
||||
let new_input = NodeInput::value(TaggedValue::DVec2(new_value), *exposed);
|
||||
document.network_interface.set_input(&InputConnector::node(*node_id, 4), new_input, network_path);
|
||||
}
|
||||
|
||||
// Remove the possible existence of the old "Pivot" hidden value input that was removed in #2730
|
||||
let nested_transform_network = [network_path, &[*node_id]].concat();
|
||||
if node.inputs.get(5).is_some() {
|
||||
document.network_interface.remove_import(5, &nested_transform_network);
|
||||
}
|
||||
|
||||
// Add the Origin Offset parameter as a hidden input, which will be given actual functionality in the future but is currently used as a marker to detect not-yet-upgraded Transform nodes
|
||||
document
|
||||
.network_interface
|
||||
.add_import(TaggedValue::DVec2(DVec2::ZERO), false, 5, "Origin Offset", "", &nested_transform_network);
|
||||
document.network_interface.set_input_override(node_id, 5, Some("hidden".to_string()), network_path); // Hide it while we're not yet using it
|
||||
|
||||
// Add the Scale Appearance parameter as a hidden input, which will be given actual functionality in the future but is currently used as a marker to detect not-yet-upgraded Transform nodes
|
||||
document
|
||||
.network_interface
|
||||
.add_import(TaggedValue::Bool(true), false, 6, "Scale Appearance", "", &nested_transform_network);
|
||||
document.network_interface.set_input_override(node_id, 6, Some("hidden".to_string()), network_path); // Hide it while we're not yet using it
|
||||
}
|
||||
|
||||
// Add context features to nodes that don't have them (fine-grained context caching migration)
|
||||
if node.context_features == graphene_std::ContextDependencies::default()
|
||||
&& let Some(reference) = document.network_interface.reference(node_id, network_path).cloned().flatten()
|
||||
&& let Some(node_definition) = resolve_document_node_type(&reference)
|
||||
{
|
||||
let context_features = node_definition.node_template.document_node.context_features;
|
||||
document.network_interface.set_context_features(node_id, network_path, context_features);
|
||||
}
|
||||
|
||||
// ==================================
|
||||
|
||||
Reference in New Issue
Block a user