use crate::instances::Instances; use crate::raster_types::{CPU, GPU, RasterDataTable}; use crate::transform::{ApplyTransform, Footprint, Transform}; use crate::vector::VectorDataTable; use crate::{CloneVarArgs, Context, Ctx, ExtractAll, GraphicGroupTable, OwnedContextImpl}; use core::f64; use glam::{DAffine2, DVec2}; #[node_macro::node(category(""))] async fn transform( ctx: impl Ctx + CloneVarArgs + ExtractAll, #[implementations( Context -> VectorDataTable, Context -> GraphicGroupTable, Context -> RasterDataTable, Context -> RasterDataTable, )] transform_target: impl Node, Output = Instances>, translate: DVec2, rotate: f64, scale: DVec2, skew: DVec2, _pivot: DVec2, ) -> Instances { let matrix = DAffine2::from_scale_angle_translation(scale, rotate, translate) * DAffine2::from_cols_array(&[1., skew.y, skew.x, 1., 0., 0.]); let footprint = ctx.try_footprint().copied(); let mut ctx = OwnedContextImpl::from(ctx); if let Some(mut footprint) = footprint { footprint.apply_transform(&matrix); ctx = ctx.with_footprint(footprint); } let mut transform_target = transform_target.eval(ctx.into_context()).await; for data_transform in transform_target.instance_mut_iter() { *data_transform.transform = matrix * *data_transform.transform; } transform_target } #[node_macro::node(category(""))] fn replace_transform( _: impl Ctx, #[implementations(VectorDataTable, RasterDataTable, GraphicGroupTable)] mut data: Instances, #[implementations(DAffine2)] transform: TransformInput, ) -> Instances { for data_transform in data.instance_mut_iter() { *data_transform.transform = transform.transform(); } data } #[node_macro::node(category("Debug"))] async fn boundless_footprint( ctx: impl Ctx + CloneVarArgs + ExtractAll, #[implementations( Context -> VectorDataTable, Context -> GraphicGroupTable, Context -> RasterDataTable, Context -> RasterDataTable, Context -> String, Context -> f64, )] transform_target: impl Node, Output = T>, ) -> T { let ctx = OwnedContextImpl::from(ctx).with_footprint(Footprint::BOUNDLESS); transform_target.eval(ctx.into_context()).await } #[node_macro::node(category("Debug"))] async fn freeze_real_time( ctx: impl Ctx + CloneVarArgs + ExtractAll, #[implementations( Context -> VectorDataTable, Context -> GraphicGroupTable, Context -> RasterDataTable, Context -> RasterDataTable, Context -> String, Context -> f64, )] transform_target: impl Node, Output = T>, ) -> T { let ctx = OwnedContextImpl::from(ctx).with_real_time(0.); transform_target.eval(ctx.into_context()).await }