private void RotateWidgets(Vector2 pivotPoint, List <Widget> widgets, Vector2 curMousePos, Vector2 prevMousePos, bool discret, ref float accumAngle, ref float prevAngle) { List <KeyValuePair <Widget, float> > wasRotations = widgets.Select(widget => new KeyValuePair <Widget, float>(widget, widget.Rotation)).ToList(); float rotationRes = prevAngle; Utils.ApplyTransformationToWidgetsGroupOobb( sv.Scene, widgets, pivotPoint, false, curMousePos, prevMousePos, (originalVectorInOobbSpace, deformedVectorInOobbSpace) => { float rotation = 0; if (originalVectorInOobbSpace.Length > Mathf.ZeroTolerance && deformedVectorInOobbSpace.Length > Mathf.ZeroTolerance) { rotation = Mathf.Wrap180(deformedVectorInOobbSpace.Atan2Deg - originalVectorInOobbSpace.Atan2Deg); } if (discret) { rotation = Utils.RoundTo(rotation, 15); } rotationRes = rotation; return(Matrix32.Rotation(rotation * Mathf.DegToRad)); } ); // accumulate rotation, each visual turn of widget will increase it's angle on 360, // without that code angle will be allways [-180; 180) rotationRes = rotationRes.NormalizeRotation(); float rotationDelta = (rotationRes - prevAngle).NormalizeRotation(); prevAngle = rotationRes; accumAngle += rotationDelta; foreach (KeyValuePair <Widget, float> wasRotation in wasRotations) { SetAnimableProperty.Perform(wasRotation.Key, nameof(Widget.Rotation), wasRotation.Value + accumAngle); } }
private void DrawSegments(RulerData rulerData, float strokeDelta, float strokeLength, float?strokeValue = null) { var maskInverted = rulerData.RulerOrientation.GetDirection(); var mask = (Vector2.One - maskInverted); var delta = mask * strokeDelta; var j = -(int)Math.Round(((rulerData.Origin * mask).Length - rulerData.LeftStoper) / strokeDelta); var b = maskInverted * rulerData.Offset + rulerData.Origin * mask + j * strokeDelta * mask; var a = b - maskInverted * strokeLength; var fontHeight = 14f; var letterspacing = 1f; var textOffset = Vector2.Zero; do { if (GetVectorComponentForOrientation(a, rulerData.RulerOrientation) - rulerData.Offset >= 0) { Renderer.DrawLine(a, b, ColorTheme.Current.SceneView.RulerTextColor); if (strokeValue != null) { var lengthMarkerText = ((int)(j * strokeValue.Value)).ToString(); var textLength = FontPool.Instance.DefaultFont.MeasureTextLine(lengthMarkerText, fontHeight, letterspacing); var lengthMarkerPosition = a + textOffset; Renderer.PushState(RenderState.Transform1); Renderer.MultiplyTransform1(Matrix32.Translation(lengthMarkerPosition.X.Round(), lengthMarkerPosition.Y.Round())); if (rulerData.RulerOrientation == RulerOrientation.Vertical) { Renderer.MultiplyTransform1(Matrix32.Rotation(-Mathf.HalfPi)); textOffset = Vector2.Down * (5 + textLength.X); } else { textOffset = Vector2.Right * 5; } Renderer.DrawTextLine(Vector2.Zero, lengthMarkerText, fontHeight, ColorTheme.Current.SceneView.RulerTextColor, letterspacing); Renderer.PopState(); } } j++; a += delta; b += delta; } while (rulerData.RightStoper > GetVectorComponentForOrientation(a, rulerData.RulerOrientation)); }
void Render(Widget widget) { var maxCol = Timeline.Instance.ColumnCount; widget.PrepareRendererState(); Renderer.DrawRect(Vector2.Zero, widget.ContentSize, ColorTheme.Current.TimelineGrid.PropertyRowBackground); var colorIndex = PropertyAttributes <TangerineKeyframeColorAttribute> .Get(node.GetType(), animator.TargetProperty)?.ColorIndex ?? 0; var color = KeyframePalette.Colors[colorIndex]; var baseTransform = Renderer.Transform1; for (int i = 0; i < animator.ReadonlyKeys.Count; i++) { var key = animator.ReadonlyKeys[i]; Renderer.Transform1 = Matrix32.Rotation(Mathf.Pi / 4) * Matrix32.Translation((key.Frame + 0.5f) * TimelineMetrics.ColWidth + 0.5f, widget.Height / 2 + 0.5f) * baseTransform; var v = TimelineMetrics.ColWidth / 3 * Vector2.One; Renderer.DrawRect(-v, v, color); } }
public override void ExecuteTransaction() { var groups = Document.Current?.SelectedNodes().OfType <Frame>().ToList(); if (groups?.Count == 0) { return; } var container = (Widget)Document.Current.Container; var p = container.RootFolder().Find(groups[0]); ClearRowSelection.Perform(); UntieWidgetsFromBones.Perform(Document.Current.Container.Nodes.OfType <Bone>(), groups); foreach (var group in groups) { UnlinkFolderItem.Perform(container, group); } foreach (var group in groups) { var flipXFactor = group.Scale.X < 0 ? -1 : 1; var flipYFactor = group.Scale.Y < 0 ? -1 : 1; var flipVector = Vector2.Right + Vector2.Down * flipXFactor * flipYFactor; var groupRootBones = new List <Bone>(); var groupNodes = group.Nodes.ToList().Where(GroupNodes.IsValidNode).ToList(); var localToParentTransform = group.CalcLocalToParentTransform(); foreach (var node in groupNodes) { UnlinkFolderItem.Perform(group, node); InsertFolderItem.Perform(container, p, node); SelectNode.Perform(node); p.Index++; if (node is Widget) { GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Widget.Position), v => localToParentTransform * v); GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Widget.Scale), v => v * group.Scale); GroupNodes.TransformPropertyAndKeyframes <float>(node, nameof(Widget.Rotation), v => v * Mathf.Sign(group.Scale.X * group.Scale.Y) + group.Rotation); GroupNodes.TransformPropertyAndKeyframes <Color4>(node, nameof(Widget.Color), v => group.Color * v); } else if (node is Bone) { var root = BoneUtils.FindBoneRoot((Bone)node, groupNodes); if (!groupRootBones.Contains(root)) { GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Bone.Position), v => localToParentTransform * v); GroupNodes.TransformPropertyAndKeyframes <float>(node, nameof(Bone.Rotation), v => (Matrix32.Rotation(v * Mathf.DegToRad) * localToParentTransform).ToTransform2().Rotation); groupRootBones.Add(root); } else if (flipVector != Vector2.One) { GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Bone.Position), v => v * flipVector); GroupNodes.TransformPropertyAndKeyframes <float>(node, nameof(Bone.Rotation), v => - v); } GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Bone.RefPosition), v => localToParentTransform * v); GroupNodes.TransformPropertyAndKeyframes <float>(node, nameof(Bone.RefRotation), v => (Matrix32.Rotation(v * Mathf.DegToRad) * localToParentTransform).ToTransform2().Rotation); } } } }