public static void ApplyTransformationToWidgetsGroupOobb(IEnumerable <Widget> widgetsInParentSpace, Widget parentWidget, Matrix32 oobbInParentSpace, Vector2 curMousePosInParentSpace, Vector2 prevMousePosInParentSpace, Func <Vector2, Vector2, Matrix32> onCalcTransformationFromOriginalVectorInOobbSpaceAndDeformedVectorInOobbSpace) { Vector2 pivotInParentSpace = oobbInParentSpace.T; Vector2 pivotInOobbSpace = pivotInParentSpace; Vector2 controlPointInOobbSpace = prevMousePosInParentSpace; Vector2 targetPointInOobbSpace = curMousePosInParentSpace; Matrix32 transformationFromParentToOobb = oobbInParentSpace.CalcInversed(); pivotInOobbSpace = pivotInOobbSpace * transformationFromParentToOobb; controlPointInOobbSpace = controlPointInOobbSpace * transformationFromParentToOobb; targetPointInOobbSpace = targetPointInOobbSpace * transformationFromParentToOobb; Vector2 originalVectorInOobbSpace = controlPointInOobbSpace - pivotInOobbSpace; Vector2 deformedVectorInOobbSpace = targetPointInOobbSpace - pivotInOobbSpace; // calculate transformation from original vector to deformed vector Matrix32 deformationInOobbSpace = onCalcTransformationFromOriginalVectorInOobbSpaceAndDeformedVectorInOobbSpace(originalVectorInOobbSpace, deformedVectorInOobbSpace); ApplyTransformationToWidgetsGroupOobb( widgetsInParentSpace, parentWidget, oobbInParentSpace, deformationInOobbSpace ); }
void RescaleHelper(List <PointObject> points, int controlPointIndex, bool proportional, bool centerProportional) { var t = sv.Scene.CalcTransitionToSpaceOf(Document.Current.Container.AsWidget); t.T = Vector2.Zero; var transformedMouseDelta = (sv.MousePosition - initialMousePosition) * t / Document.Current.Container.AsWidget.Size; Vector2 origin; var idx = (controlPointIndex + 4) % 8 / 2; var next = (idx + 1) % 4; var prev = (idx + 3) % 4; var axisX = hullNormalized[next] - hullNormalized[idx]; var axisY = hullNormalized[prev] - hullNormalized[idx]; if (controlPointIndex == 7 || controlPointIndex == 3 || controlPointIndex == 1 || controlPointIndex == 5) { origin = (hullNormalized[next] + hullNormalized[idx]) / 2; } else { origin = hullNormalized[idx]; } axisX.Snap(Vector2.Zero); axisY.Snap(Vector2.Zero); if (axisX == Vector2.Zero) { axisX = new Vector2(-axisY.Y, axisY.X); } if (axisY == Vector2.Zero) { axisY = new Vector2(-axisX.Y, axisX.X); } var basis = new Matrix32(axisX, axisY, centerProportional ? (hullNormalized.V1 + hullNormalized.V3) / 2 : origin); var basisInversed = basis.CalcInversed(); var deltaSize = basisInversed * transformedMouseDelta - Vector2.Zero * basisInversed; deltaSize = (deltaSize * (controlPointIndex % 2 == 0 ? Vector2.One : Vector2.Down)).Snap(Vector2.Zero); if (deltaSize == Vector2.Zero) { return; } var avSize = 0.5f * (deltaSize.X + deltaSize.Y); if (proportional) { if (controlPointIndex == 7 || controlPointIndex == 3 || controlPointIndex == 1 || controlPointIndex == 5) { deltaSize.X = deltaSize.Y; } else { deltaSize.X = avSize; deltaSize.Y = avSize; } } for (var i = 0; i < points.Count; i++) { var deltaPos = basisInversed * points[i].Position * deltaSize * basis - Vector2.Zero * basis; Core.Operations.SetAnimableProperty.Perform(points[i], nameof(PointObject.Position), points[i].Position + deltaPos, CoreUserPreferences.Instance.AutoKeyframes); } }
public static void ApplyTransformationToWidgetsGroupOobb(IEnumerable <Widget> widgetsInParentSpace, Widget parentWidget, Matrix32 oobbInParentSpace, Matrix32 oobbTransformation) { Matrix32 originalOobbToWorldSpace = oobbInParentSpace * parentWidget.LocalToWorldTransform; foreach (Widget widget in widgetsInParentSpace) { Matrix32 widgetToOriginalOobbSpace = widget.LocalToWorldTransform * originalOobbToWorldSpace.CalcInversed(); // calculate new oobb transformation in world space Matrix32 deformedOobbToWorldSpace = oobbTransformation * originalOobbToWorldSpace; Matrix32 deformedWidgetToWorldSpace = widgetToOriginalOobbSpace * deformedOobbToWorldSpace; Matrix32 deformedWidgetToParentSpace = deformedWidgetToWorldSpace * widget.ParentWidget.LocalToWorldTransform.CalcInversed(); Transform2 widgetResultTransform = widget.CalcApplicableTransfrom2(deformedWidgetToParentSpace); // correct rotation delta, to prevent wrong values if new angle 0 and previous is 359, // then rotationDelta must be 1 float rotationDelta = (widget.Rotation - widgetResultTransform.Rotation).NormalizeRotation(); if ((widget.Position - widgetResultTransform.Translation).Length > Mathf.ZeroTolerance) { SetAnimableProperty.Perform(widget, nameof(Widget.Position), widgetResultTransform.Translation); } if (Mathf.Abs(rotationDelta) > Mathf.ZeroTolerance) { SetAnimableProperty.Perform(widget, nameof(Widget.Rotation), widget.Rotation + rotationDelta); } if ((widget.Scale - widgetResultTransform.Scale).Length > Mathf.ZeroTolerance) { SetAnimableProperty.Perform(widget, nameof(Widget.Scale), widgetResultTransform.Scale); } } }