Exemplo n.º 1
0
        public static void ApplyTransformationToWidgetsGroupObb(IEnumerable <Widget> widgetsInParentSpace,
                                                                Matrix32d obbInParentSpace, Vector2d currentMousePosInParentSpace, Vector2d previousMousePosInParentSpace,
                                                                bool convertScaleToSize, CalculateTransformationDelegate onCalculateTransformation)
        {
            if (Math.Abs(obbInParentSpace.CalcDeterminant()) < Mathf.ZeroTolerance)
            {
                return;
            }

            Matrix32d transformationFromParentToObb = obbInParentSpace.CalcInversed();
            Vector2d  controlPointInObbSpace        = previousMousePosInParentSpace * transformationFromParentToObb;
            Vector2d  targetPointInObbSpace         = currentMousePosInParentSpace * transformationFromParentToObb;

            Vector2d originalVectorInObbSpace = controlPointInObbSpace;
            Vector2d deformedVectorInObbSpace = targetPointInObbSpace;

            Transform2d obbTransformation = onCalculateTransformation(
                originalVectorInObbSpace, deformedVectorInObbSpace
                );

            ApplyTransformationToWidgetsGroupObb(
                widgetsInParentSpace, obbInParentSpace, obbTransformation, convertScaleToSize
                );
        }
Exemplo n.º 2
0
        public static void ApplyTransformationToWidgetsGroupObb(IEnumerable <Widget> widgetsInParentSpace,
                                                                Matrix32d obbInParentSpace, Transform2d obbTransformation, bool convertScaleToSize)
        {
            Matrix32d originalObbToParentSpace = obbInParentSpace;

            if (Math.Abs(originalObbToParentSpace.CalcDeterminant()) < Mathf.ZeroTolerance)
            {
                return;
            }

            Matrix32d obbTransformationMatrix = obbTransformation.ToMatrix32();

            foreach (Widget widget in widgetsInParentSpace)
            {
                WidgetZeroScalePreserver zeroScalePreserver = new WidgetZeroScalePreserver(widget);
                zeroScalePreserver.Store();
                try {
                    Matrix32d widgetToParentSpace      = widget.CalcLocalToParentTransformDouble();
                    Matrix32d widgetToOriginalObbSpace = widgetToParentSpace * originalObbToParentSpace.CalcInversed();

                    // Calculate the new obb transformation in the parent space.
                    Matrix32d deformedObbToParentSpace = obbTransformationMatrix * originalObbToParentSpace;

                    Matrix32d deformedWidgetToParentSpace = widgetToOriginalObbSpace * deformedObbToParentSpace;

                    Transform2d widgetResultTransform = widget.ExtractTransform2Double(deformedWidgetToParentSpace,
                                                                                       widget.Rotation + obbTransformation.Rotation);

                    // Correct a rotation delta, to prevent wrong values if a new angle 0 and previous is 359,
                    // then rotationDelta must be 1.
                    double rotationDelta = Mathd.Wrap180(widgetResultTransform.Rotation - widget.Rotation);

                    // Reduce an influence of small transformations (Scale, Position, Rotation).
                    bool needChangeScaleX = IsSignificantChangeOfValue(widget.Scale.X, widgetResultTransform.Scale.X);
                    bool needChangeScaleY = IsSignificantChangeOfValue(widget.Scale.Y, widgetResultTransform.Scale.Y);

                    if (needChangeScaleX || needChangeScaleY)
                    {
                        Vector2 useScale = new Vector2(
                            (float)(!needChangeScaleX ? widget.Scale.X : widgetResultTransform.Scale.X),
                            (float)(!needChangeScaleY ? widget.Scale.Y : widgetResultTransform.Scale.Y)
                            );
                        useScale = zeroScalePreserver.AdjustToScale(useScale);

                        zeroScalePreserver.Restore();

                        if (!convertScaleToSize)
                        {
                            SetAnimableProperty.Perform(widget, nameof(Widget.Scale), useScale,
                                                        CoreUserPreferences.Instance.AutoKeyframes);
                        }
                        else
                        {
                            Vector2 useSize = new Vector2(
                                Math.Abs(widget.Scale.X) < FloatSignificantDelta
                                                                        ? widget.Size.X
                                                                        : widget.Size.X * Math.Abs(useScale.X / widget.Scale.X),
                                Math.Abs(widget.Scale.Y) < FloatSignificantDelta
                                                                        ? widget.Size.Y
                                                                        : widget.Size.Y * Math.Abs(useScale.Y / widget.Scale.Y)
                                );
                            SetAnimableProperty.Perform(widget, nameof(Widget.Size), useSize,
                                                        CoreUserPreferences.Instance.AutoKeyframes);
                        }
                    }

                    bool needChangePositionX = IsSignificantChangeOfValue(widget.Position.X, widgetResultTransform.Translation.X);
                    bool needChangePositionY = IsSignificantChangeOfValue(widget.Position.Y, widgetResultTransform.Translation.Y);

                    if (needChangePositionX || needChangePositionY)
                    {
                        SetAnimableProperty.Perform(widget, nameof(Widget.Position),
                                                    new Vector2(
                                                        (float)(!needChangePositionX ? widget.Position.X : widgetResultTransform.Translation.X),
                                                        (float)(!needChangePositionY ? widget.Position.Y : widgetResultTransform.Translation.Y)
                                                        ),
                                                    CoreUserPreferences.Instance.AutoKeyframes);
                    }

                    if (IsSignificantChangeByDelta(widget.Rotation, rotationDelta))
                    {
                        SetAnimableProperty.Perform(widget, nameof(Widget.Rotation), (float)(widget.Rotation + rotationDelta),
                                                    CoreUserPreferences.Instance.AutoKeyframes);
                    }
                } finally {
                    zeroScalePreserver.Restore();
                }
            }
        }