@@ -14,6 +14,7 @@ use graphene_std::vector::{HandleId, PointId};
14
14
15
15
use glam:: { DAffine2 , DMat2 , DVec2 } ;
16
16
use std:: collections:: { HashMap , VecDeque } ;
17
+ use std:: f64:: consts:: PI ;
17
18
18
19
#[ derive( Debug , PartialEq , Clone , Copy ) ]
19
20
struct AnchorPoint {
@@ -305,17 +306,17 @@ pub enum TransformOperation {
305
306
}
306
307
307
308
impl TransformOperation {
308
- pub fn apply_transform_operation ( & self , selected : & mut Selected , increment_mode : bool , local : bool , quad : Quad , transform : DAffine2 ) {
309
+ pub fn apply_transform_operation ( & self , selected : & mut Selected , increment_mode : bool , local : bool , quad : Quad , transform : DAffine2 , pivot : DVec2 , local_transform : DAffine2 ) {
309
310
let local_axis_transform_angle = ( quad. top_left ( ) - quad. top_right ( ) ) . to_angle ( ) ;
310
311
if self != & TransformOperation :: None {
311
312
let transformation = match self {
312
313
TransformOperation :: Grabbing ( translation) => {
313
- let translate = DAffine2 :: from_translation ( transform. transform_vector2 ( translation. to_dvec ( transform , increment_mode) ) ) ;
314
+ let translate = DAffine2 :: from_translation ( transform. transform_vector2 ( translation. to_dvec ( local_transform , increment_mode) ) ) ;
314
315
if local {
315
316
let resolved_angle = if local_axis_transform_angle > 0. {
316
- local_axis_transform_angle - std:: f64:: consts:: PI
317
- } else {
318
317
local_axis_transform_angle
318
+ } else {
319
+ local_axis_transform_angle - PI
319
320
} ;
320
321
DAffine2 :: from_angle ( resolved_angle) * translate * DAffine2 :: from_angle ( -resolved_angle)
321
322
} else {
@@ -333,7 +334,7 @@ impl TransformOperation {
333
334
TransformOperation :: None => unreachable ! ( ) ,
334
335
} ;
335
336
336
- selected. update_transforms ( transformation) ;
337
+ selected. update_transforms ( transformation, Some ( pivot ) ) ;
337
338
self . hints ( selected. responses , local) ;
338
339
}
339
340
}
@@ -350,7 +351,7 @@ impl TransformOperation {
350
351
self . is_constraint_to_axis ( ) || !matches ! ( self , TransformOperation :: Grabbing ( _) )
351
352
}
352
353
353
- pub fn constrain_axis ( & mut self , axis : Axis , selected : & mut Selected , increment_mode : bool , mut local : bool , quad : Quad , transform : DAffine2 ) -> bool {
354
+ pub fn constrain_axis ( & mut self , axis : Axis , selected : & mut Selected , increment_mode : bool , mut local : bool , quad : Quad , transform : DAffine2 , pivot : DVec2 , local_transform : DAffine2 ) -> bool {
354
355
( * self , local) = match self {
355
356
TransformOperation :: Grabbing ( translation) => {
356
357
let ( translation, local) = translation. with_constraint ( axis, local) ;
@@ -362,19 +363,19 @@ impl TransformOperation {
362
363
}
363
364
_ => ( * self , false ) ,
364
365
} ;
365
- self . apply_transform_operation ( selected, increment_mode, local, quad, transform) ;
366
+ self . apply_transform_operation ( selected, increment_mode, local, quad, transform, pivot , local_transform ) ;
366
367
local
367
368
}
368
369
369
- pub fn grs_typed ( & mut self , typed : Option < f64 > , selected : & mut Selected , increment_mode : bool , local : bool , quad : Quad , transform : DAffine2 ) {
370
+ pub fn grs_typed ( & mut self , typed : Option < f64 > , selected : & mut Selected , increment_mode : bool , local : bool , quad : Quad , transform : DAffine2 , pivot : DVec2 , local_transform : DAffine2 ) {
370
371
match self {
371
372
TransformOperation :: None => ( ) ,
372
373
TransformOperation :: Grabbing ( translation) => translation. typed_distance = typed,
373
374
TransformOperation :: Rotating ( rotation) => rotation. typed_angle = typed,
374
375
TransformOperation :: Scaling ( scale) => scale. typed_factor = typed,
375
376
} ;
376
377
377
- self . apply_transform_operation ( selected, increment_mode, local, quad, transform) ;
378
+ self . apply_transform_operation ( selected, increment_mode, local, quad, transform, pivot , local_transform ) ;
378
379
}
379
380
380
381
pub fn hints ( & self , responses : & mut VecDeque < Message > , local : bool ) {
@@ -456,15 +457,15 @@ impl TransformOperation {
456
457
}
457
458
}
458
459
459
- pub fn negate ( & mut self , selected : & mut Selected , increment_mode : bool , local : bool , quad : Quad , transform : DAffine2 ) {
460
+ pub fn negate ( & mut self , selected : & mut Selected , increment_mode : bool , local : bool , quad : Quad , transform : DAffine2 , pivot : DVec2 , local_transform : DAffine2 ) {
460
461
if * self != TransformOperation :: None {
461
462
* self = match self {
462
463
TransformOperation :: Scaling ( scale) => TransformOperation :: Scaling ( scale. negate ( ) ) ,
463
464
TransformOperation :: Rotating ( rotation) => TransformOperation :: Rotating ( rotation. negate ( ) ) ,
464
465
TransformOperation :: Grabbing ( translation) => TransformOperation :: Grabbing ( translation. negate ( ) ) ,
465
466
_ => * self ,
466
467
} ;
467
- self . apply_transform_operation ( selected, increment_mode, local, quad, transform) ;
468
+ self . apply_transform_operation ( selected, increment_mode, local, quad, transform, pivot , local_transform ) ;
468
469
}
469
470
}
470
471
}
@@ -590,11 +591,14 @@ impl<'a> Selected<'a> {
590
591
responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
591
592
592
593
if let Some ( ( id, initial) ) = handle. mirror {
593
- let direction = viewspace. transform_vector2 ( new_pos_viewport - relative) . try_normalize ( ) ;
594
- let length = viewspace. transform_vector2 ( initial - relative) . length ( ) ;
595
- let new_relative = direction. map_or ( initial - relative, |direction| viewspace. inverse ( ) . transform_vector2 ( -direction * length) ) ;
596
- let modification_type = id. set_relative_position ( new_relative) ;
597
- responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
594
+ // When the handle is scaled to zero, don't update the mirror handle
595
+ if ( new_pos_viewport - relative) . length_squared ( ) > f64:: EPSILON {
596
+ let direction = viewspace. transform_vector2 ( new_pos_viewport - relative) . try_normalize ( ) ;
597
+ let length = viewspace. transform_vector2 ( initial - relative) . length ( ) ;
598
+ let new_relative = direction. map_or ( initial - relative, |direction| viewspace. inverse ( ) . transform_vector2 ( -direction * length) ) ;
599
+ let modification_type = id. set_relative_position ( new_relative) ;
600
+ responses. add ( GraphOperationMessage :: Vector { layer, modification_type } ) ;
601
+ }
598
602
}
599
603
}
600
604
}
@@ -624,8 +628,8 @@ impl<'a> Selected<'a> {
624
628
}
625
629
}
626
630
627
- pub fn update_transforms ( & mut self , delta : DAffine2 ) {
628
- let pivot = DAffine2 :: from_translation ( * self . pivot ) ;
631
+ pub fn update_transforms ( & mut self , delta : DAffine2 , pivot : Option < DVec2 > ) {
632
+ let pivot = DAffine2 :: from_translation ( pivot . unwrap_or_else ( || * self . pivot ) ) ;
629
633
let transformation = pivot * delta * pivot. inverse ( ) ;
630
634
match self . tool_type {
631
635
ToolType :: Pen => self . apply_transform_pen ( transformation) ,
0 commit comments