public void Matrix32() { string fs = @"#version 330 uniform mat3x2 exampleMat32; out vec3 FragColor; void main() { FragColor = vec3(exampleMat32[1].x, exampleMat32[2].x, 0.0); }"; using (GraphicsWindow window = Device.CreateWindow(1, 1)) using (Framebuffer framebuffer = TestUtility.CreateFramebuffer(window.Context)) using (ShaderProgram sp = Device.CreateShaderProgram(ShaderSources.PassThroughVertexShader(), fs)) using (VertexArray va = TestUtility.CreateVertexArray(window.Context, sp.VertexAttributes["position"].Location)) { Matrix32 <float> m32 = new Matrix32 <float>( 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f); Uniform <Matrix32 <float> > exampleMat32 = (Uniform <Matrix32 <float> >)sp.Uniforms["exampleMat32"]; Assert.AreEqual("exampleMat32", exampleMat32.Name); Assert.AreEqual(UniformType.FloatMatrix32, exampleMat32.Datatype); Assert.AreEqual(new Matrix32 <float>(), exampleMat32.Value); exampleMat32.Value = m32; Assert.AreEqual(m32, exampleMat32.Value); window.Context.Framebuffer = framebuffer; window.Context.Draw(PrimitiveType.Points, 0, 1, new DrawState(TestUtility.CreateRenderStateWithoutDepthTest(), sp, va), new SceneState()); TestUtility.ValidateColor(framebuffer.ColorAttachments[0], 255, 255, 0); } }
void RescaleWidgets(Quadrangle originalHull, bool hullInFirstWidgetSpace, Vector2 hullsPivotPoint, List <Widget> widgets, int controlPointIndex, Vector2 curMousePos, Vector2 prevMousePos, bool proportional) { Utils.ApplyTransformationToWidgetsGroupOobb( sv.Scene, widgets, hullsPivotPoint, hullInFirstWidgetSpace, curMousePos, prevMousePos, (originalVectorInOobbSpace, deformedVectorInOobbSpace) => { Vector2 deformationScaleInOobbSpace = new Vector2( Math.Abs(originalVectorInOobbSpace.X) < Mathf.ZeroTolerance ? 1 : deformedVectorInOobbSpace.X / originalVectorInOobbSpace.X, Math.Abs(originalVectorInOobbSpace.Y) < Mathf.ZeroTolerance ? 1 : deformedVectorInOobbSpace.Y / originalVectorInOobbSpace.Y ); if (proportional) { deformationScaleInOobbSpace.X = (deformationScaleInOobbSpace.X + deformationScaleInOobbSpace.Y) / 2; deformationScaleInOobbSpace.Y = deformationScaleInOobbSpace.X; } if (!LookupInvolvedAxes[controlPointIndex][0]) { deformationScaleInOobbSpace.X = proportional ? deformationScaleInOobbSpace.Y : 1; } if (!LookupInvolvedAxes[controlPointIndex][1]) { deformationScaleInOobbSpace.Y = proportional ? deformationScaleInOobbSpace.X : 1; } return(Matrix32.Scaling(deformationScaleInOobbSpace)); } ); }
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); } }
private static void BakeSkinningTransform(SkinningWeights newSkinningWeights, Node node) { if (node is PointObject) { var point = (PointObject)node; var originTranslation = point.TransformedPosition; var boneArray = node.Parent.Parent.AsWidget.BoneArray; var localToParentTransform = node.Parent.AsWidget.CalcLocalToParentTransform(); var transformedPosition = originTranslation * localToParentTransform * boneArray.CalcWeightedRelativeTransform(newSkinningWeights).CalcInversed() * localToParentTransform.CalcInversed(); var translation = (transformedPosition - point.Offset) / point.Parent.AsWidget.Size; SetAnimableProperty.Perform(node, nameof(PointObject.Position), translation); } else { var widget = node.AsWidget; var originLocalToParent = node.AsWidget.CalcLocalToParentTransform(); var transform = (originLocalToParent * widget.Parent.AsWidget.BoneArray.CalcWeightedRelativeTransform(newSkinningWeights).CalcInversed()).ToTransform2(); SetAnimableProperty.Perform(node, nameof(Widget.Rotation), transform.Rotation); var localToParentTransform = Matrix32.Translation(-(widget.Pivot * widget.Size)) * Matrix32.Transformation( Vector2.Zero, widget.Scale, widget.Rotation * Mathf.Pi / 180f, Vector2.Zero); SetAnimableProperty.Perform(node, nameof(Widget.Position), transform.Translation - localToParentTransform.T); } }
private void CalcGeometry(Matrix32 matrix, out Vector2 a, out Vector2 b) { NineGrid.BuildLayout(parts, (Vector2)Owner.Texture.ImageSize, Owner.LeftOffset, Owner.RightOffset, Owner.TopOffset, Owner.BottomOffset, Owner.Size); a = matrix.TransformVector(parts[IndexA].Rect.A); b = matrix.TransformVector(parts[IndexB].Rect.B); }
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 ); }
public static void ApplyTransformationToWidgetsGroupOobb(IList <Widget> widgetsInParentSpace, Vector2 pivotInParentSpace, bool oobbInFirstWidgetSpace, Vector2 curMousePosInParentSpace, Vector2 prevMousePosInParentSpace, Func <Vector2, Vector2, Matrix32> onCalcTransformationFromOriginalVectorInOobbSpaceAndDeformedVectorInOobbSpace) { if (widgetsInParentSpace.Count == 0) { return; } Matrix32 originalOobbToParentSpace = Matrix32.Translation(pivotInParentSpace); if (oobbInFirstWidgetSpace) { Matrix32 firstWidgetToParentSpace = widgetsInParentSpace[0].CalcLocalToParentTransform(); originalOobbToParentSpace = firstWidgetToParentSpace * Matrix32.Translation(firstWidgetToParentSpace.T).CalcInversed() * Matrix32.Translation(pivotInParentSpace); } ApplyTransformationToWidgetsGroupOobb( widgetsInParentSpace, widgetsInParentSpace[0].ParentWidget, originalOobbToParentSpace, curMousePosInParentSpace, prevMousePosInParentSpace, onCalcTransformationFromOriginalVectorInOobbSpaceAndDeformedVectorInOobbSpace ); }
void Render(Widget widget) { widget.PrepareRendererState(); Renderer.DrawRect(Vector2.Zero, RootWidget.Size, ColorTheme.Current.Toolbar.Background); Renderer.Transform1 *= Matrix32.Translation(-Timeline.Instance.Offset.X, 0); RenderCursor(); for (int i = 0; i < Timeline.Instance.ColumnCount; i++) { var x = i * TimelineMetrics.ColWidth + 0.5f; if (i % 10 == 0) { float textHeight = Theme.Metrics.TextHeight; float y = (RootWidget.Height - textHeight) / 2; Renderer.DrawTextLine( new Vector2(x, y), i.ToString(), Theme.Metrics.TextHeight, Theme.Colors.BlackText, 0.0f); Renderer.DrawLine(x, 0, x, RootWidget.Height, ColorTheme.Current.TimelineRuler.Notchings); } } foreach (var m in Document.Current.Container.Markers) { RenderMarker(m); } }
private static void SetupViewportAndProjectionMatrix() { Renderer.SetOrthogonalProjection(0, 0, The.World.Width, The.World.Height); var windowSize = The.Window.ClientSize; The.Window.Input.MousePositionTransform = Matrix32.Scaling(The.World.Width / windowSize.X, The.World.Height / windowSize.Y); }
public void TransformTest() { var rectangle = new Rectangle(Vector2.Zero, Vector2.One); rectangle = rectangle.Transform(Matrix32.Scaling(Vector2.Half)); var expectedRectangle = new Rectangle(Vector2.Zero, Vector2.Half); Assert.That(rectangle, Is.EqualTo(expectedRectangle)); }
internal UniformFloatMatrix32GL3x(string name, int location, ICleanableObserver observer) : base(name, UniformType.FloatMatrix32) { _location = location; _value = new Matrix32 <float>(); _dirty = true; _observer = observer; _observer.NotifyDirty(this); }
public void Construct1() { Matrix32<double> m = new Matrix32<double>(1.0); for (int i = 0; i < m.NumberOfComponents; ++i) { Assert.AreEqual(1.0, m.ReadOnlyColumnMajorValues[0], 1e-14); } }
static void DrawRectOutline(Vector2 a, Vector2 b, Matrix32 t) { var c = ColorTheme.Current.SceneView.MouseSelection; Renderer.DrawLine(a * t, new Vector2(b.X, a.Y) * t, c, 1, LineCap.Square); Renderer.DrawLine(new Vector2(b.X, a.Y) * t, b * t, c, 1, LineCap.Square); Renderer.DrawLine(b * t, new Vector2(a.X, b.Y) * t, c, 1, LineCap.Square); Renderer.DrawLine(new Vector2(a.X, b.Y) * t, a * t, c, 1, LineCap.Square); }
protected static Rectangle CalcAABBInContainer(Matrix32 contentToContainer, Rectangle contentAABB) { var result = new Rectangle(float.MaxValue, float.MaxValue, float.MinValue, float.MinValue) .IncludingPoint(contentToContainer * contentAABB.A) .IncludingPoint(contentToContainer * new Vector2(contentAABB.Right, contentAABB.Top)) .IncludingPoint(contentToContainer * contentAABB.B) .IncludingPoint(contentToContainer * new Vector2(contentAABB.Left, contentAABB.Bottom)); return(result); }
IEnumerator <object> Rotate(Quadrangle hull, List <PointObject> points) { using (Document.Current.History.BeginTransaction()) { var t = Document.Current.Container.AsWidget.LocalToWorldTransform.CalcInversed(); hull *= Matrix32.Scaling(Vector2.One / Document.Current.Container.AsWidget.Size); var center = (hull.V1 + hull.V3) / 2; var size = Document.Current.Container.AsWidget.Size; var mousePosInitial = (sv.MousePosition * t - center * size) / size; var rotation = 0f; while (sv.Input.IsMousePressed()) { Document.Current.History.RollbackTransaction(); Utils.ChangeCursorIfDefault(Cursors.Rotate); var b = (sv.MousePosition * t - center * size) / size; var angle = 0f; if (mousePosInitial.Length > Mathf.ZeroTolerance && b.Length > Mathf.ZeroTolerance) { angle = Mathf.Wrap180(b.Atan2Deg - mousePosInitial.Atan2Deg); rotation = angle; } if (Math.Abs(angle) > Mathf.ZeroTolerance) { var effectiveAngle = sv.Input.IsKeyPressed(Key.Shift) ? Utils.RoundTo(rotation, 15) : angle; Quadrangle newBounds = new Quadrangle(); for (int i = 0; i < 4; i++) { newBounds[i] = Vector2.RotateDeg(hull[i] - center, effectiveAngle) + center; } for (var i = 0; i < points.Count; i++) { var offset = center - points[i].Offset / size; var position = Vector2.RotateDeg((points[i].Position - offset), effectiveAngle) + offset; Core.Operations.SetAnimableProperty.Perform(points[i], nameof(PointObject.Position), position, CoreUserPreferences.Instance.AutoKeyframes); if (points[i] is SplinePoint) { Core.Operations.SetAnimableProperty.Perform( points[i], nameof(SplinePoint.TangentAngle), (points[i] as SplinePoint).TangentAngle - effectiveAngle, CoreUserPreferences.Instance.AutoKeyframes ); } } } yield return(null); } sv.Input.ConsumeKey(Key.Mouse0); Window.Current.Invalidate(); Document.Current.History.CommitTransaction(); } }
private static void DrawCreateWidgetGizmo(Vector2 a, Vector2 b, Matrix32 t) { var c = ColorTheme.Current.SceneView.MouseSelection; Renderer.DrawLine(a * t, new Vector2(b.X, a.Y) * t, c, 1, LineCap.Square); Renderer.DrawLine(new Vector2(b.X, a.Y) * t, b * t, c, 1, LineCap.Square); Renderer.DrawLine(b * t, new Vector2(a.X, b.Y) * t, c, 1, LineCap.Square); Renderer.DrawLine(new Vector2(a.X, b.Y) * t, a * t, c, 1, LineCap.Square); var midX = (a.X + b.X) * 0.5f; var midY = (a.Y + b.Y) * 0.5f; Renderer.DrawLine(new Vector2(midX, a.Y) * t, new Vector2(midX, b.Y) * t, c, 1, LineCap.Square); Renderer.DrawLine(new Vector2(a.X, midY) * t, new Vector2(b.X, midY) * t, c, 1, LineCap.Square); }
public static void DrawCapsule(Vector2 a, Vector2 b, Vector2 n, Matrix32 t, int numSegments, Color4 color, float thickness = 1) { Renderer.DrawLine((a + n) * t, (b + n) * t, color, thickness); Renderer.DrawLine((a - n) * t, (b - n) * t, color, thickness); var step = 180 / numSegments; for (var i = 0; i < numSegments; i++) { var v1 = Vector2.RotateDeg(n, i * step); var v2 = Vector2.RotateDeg(n, (i + 1) * step); Renderer.DrawLine((v1 + a) * t, (v2 + a) * t, color, thickness); Renderer.DrawLine((-v1 + b) * t, (-v2 + b) * t, color, thickness); } }
private IEnumerator <object> Resize(Quadrangle hull, int controlPointIndex, Vector2 pivot) { var cursor = WidgetContext.Current.MouseCursor; using (Document.Current.History.BeginTransaction()) { var widgets = Document.Current.SelectedNodes().Editable().OfType <Widget>(); var mouseStartPos = SceneView.MousePosition; while (SceneView.Input.IsMousePressed()) { Document.Current.History.RollbackTransaction(); Matrix32 transform = Matrix32.Identity; Utils.ChangeCursorIfDefault(cursor); var proportional = SceneView.Input.IsKeyPressed(Key.Shift); var isChangingScale = SceneView.Input.IsKeyPressed(Key.Control); var toBeTransformed = widgets.Where(w => isChangingScale ? !w.IsPropertyReadOnly(nameof(Widget.Scale)) : !w.IsPropertyReadOnly(nameof(Widget.Size))).ToList(); var areChildrenFreezed = SceneView.Input.IsKeyPressed(Key.Z) && !isChangingScale && toBeTransformed.Count == 1; if (areChildrenFreezed) { transform = toBeTransformed[0].CalcTransitionToSpaceOf(Document.Current.Container.AsWidget); } var pivotPoint = isChangingScale ? (toBeTransformed.Count <= 1 ? (Vector2?)null : pivot) : hull[lookupPivotIndex[controlPointIndex] / 2]; RescaleWidgets( toBeTransformed.Count <= 1, pivotPoint, toBeTransformed, controlPointIndex, SceneView.MousePosition, mouseStartPos, proportional, !isChangingScale ); if (areChildrenFreezed) { transform *= Document.Current.Container.AsWidget.CalcTransitionToSpaceOf(toBeTransformed[0]); RestoreChildrenPositions(toBeTransformed[0], transform); } yield return(null); } SceneView.Input.ConsumeKey(Key.Mouse0); Document.Current.History.CommitTransaction(); } }
public void DoubleToFloat() { Matrix32<double> m = new Matrix32<double>( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); Matrix32<float> mf = Matrix32<double>.DoubleToFloat(m); Assert.AreEqual(1.0f, mf.Column0Row0, 1e-7); Assert.AreEqual(2.0f, mf.Column1Row0, 1e-7); Assert.AreEqual(3.0f, mf.Column2Row0, 1e-7); Assert.AreEqual(4.0f, mf.Column0Row1, 1e-7); Assert.AreEqual(5.0f, mf.Column1Row1, 1e-7); Assert.AreEqual(6.0f, mf.Column2Row1, 1e-7); }
private static void RestoreChildrenPositions(Widget widget, Matrix32 transform) { foreach (var child in widget.Nodes.OfType <Widget>()) { var newPosition = transform.TransformVector(child.Position); SetProperty.Perform(child, nameof(Widget.Position), newPosition); if (child.Animators.TryFind(nameof(Widget.Position), out var animator)) { foreach (var key in animator.ReadonlyKeys.ToList()) { var newKey = key.Clone(); newKey.Value = transform.TransformVector((Vector2)key.Value); SetKeyframe.Perform(animator, newKey); } } } }
void Render(Widget widget) { widget.PrepareRendererState(); Renderer.DrawRect(Vector2.Zero, RootWidget.Size, ColorTheme.Current.Toolbar.Background); Renderer.MultiplyTransform1(Matrix32.Translation(-Timeline.Instance.Offset.X.Round(), 0)); RenderCursor(); Timeline.Instance.GetVisibleColumnRange(out var minColumn, out var maxColumn); for (int i = minColumn; i <= maxColumn; i++) { if (i % 10 == 0) { var x = i * TimelineMetrics.ColWidth + 0.5f; float textHeight = Theme.Metrics.TextHeight; float y = (RootWidget.Height - textHeight) / 2; Renderer.DrawTextLine( new Vector2(x, y), i.ToString(), Theme.Metrics.TextHeight, Theme.Colors.BlackText, 0.0f); if (!Document.Current.Animation.IsCompound) { Renderer.DrawLine(x, 0, x, RootWidget.Height, ColorTheme.Current.TimelineRuler.Notchings); } } } bool metUpperMarker = false; foreach (var m in Document.Current.Animation.Markers) { if (upperMarker != m) { RenderMarker(m); } else { metUpperMarker = true; } } if (!metUpperMarker && upperMarker != null) { upperMarker = null; } RenderUpperMarker(); }
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)); }
public void Construct2() { Matrix32<double> m = new Matrix32<double>( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); Assert.AreEqual(1.0, m.Column0Row0); Assert.AreEqual(2.0, m.Column1Row0); Assert.AreEqual(3.0, m.Column2Row0); Assert.AreEqual(4.0, m.Column0Row1); Assert.AreEqual(5.0, m.Column1Row1); Assert.AreEqual(6.0, m.Column2Row1); Assert.AreEqual(1.0, m.ReadOnlyColumnMajorValues[0]); Assert.AreEqual(4.0, m.ReadOnlyColumnMajorValues[1]); Assert.AreEqual(2.0, m.ReadOnlyColumnMajorValues[2]); Assert.AreEqual(5.0, m.ReadOnlyColumnMajorValues[3]); Assert.AreEqual(3.0, m.ReadOnlyColumnMajorValues[4]); Assert.AreEqual(6.0, m.ReadOnlyColumnMajorValues[5]); }
private static Rectangle ExpandMeshLocalAABB( Rectangle aabb, Vector2 size, DistortionMeshPoint point, BoneArray bones, Matrix32 weightsMatrix, Matrix32 weightsMatrixInversed ) { var position = size * point.Position + point.Offset; if (point.SkinningWeights != null) { position = weightsMatrixInversed.TransformVector(bones.ApplySkinningToVector( weightsMatrix.TransformVector(position), point.SkinningWeights )); } return(aabb.IncludingPoint(position)); }
private 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(animator.Animable.GetType(), animator.TargetPropertyPath)?.ColorIndex ?? 0; var color = KeyframePalette.Colors[colorIndex]; for (int i = 0; i < animator.ReadonlyKeys.Count; i++) { var key = animator.ReadonlyKeys[i]; Renderer.Transform1 = Matrix32.RotationRough(Mathf.Pi / 4) * Matrix32.Translation((key.Frame + 0.5f) * TimelineMetrics.ColWidth + 0.5f, widget.Height / 2 + 0.5f) * widget.LocalToWorldTransform; var v = TimelineMetrics.ColWidth / 3 * Vector2.One; Renderer.DrawRect(-v, v, color); } }
public static void ApplyTransformationToWidgetsGroupOobb(Widget sceneWidget, IList <Widget> widgetsInParentSpace, Vector2 pivotInSceneSpace, bool oobbInFirstWidgetSpace, Vector2 curMousePosInSceneSpace, Vector2 prevMousePosSceneSpace, Func <Vector2, Vector2, Matrix32> onCalcTransformationFromOriginalVectorInOobbSpaceAndDeformedVectorInOobbSpace) { if (widgetsInParentSpace.Count == 0) { return; } Matrix32 fromSceneToParentSpace = sceneWidget.CalcTransitionToSpaceOf(widgetsInParentSpace[0].ParentWidget); ApplyTransformationToWidgetsGroupOobb( widgetsInParentSpace, pivotInSceneSpace * fromSceneToParentSpace, oobbInFirstWidgetSpace, curMousePosInSceneSpace * fromSceneToParentSpace, prevMousePosSceneSpace * fromSceneToParentSpace, onCalcTransformationFromOriginalVectorInOobbSpaceAndDeformedVectorInOobbSpace ); }
public void Equals() { Matrix32<double> a = new Matrix32<double>( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); Matrix32<double> b = new Matrix32<double>(0.0); Matrix32<double> c = new Matrix32<double>( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); Assert.IsTrue(a.Equals(c)); Assert.IsTrue(c.Equals(a)); Assert.IsTrue(a == c); Assert.IsTrue(c == a); Assert.IsFalse(c != a); Assert.IsFalse(c != a); Assert.IsFalse(a.Equals(b)); Assert.IsFalse(b.Equals(a)); Assert.IsFalse(a == b); Assert.IsFalse(b == a); Assert.IsTrue(a != b); Assert.IsTrue(b != a); object objA = a; object objB = b; object objC = c; Assert.IsTrue(a.Equals(objA)); Assert.IsTrue(a.Equals(objC)); Assert.IsFalse(a.Equals(objB)); Assert.IsTrue(objA.Equals(objC)); Assert.IsFalse(objA.Equals(objB)); Assert.IsFalse(a.Equals(null)); Assert.IsFalse(a.Equals(5)); }
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); } } }
public IEnumerator <object> Task() { while (true) { if (!SceneView.Instance.InputArea.IsMouseOverThisOrDescendant()) { yield return(null); continue; } var points = Document.Current.SelectedNodes().Editable().OfType <PointObject>().ToList(); if (points.Count > 1) { Rectangle aabb; Utils.CalcAABB(points, Document.Current.Container.AsWidget, out aabb); var hull = aabb.ToQuadrangle(); var hullSize = hull.V3 - hull.V1; hullNormalized = hull * Matrix32.Scaling(Vector2.One / Document.Current.Container.AsWidget.Size); var expandedHullInSceneCoords = PointObjectsPresenter.ExpandAndTranslateToSpaceOf(hull, Document.Current.Container.AsWidget, sv.Frame) * sv.Frame.CalcTransitionToSpaceOf(sv.Scene); for (int i = 0; i < 4; i++) { if (Mathf.Abs(hullSize.X) > Mathf.ZeroTolerance && Mathf.Abs(hullSize.Y) > Mathf.ZeroTolerance) { if (sv.HitTestResizeControlPoint(expandedHullInSceneCoords[i])) { Utils.ChangeCursorIfDefault(MouseCursor.SizeNS); if (sv.Input.ConsumeKeyPress(Key.Mouse0)) { yield return(Rescale(i * 2, MouseCursor.SizeNS, points)); } } } } for (int i = 0; i < 4; i++) { if (Mathf.Abs(hullSize.X) < Mathf.ZeroTolerance && i % 2 == 1 || Mathf.Abs(hullSize.Y) < Mathf.ZeroTolerance && i % 2 == 0 ) { continue; } var a = expandedHullInSceneCoords[i]; var b = expandedHullInSceneCoords[(i + 1) % 4]; if (sv.HitTestResizeControlPoint((a + b) / 2)) { var cursor = MouseCursor.Default; if (Mathf.Abs(hullSize.X) < Mathf.ZeroTolerance) { cursor = MouseCursor.SizeNS; } else if (Mathf.Abs(hullSize.Y) < Mathf.ZeroTolerance) { cursor = MouseCursor.SizeWE; } else { cursor = (b.X - a.X).Abs() > (b.Y - a.Y).Abs() ? MouseCursor.SizeNS : MouseCursor.SizeWE; } Utils.ChangeCursorIfDefault(cursor); if (sv.Input.ConsumeKeyPress(Key.Mouse0)) { yield return(Rescale(i * 2 + 1, cursor, points)); } } } } yield return(null); } }
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); } } } }
public void TestGetHashCode() { Matrix32<double> a = new Matrix32<double>( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); Matrix32<double> b = new Matrix32<double>(0.0); Matrix32<double> c = new Matrix32<double>( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); Assert.AreEqual(a.GetHashCode(), c.GetHashCode()); Assert.AreNotEqual(a.GetHashCode(), b.GetHashCode()); }
public void Matrix32() { string fs = @"#version 330 uniform mat3x2 exampleMat32; out vec3 FragColor; void main() { FragColor = vec3(exampleMat32[1].x, exampleMat32[2].x, 0.0); }"; using (GraphicsWindow window = Device.CreateWindow(1, 1)) using (Framebuffer framebuffer = TestUtility.CreateFramebuffer(window.Context)) using (ShaderProgram sp = Device.CreateShaderProgram(ShaderSources.PassThroughVertexShader(), fs)) using (VertexArray va = TestUtility.CreateVertexArray(window.Context, sp.VertexAttributes["position"].Location)) { Matrix32<float> m32 = new Matrix32<float>( 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f); Uniform<Matrix32<float>> exampleMat32 = (Uniform<Matrix32<float>>)sp.Uniforms["exampleMat32"]; Assert.AreEqual("exampleMat32", exampleMat32.Name); Assert.AreEqual(UniformType.FloatMatrix32, exampleMat32.Datatype); Assert.AreEqual(new Matrix32<float>(), exampleMat32.Value); exampleMat32.Value = m32; Assert.AreEqual(m32, exampleMat32.Value); window.Context.Framebuffer = framebuffer; window.Context.Draw(PrimitiveType.Points, 0, 1, new DrawState(TestUtility.CreateRenderStateWithoutDepthTest(), sp, va), new SceneState()); TestUtility.ValidateColor(framebuffer.ColorAttachments[0], 255, 255, 0); } }
public override void MultiplyTransform2(Matrix32 transform) { var cmd = AddCommand <MultiplyTransform2Command>(); cmd.Value = transform; }
protected static Rectangle CalcAABBInContainer(Matrix32 containerWorldToLocal, Matrix32 contentLocalToWorld, Rectangle contentAABB) { return(CalcAABBInContainer(contentLocalToWorld * containerWorldToLocal, contentAABB)); }
public ViewRectProjector(Widget widget, Rectangle area) { Widget = widget; Area = area; viewWorldToLocal = Widget.LocalToWorldTransform.CalcInversed(); }