sonolus.py 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sonolus.py might be problematic. Click here for more details.
- sonolus/backend/finalize.py +18 -10
- sonolus/backend/interpret.py +7 -7
- sonolus/backend/ir.py +24 -0
- sonolus/backend/optimize/__init__.py +0 -0
- sonolus/backend/{allocate.py → optimize/allocate.py} +4 -3
- sonolus/backend/{constant_evaluation.py → optimize/constant_evaluation.py} +7 -7
- sonolus/backend/{coalesce.py → optimize/copy_coalesce.py} +3 -3
- sonolus/backend/optimize/dead_code.py +185 -0
- sonolus/backend/{dominance.py → optimize/dominance.py} +2 -17
- sonolus/backend/{flow.py → optimize/flow.py} +6 -5
- sonolus/backend/{inlining.py → optimize/inlining.py} +4 -17
- sonolus/backend/{liveness.py → optimize/liveness.py} +69 -65
- sonolus/backend/optimize/optimize.py +44 -0
- sonolus/backend/{passes.py → optimize/passes.py} +1 -1
- sonolus/backend/optimize/simplify.py +191 -0
- sonolus/backend/{ssa.py → optimize/ssa.py} +31 -18
- sonolus/backend/place.py +17 -25
- sonolus/backend/utils.py +10 -0
- sonolus/backend/visitor.py +360 -101
- sonolus/build/cli.py +14 -3
- sonolus/build/compile.py +8 -8
- sonolus/build/engine.py +10 -5
- sonolus/build/project.py +30 -1
- sonolus/script/archetype.py +429 -138
- sonolus/script/array.py +25 -8
- sonolus/script/array_like.py +297 -0
- sonolus/script/bucket.py +73 -11
- sonolus/script/containers.py +234 -51
- sonolus/script/debug.py +8 -8
- sonolus/script/easing.py +147 -105
- sonolus/script/effect.py +60 -0
- sonolus/script/engine.py +71 -4
- sonolus/script/globals.py +66 -32
- sonolus/script/instruction.py +79 -25
- sonolus/script/internal/builtin_impls.py +138 -27
- sonolus/script/internal/constant.py +139 -0
- sonolus/script/internal/context.py +14 -5
- sonolus/script/internal/dict_impl.py +65 -0
- sonolus/script/internal/generic.py +6 -9
- sonolus/script/internal/impl.py +38 -13
- sonolus/script/internal/introspection.py +5 -2
- sonolus/script/{math.py → internal/math_impls.py} +28 -28
- sonolus/script/internal/native.py +3 -3
- sonolus/script/internal/random.py +67 -0
- sonolus/script/internal/range.py +81 -0
- sonolus/script/internal/transient.py +51 -0
- sonolus/script/internal/tuple_impl.py +113 -0
- sonolus/script/interval.py +234 -16
- sonolus/script/iterator.py +120 -167
- sonolus/script/level.py +24 -0
- sonolus/script/num.py +79 -47
- sonolus/script/options.py +78 -12
- sonolus/script/particle.py +37 -4
- sonolus/script/pointer.py +4 -4
- sonolus/script/print.py +22 -1
- sonolus/script/project.py +59 -0
- sonolus/script/{graphics.py → quad.py} +75 -12
- sonolus/script/record.py +44 -13
- sonolus/script/runtime.py +50 -1
- sonolus/script/sprite.py +198 -115
- sonolus/script/text.py +2 -0
- sonolus/script/timing.py +72 -0
- sonolus/script/transform.py +296 -66
- sonolus/script/ui.py +134 -78
- sonolus/script/values.py +6 -13
- sonolus/script/vec.py +118 -3
- {sonolus_py-0.1.4.dist-info → sonolus_py-0.1.6.dist-info}/METADATA +1 -1
- sonolus_py-0.1.6.dist-info/RECORD +89 -0
- sonolus/backend/dead_code.py +0 -80
- sonolus/backend/optimize.py +0 -37
- sonolus/backend/simplify.py +0 -47
- sonolus/script/comptime.py +0 -160
- sonolus/script/random.py +0 -14
- sonolus/script/range.py +0 -58
- sonolus_py-0.1.4.dist-info/RECORD +0 -84
- /sonolus/script/{callbacks.py → internal/callbacks.py} +0 -0
- {sonolus_py-0.1.4.dist-info → sonolus_py-0.1.6.dist-info}/WHEEL +0 -0
- {sonolus_py-0.1.4.dist-info → sonolus_py-0.1.6.dist-info}/entry_points.txt +0 -0
- {sonolus_py-0.1.4.dist-info → sonolus_py-0.1.6.dist-info}/licenses/LICENSE +0 -0
sonolus/script/transform.py
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
from math import cos, sin
|
|
2
2
|
from typing import Self
|
|
3
3
|
|
|
4
|
-
from sonolus.script.
|
|
5
|
-
from sonolus.script.math import cos, sin
|
|
4
|
+
from sonolus.script.quad import Quad, QuadLike
|
|
6
5
|
from sonolus.script.record import Record
|
|
7
6
|
from sonolus.script.vec import Vec2
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
class Transform2d(Record):
|
|
10
|
+
"""A transformation matrix for 2D points.
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
```
|
|
14
|
+
Transform2d.new()
|
|
15
|
+
```
|
|
16
|
+
"""
|
|
17
|
+
|
|
11
18
|
a00: float
|
|
12
19
|
a01: float
|
|
13
20
|
a02: float
|
|
@@ -20,19 +27,36 @@ class Transform2d(Record):
|
|
|
20
27
|
|
|
21
28
|
@classmethod
|
|
22
29
|
def new(cls) -> Self:
|
|
23
|
-
"""Create a new identity transform.
|
|
30
|
+
"""Create a new identity transform.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
A new identity transform.
|
|
34
|
+
"""
|
|
24
35
|
return cls(
|
|
25
|
-
1,
|
|
26
|
-
0,
|
|
27
|
-
0,
|
|
36
|
+
1,
|
|
37
|
+
0,
|
|
38
|
+
0,
|
|
39
|
+
0,
|
|
40
|
+
1,
|
|
41
|
+
0,
|
|
42
|
+
0,
|
|
43
|
+
0,
|
|
44
|
+
1,
|
|
28
45
|
)
|
|
29
46
|
|
|
30
|
-
def _compose(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
def _compose(
|
|
48
|
+
self,
|
|
49
|
+
b00: float,
|
|
50
|
+
b01: float,
|
|
51
|
+
b02: float,
|
|
52
|
+
b10: float,
|
|
53
|
+
b11: float,
|
|
54
|
+
b12: float,
|
|
55
|
+
b20: float,
|
|
56
|
+
b21: float,
|
|
57
|
+
b22: float,
|
|
34
58
|
) -> Self:
|
|
35
|
-
|
|
59
|
+
# Multiply by b on the left (b @ a)
|
|
36
60
|
a00 = self.a00 * b00 + self.a10 * b01 + self.a20 * b02
|
|
37
61
|
a01 = self.a01 * b00 + self.a11 * b01 + self.a21 * b02
|
|
38
62
|
a02 = self.a02 * b00 + self.a12 * b01 + self.a22 * b02
|
|
@@ -43,123 +67,329 @@ class Transform2d(Record):
|
|
|
43
67
|
a21 = self.a01 * b20 + self.a11 * b21 + self.a21 * b22
|
|
44
68
|
a22 = self.a02 * b20 + self.a12 * b21 + self.a22 * b22
|
|
45
69
|
return Transform2d(
|
|
46
|
-
a00,
|
|
47
|
-
|
|
48
|
-
|
|
70
|
+
a00,
|
|
71
|
+
a01,
|
|
72
|
+
a02,
|
|
73
|
+
a10,
|
|
74
|
+
a11,
|
|
75
|
+
a12,
|
|
76
|
+
a20,
|
|
77
|
+
a21,
|
|
78
|
+
a22,
|
|
49
79
|
)
|
|
50
80
|
|
|
51
81
|
def translate(self, translation: Vec2, /) -> Self:
|
|
52
|
-
"""Translate along the x and y axes.
|
|
82
|
+
"""Translate along the x and y axes and return a new transform.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
translation: The translation vector.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
A new transform after translation.
|
|
89
|
+
"""
|
|
53
90
|
return self._compose(
|
|
54
|
-
1,
|
|
55
|
-
0,
|
|
56
|
-
|
|
91
|
+
1,
|
|
92
|
+
0,
|
|
93
|
+
translation.x,
|
|
94
|
+
0,
|
|
95
|
+
1,
|
|
96
|
+
translation.y,
|
|
97
|
+
0,
|
|
98
|
+
0,
|
|
99
|
+
1,
|
|
57
100
|
)
|
|
58
101
|
|
|
59
102
|
def scale(self, factor: Vec2, /) -> Self:
|
|
60
|
-
"""Scale
|
|
103
|
+
"""Scale about the origin and return a new transform.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
factor: The scale factor vector.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
A new transform after scaling.
|
|
110
|
+
"""
|
|
61
111
|
return self._compose(
|
|
62
|
-
factor.x,
|
|
63
|
-
0,
|
|
64
|
-
0,
|
|
112
|
+
factor.x,
|
|
113
|
+
0,
|
|
114
|
+
0,
|
|
115
|
+
0,
|
|
116
|
+
factor.y,
|
|
117
|
+
0,
|
|
118
|
+
0,
|
|
119
|
+
0,
|
|
120
|
+
1,
|
|
65
121
|
)
|
|
66
122
|
|
|
67
123
|
def scale_about(self, factor: Vec2, /, pivot: Vec2) -> Self:
|
|
68
|
-
"""Scale
|
|
124
|
+
"""Scale about the pivot and return a new transform.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
factor: The scale factor vector.
|
|
128
|
+
pivot: The pivot point for scaling.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
A new transform after scaling.
|
|
132
|
+
"""
|
|
69
133
|
return self.translate(-pivot).scale(factor).translate(pivot)
|
|
70
134
|
|
|
71
135
|
def rotate(self, angle: float, /) -> Self:
|
|
72
|
-
"""Rotate
|
|
136
|
+
"""Rotate about the origin and return a new transform.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
angle: The angle of rotation in radians.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
A new transform after rotation.
|
|
143
|
+
"""
|
|
73
144
|
c = cos(angle)
|
|
74
145
|
s = sin(angle)
|
|
75
146
|
return self._compose(
|
|
76
|
-
c,
|
|
77
|
-
s,
|
|
78
|
-
0,
|
|
147
|
+
c,
|
|
148
|
+
-s,
|
|
149
|
+
0,
|
|
150
|
+
s,
|
|
151
|
+
c,
|
|
152
|
+
0,
|
|
153
|
+
0,
|
|
154
|
+
0,
|
|
155
|
+
1,
|
|
79
156
|
)
|
|
80
157
|
|
|
81
158
|
def rotate_about(self, angle: float, /, pivot: Vec2) -> Self:
|
|
82
|
-
"""Rotate
|
|
159
|
+
"""Rotate about the pivot and return a new transform.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
angle: The angle of rotation in radians.
|
|
163
|
+
pivot: The pivot point for rotation.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
A new transform after rotation.
|
|
167
|
+
"""
|
|
83
168
|
return self.translate(-pivot).rotate(angle).translate(pivot)
|
|
84
169
|
|
|
85
170
|
def shear_x(self, m: float, /) -> Self:
|
|
86
|
-
"""Shear along the x-axis.
|
|
171
|
+
"""Shear along the x-axis and return a new transform.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
m: The shear factor along the x-axis.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
A new transform after shearing.
|
|
178
|
+
"""
|
|
87
179
|
return self._compose(
|
|
88
|
-
1,
|
|
89
|
-
|
|
90
|
-
0,
|
|
180
|
+
1,
|
|
181
|
+
m,
|
|
182
|
+
0,
|
|
183
|
+
0,
|
|
184
|
+
1,
|
|
185
|
+
0,
|
|
186
|
+
0,
|
|
187
|
+
0,
|
|
188
|
+
1,
|
|
91
189
|
)
|
|
92
190
|
|
|
93
191
|
def shear_y(self, m: float, /) -> Self:
|
|
94
|
-
"""Shear along the y-axis.
|
|
192
|
+
"""Shear along the y-axis and return a new transform.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
m: The shear factor along the y-axis.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
A new transform after shearing.
|
|
199
|
+
"""
|
|
95
200
|
return self._compose(
|
|
96
|
-
1,
|
|
97
|
-
|
|
98
|
-
0,
|
|
201
|
+
1,
|
|
202
|
+
0,
|
|
203
|
+
0,
|
|
204
|
+
m,
|
|
205
|
+
1,
|
|
206
|
+
0,
|
|
207
|
+
0,
|
|
208
|
+
0,
|
|
209
|
+
1,
|
|
99
210
|
)
|
|
100
211
|
|
|
101
|
-
def
|
|
102
|
-
"""Apply perspective
|
|
212
|
+
def simple_perspective_x(self, x: float, /) -> Self:
|
|
213
|
+
"""Apply perspective along the x-axis with vanishing point at the given x coordinate and return a new transform.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
x: The x coordinate of the vanishing point.
|
|
103
217
|
|
|
104
|
-
|
|
218
|
+
Returns:
|
|
219
|
+
A new transform after applying perspective.
|
|
105
220
|
"""
|
|
106
221
|
return self._compose(
|
|
107
|
-
1,
|
|
108
|
-
0,
|
|
109
|
-
0,
|
|
222
|
+
1,
|
|
223
|
+
0,
|
|
224
|
+
0,
|
|
225
|
+
0,
|
|
226
|
+
1,
|
|
227
|
+
0,
|
|
228
|
+
1 / x,
|
|
229
|
+
0,
|
|
230
|
+
1,
|
|
110
231
|
)
|
|
111
232
|
|
|
112
|
-
def
|
|
113
|
-
"""Apply a
|
|
233
|
+
def simple_perspective_y(self, y: float, /) -> Self:
|
|
234
|
+
"""Apply perspective along the y-axis with vanishing point at the given y coordinate and return a new transform.
|
|
114
235
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
236
|
+
Args:
|
|
237
|
+
y: The y coordinate of the vanishing point.
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
A new transform after applying perspective.
|
|
241
|
+
"""
|
|
242
|
+
return self._compose(
|
|
243
|
+
1,
|
|
244
|
+
0,
|
|
245
|
+
0,
|
|
246
|
+
0,
|
|
247
|
+
1,
|
|
248
|
+
0,
|
|
249
|
+
0,
|
|
250
|
+
1 / y,
|
|
251
|
+
1,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
def perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) -> Self:
|
|
255
|
+
"""Apply a perspective transformation along the x-axis and return a new transform.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
foreground_x: The foreground x-coordinate.
|
|
259
|
+
vanishing_point: The vanishing point vector.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
A new transform after applying perspective.
|
|
263
|
+
"""
|
|
264
|
+
return (
|
|
265
|
+
self.simple_perspective_x(vanishing_point.x - foreground_x)
|
|
266
|
+
.shear_y(vanishing_point.y / (vanishing_point.x - foreground_x))
|
|
267
|
+
.translate(Vec2(foreground_x, 0))
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
def perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) -> Self:
|
|
271
|
+
"""Apply a perspective transformation along the y-axis and return a new transform.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
foreground_y: The foreground y-coordinate.
|
|
275
|
+
vanishing_point: The vanishing point vector.
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
A new transform after applying perspective.
|
|
119
279
|
"""
|
|
120
280
|
return (
|
|
121
|
-
self
|
|
122
|
-
.perspective_vanish_y(vanishing_point.y - foreground_y)
|
|
281
|
+
self.simple_perspective_y(vanishing_point.y - foreground_y)
|
|
123
282
|
.shear_x(vanishing_point.x / (vanishing_point.y - foreground_y))
|
|
124
283
|
.translate(Vec2(0, foreground_y))
|
|
125
284
|
)
|
|
126
285
|
|
|
127
|
-
def
|
|
128
|
-
"""Apply the inverse of a perspective transformation.
|
|
286
|
+
def inverse_perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) -> Self:
|
|
287
|
+
"""Apply the inverse of a perspective transformation along the x-axis and return a new transform.
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
foreground_x: The foreground x-coordinate.
|
|
291
|
+
vanishing_point: The vanishing point vector.
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
A new transform after applying the inverse perspective.
|
|
295
|
+
"""
|
|
296
|
+
return (
|
|
297
|
+
self.translate(Vec2(-foreground_x, 0))
|
|
298
|
+
.shear_y(-vanishing_point.y / (vanishing_point.x - foreground_x))
|
|
299
|
+
.simple_perspective_x(-vanishing_point.x + foreground_x)
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
def inverse_perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) -> Self:
|
|
303
|
+
"""Apply the inverse of a perspective transformation along the y-axis and return a new transform.
|
|
304
|
+
|
|
305
|
+
Args:
|
|
306
|
+
foreground_y: The foreground y-coordinate.
|
|
307
|
+
vanishing_point: The vanishing point vector.
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
A new transform after applying the inverse perspective.
|
|
311
|
+
"""
|
|
129
312
|
return (
|
|
130
|
-
self
|
|
131
|
-
.translate(Vec2(0, -foreground_y))
|
|
313
|
+
self.translate(Vec2(0, -foreground_y))
|
|
132
314
|
.shear_x(-vanishing_point.x / (vanishing_point.y - foreground_y))
|
|
133
|
-
.
|
|
315
|
+
.simple_perspective_y(-vanishing_point.y + foreground_y)
|
|
134
316
|
)
|
|
135
317
|
|
|
136
|
-
def normalize(self):
|
|
137
|
-
"""Normalize the transform to have a 1 in the bottom right corner.
|
|
318
|
+
def normalize(self) -> Self:
|
|
319
|
+
"""Normalize the transform to have a 1 in the bottom right corner and return a new transform.
|
|
320
|
+
|
|
321
|
+
This may fail in some special cases involving perspective transformations where the bottom right corner is 0.
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
A new normalized transform.
|
|
325
|
+
"""
|
|
138
326
|
return Transform2d(
|
|
139
|
-
self.a00 / self.a22,
|
|
140
|
-
self.
|
|
141
|
-
self.
|
|
327
|
+
self.a00 / self.a22,
|
|
328
|
+
self.a01 / self.a22,
|
|
329
|
+
self.a02 / self.a22,
|
|
330
|
+
self.a10 / self.a22,
|
|
331
|
+
self.a11 / self.a22,
|
|
332
|
+
self.a12 / self.a22,
|
|
333
|
+
self.a20 / self.a22,
|
|
334
|
+
self.a21 / self.a22,
|
|
335
|
+
1,
|
|
142
336
|
)
|
|
143
337
|
|
|
144
338
|
def compose(self, other: Self, /) -> Self:
|
|
145
|
-
"""Compose with another transform which is applied after this transform.
|
|
339
|
+
"""Compose with another transform which is applied after this transform and return a new transform.
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
other: The other transform to compose with.
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
A new transform resulting from the composition.
|
|
346
|
+
"""
|
|
146
347
|
return self._compose(
|
|
147
|
-
other.a00,
|
|
148
|
-
other.
|
|
149
|
-
other.
|
|
348
|
+
other.a00,
|
|
349
|
+
other.a01,
|
|
350
|
+
other.a02,
|
|
351
|
+
other.a10,
|
|
352
|
+
other.a11,
|
|
353
|
+
other.a12,
|
|
354
|
+
other.a20,
|
|
355
|
+
other.a21,
|
|
356
|
+
other.a22,
|
|
150
357
|
)
|
|
151
358
|
|
|
152
359
|
def compose_before(self, other: Self, /) -> Self:
|
|
153
|
-
"""Compose with another transform which is applied before this transform.
|
|
360
|
+
"""Compose with another transform which is applied before this transform and return a new transform.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
other: The other transform to compose with.
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
A new transform resulting from the composition.
|
|
367
|
+
"""
|
|
154
368
|
return other.compose(self)
|
|
155
369
|
|
|
156
370
|
def transform_vec(self, v: Vec2) -> Vec2:
|
|
371
|
+
"""Transform a Vec2 and return a new Vec2.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
v: The vector to transform.
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
A new transformed vector.
|
|
378
|
+
"""
|
|
157
379
|
x = self.a00 * v.x + self.a01 * v.y + self.a02
|
|
158
380
|
y = self.a10 * v.x + self.a11 * v.y + self.a12
|
|
159
381
|
w = self.a20 * v.x + self.a21 * v.y + self.a22
|
|
160
382
|
return Vec2(x / w, y / w)
|
|
161
383
|
|
|
162
384
|
def transform_quad(self, quad: QuadLike) -> Quad:
|
|
385
|
+
"""Transform a Quad and return a new Quad.
|
|
386
|
+
|
|
387
|
+
Args:
|
|
388
|
+
quad: The quad to transform.
|
|
389
|
+
|
|
390
|
+
Returns:
|
|
391
|
+
A new transformed quad.
|
|
392
|
+
"""
|
|
163
393
|
return Quad(
|
|
164
394
|
bl=self.transform_vec(quad.bl),
|
|
165
395
|
br=self.transform_vec(quad.br),
|