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 osuTK;
6
7namespace osu.Framework.Extensions.MatrixExtensions
8{
9 public static class MatrixExtensions
10 {
11 public static void TranslateFromLeft(ref Matrix3 m, Vector2 v)
12 {
13 m.Row2 += m.Row0 * v.X + m.Row1 * v.Y;
14 }
15
16 public static void TranslateFromRight(ref Matrix3 m, Vector2 v)
17 {
18 //m.Column0 += m.Column2 * v.X;
19 m.M11 += m.M13 * v.X;
20 m.M21 += m.M23 * v.X;
21 m.M31 += m.M33 * v.X;
22
23 //m.Column1 += m.Column2 * v.Y;
24 m.M12 += m.M13 * v.Y;
25 m.M22 += m.M23 * v.Y;
26 m.M32 += m.M33 * v.Y;
27 }
28
29 public static void RotateFromLeft(ref Matrix3 m, float radians)
30 {
31 float cos = MathF.Cos(radians);
32 float sin = MathF.Sin(radians);
33
34 Vector3 row0 = m.Row0 * cos + m.Row1 * sin;
35 m.Row1 = m.Row1 * cos - m.Row0 * sin;
36 m.Row0 = row0;
37 }
38
39 public static void RotateFromRight(ref Matrix3 m, float radians)
40 {
41 float cos = MathF.Cos(radians);
42 float sin = MathF.Sin(radians);
43
44 //Vector3 column0 = m.Column0 * cos + m.Column1 * sin;
45 float m11 = m.M11 * cos - m.M12 * sin;
46 float m21 = m.M21 * cos - m.M22 * sin;
47 float m31 = m.M31 * cos - m.M32 * sin;
48
49 //m.Column1 = m.Column1 * cos - m.Column0 * sin;
50 m.M12 = m.M12 * cos + m.M11 * sin;
51 m.M22 = m.M22 * cos + m.M21 * sin;
52 m.M32 = m.M32 * cos + m.M31 * sin;
53
54 //m.Column0 = row0;
55 m.M11 = m11;
56 m.M21 = m21;
57 m.M31 = m31;
58 }
59
60 public static void ScaleFromLeft(ref Matrix3 m, Vector2 v)
61 {
62 m.Row0 *= v.X;
63 m.Row1 *= v.Y;
64 }
65
66 public static void ScaleFromRight(ref Matrix3 m, Vector2 v)
67 {
68 //m.Column0 *= v.X;
69 m.M11 *= v.X;
70 m.M21 *= v.X;
71 m.M31 *= v.X;
72
73 //m.Column1 *= v.Y;
74 m.M12 *= v.Y;
75 m.M22 *= v.Y;
76 m.M32 *= v.Y;
77 }
78
79 /// <summary>
80 /// Apply shearing in X and Y direction from the left hand side.
81 /// Since shearing is non-commutative it is important to note that we
82 /// first shear in the X direction, and then in the Y direction.
83 /// </summary>
84 /// <param name="m">The matrix to apply the shearing operation to.</param>
85 /// <param name="v">The X and Y amounts of shearing.</param>
86 public static void ShearFromLeft(ref Matrix3 m, Vector2 v)
87 {
88 Vector3 row0 = m.Row0 + m.Row1 * v.Y + m.Row0 * v.X * v.Y;
89 m.Row1 += m.Row0 * v.X;
90 m.Row0 = row0;
91 }
92
93 /// <summary>
94 /// Apply shearing in X and Y direction from the right hand side.
95 /// Since shearing is non-commutative it is important to note that we
96 /// first shear in the Y direction, and then in the X direction.
97 /// </summary>
98 /// <param name="m">The matrix to apply the shearing operation to.</param>
99 /// <param name="v">The X and Y amounts of shearing.</param>
100 public static void ShearFromRight(ref Matrix3 m, Vector2 v)
101 {
102 float xy = v.X * v.Y;
103
104 //m.Column0 += m.Column1 * v.X;
105 float m11 = m.M11 + m.M12 * v.X;
106 float m21 = m.M21 + m.M22 * v.X;
107 float m31 = m.M31 + m.M32 * v.X;
108
109 //m.Column1 += m.Column0 * v.Y + m.Column1 * xy;
110 m.M12 += m.M11 * v.Y + m.M12 * xy;
111 m.M22 += m.M21 * v.Y + m.M22 * xy;
112 m.M32 += m.M31 * v.Y + m.M32 * xy;
113
114 m.M11 = m11;
115 m.M21 = m21;
116 m.M31 = m31;
117 }
118
119 public static void FastInvert(ref Matrix3 value)
120 {
121 float d11 = value.M22 * value.M33 + value.M23 * -value.M32;
122 float d12 = value.M21 * value.M33 + value.M23 * -value.M31;
123 float d13 = value.M21 * value.M32 + value.M22 * -value.M31;
124
125 float det = value.M11 * d11 - value.M12 * d12 + value.M13 * d13;
126
127 if (Math.Abs(det) == 0.0f)
128 {
129 value = Matrix3.Zero;
130 return;
131 }
132
133 det = 1f / det;
134
135 float d21 = value.M12 * value.M33 + value.M13 * -value.M32;
136 float d22 = value.M11 * value.M33 + value.M13 * -value.M31;
137 float d23 = value.M11 * value.M32 + value.M12 * -value.M31;
138
139 float d31 = value.M12 * value.M23 - value.M13 * value.M22;
140 float d32 = value.M11 * value.M23 - value.M13 * value.M21;
141 float d33 = value.M11 * value.M22 - value.M12 * value.M21;
142
143 value.M11 = +d11 * det;
144 value.M12 = -d21 * det;
145 value.M13 = +d31 * det;
146 value.M21 = -d12 * det;
147 value.M22 = +d22 * det;
148 value.M23 = -d32 * det;
149 value.M31 = +d13 * det;
150 value.M32 = -d23 * det;
151 value.M33 = +d33 * det;
152 }
153 }
154}