A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5using osu.Framework.Extensions.MatrixExtensions;
6using osuTK;
7using osu.Framework.Extensions.TypeExtensions;
8using osu.Framework.Utils;
9
10namespace osu.Framework.Graphics
11{
12 public struct DrawInfo : IEquatable<DrawInfo>
13 {
14 public Matrix3 Matrix;
15 public Matrix3 MatrixInverse;
16
17 public DrawInfo(Matrix3? matrix = null, Matrix3? matrixInverse = null)
18 {
19 Matrix = matrix ?? Matrix3.Identity;
20 MatrixInverse = matrixInverse ?? Matrix3.Identity;
21 }
22
23 /// <summary>
24 /// Applies a transformation to the current DrawInfo.
25 /// </summary>
26 /// <param name="translation">The amount by which to translate the current position.</param>
27 /// <param name="scale">The amount by which to scale.</param>
28 /// <param name="rotation">The amount by which to rotate.</param>
29 /// <param name="shear">The shear amounts for both directions.</param>
30 /// <param name="origin">The center of rotation and scale.</param>
31 public void ApplyTransform(Vector2 translation, Vector2 scale, float rotation, Vector2 shear, Vector2 origin)
32 {
33 if (translation != Vector2.Zero)
34 {
35 MatrixExtensions.TranslateFromLeft(ref Matrix, translation);
36 MatrixExtensions.TranslateFromRight(ref MatrixInverse, -translation);
37 }
38
39 if (rotation != 0)
40 {
41 float radians = MathUtils.DegreesToRadians(rotation);
42 MatrixExtensions.RotateFromLeft(ref Matrix, radians);
43 MatrixExtensions.RotateFromRight(ref MatrixInverse, -radians);
44 }
45
46 if (shear != Vector2.Zero)
47 {
48 MatrixExtensions.ShearFromLeft(ref Matrix, -shear);
49 MatrixExtensions.ShearFromRight(ref MatrixInverse, shear);
50 }
51
52 if (scale != Vector2.One)
53 {
54 Vector2 inverseScale = new Vector2(1.0f / scale.X, 1.0f / scale.Y);
55 MatrixExtensions.ScaleFromLeft(ref Matrix, scale);
56 MatrixExtensions.ScaleFromRight(ref MatrixInverse, inverseScale);
57 }
58
59 if (origin != Vector2.Zero)
60 {
61 MatrixExtensions.TranslateFromLeft(ref Matrix, -origin);
62 MatrixExtensions.TranslateFromRight(ref MatrixInverse, origin);
63 }
64
65 //========================================================================================
66 //== Uncomment the following 2 lines to use a ground-truth matrix inverse for debugging ==
67 //========================================================================================
68 //target.MatrixInverse = target.Matrix;
69 //MatrixExtensions.FastInvert(ref target.MatrixInverse);
70 }
71
72 public readonly bool Equals(DrawInfo other) => Matrix.Equals(other.Matrix);
73
74 public override string ToString() => $@"{GetType().ReadableName().Replace(@"DrawInfo", string.Empty)} DrawInfo";
75 }
76}