sonolus.py 0.3.4__py3-none-any.whl → 0.4.1__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/excepthook.py +30 -0
- sonolus/backend/finalize.py +15 -1
- sonolus/backend/ops.py +4 -0
- sonolus/backend/optimize/allocate.py +5 -5
- sonolus/backend/optimize/constant_evaluation.py +124 -19
- sonolus/backend/optimize/copy_coalesce.py +15 -12
- sonolus/backend/optimize/dead_code.py +7 -6
- sonolus/backend/optimize/dominance.py +2 -2
- sonolus/backend/optimize/flow.py +54 -8
- sonolus/backend/optimize/inlining.py +137 -30
- sonolus/backend/optimize/liveness.py +2 -2
- sonolus/backend/optimize/optimize.py +15 -1
- sonolus/backend/optimize/passes.py +11 -3
- sonolus/backend/optimize/simplify.py +137 -8
- sonolus/backend/optimize/ssa.py +47 -13
- sonolus/backend/place.py +5 -4
- sonolus/backend/utils.py +44 -16
- sonolus/backend/visitor.py +288 -17
- sonolus/build/cli.py +47 -19
- sonolus/build/compile.py +12 -5
- sonolus/build/engine.py +70 -1
- sonolus/build/level.py +3 -3
- sonolus/build/project.py +2 -2
- sonolus/script/archetype.py +12 -9
- sonolus/script/array.py +23 -18
- sonolus/script/array_like.py +26 -29
- sonolus/script/bucket.py +1 -1
- sonolus/script/containers.py +22 -26
- sonolus/script/debug.py +20 -43
- sonolus/script/effect.py +1 -1
- sonolus/script/globals.py +3 -3
- sonolus/script/instruction.py +2 -2
- sonolus/script/internal/builtin_impls.py +155 -28
- sonolus/script/internal/constant.py +13 -3
- sonolus/script/internal/context.py +46 -15
- sonolus/script/internal/impl.py +9 -3
- sonolus/script/internal/introspection.py +8 -1
- sonolus/script/internal/native.py +2 -2
- sonolus/script/internal/range.py +8 -11
- sonolus/script/internal/simulation_context.py +1 -1
- sonolus/script/internal/transient.py +2 -2
- sonolus/script/internal/value.py +41 -3
- sonolus/script/interval.py +13 -13
- sonolus/script/iterator.py +53 -107
- sonolus/script/level.py +2 -2
- sonolus/script/maybe.py +241 -0
- sonolus/script/num.py +29 -14
- sonolus/script/options.py +1 -1
- sonolus/script/particle.py +1 -1
- sonolus/script/project.py +24 -5
- sonolus/script/quad.py +15 -15
- sonolus/script/record.py +48 -44
- sonolus/script/runtime.py +22 -18
- sonolus/script/sprite.py +1 -1
- sonolus/script/stream.py +66 -82
- sonolus/script/transform.py +35 -34
- sonolus/script/values.py +10 -10
- sonolus/script/vec.py +21 -18
- {sonolus_py-0.3.4.dist-info → sonolus_py-0.4.1.dist-info}/METADATA +1 -1
- sonolus_py-0.4.1.dist-info/RECORD +93 -0
- sonolus_py-0.3.4.dist-info/RECORD +0 -92
- {sonolus_py-0.3.4.dist-info → sonolus_py-0.4.1.dist-info}/WHEEL +0 -0
- {sonolus_py-0.3.4.dist-info → sonolus_py-0.4.1.dist-info}/entry_points.txt +0 -0
- {sonolus_py-0.3.4.dist-info → sonolus_py-0.4.1.dist-info}/licenses/LICENSE +0 -0
sonolus/script/stream.py
CHANGED
|
@@ -13,6 +13,7 @@ from sonolus.script.internal.introspection import get_field_specifiers
|
|
|
13
13
|
from sonolus.script.internal.native import native_function
|
|
14
14
|
from sonolus.script.internal.value import BackingValue, Value
|
|
15
15
|
from sonolus.script.iterator import SonolusIterator
|
|
16
|
+
from sonolus.script.maybe import Maybe, Nothing, Some
|
|
16
17
|
from sonolus.script.num import Num
|
|
17
18
|
from sonolus.script.record import Record
|
|
18
19
|
from sonolus.script.runtime import prev_time, time
|
|
@@ -48,7 +49,7 @@ class _StreamDataField(SonolusDescriptor):
|
|
|
48
49
|
|
|
49
50
|
def __get__(self, instance, owner):
|
|
50
51
|
_check_can_read_or_write_stream()
|
|
51
|
-
return self._get().
|
|
52
|
+
return self._get()._get_readonly_()
|
|
52
53
|
|
|
53
54
|
def __set__(self, instance, value):
|
|
54
55
|
_check_can_write_stream()
|
|
@@ -136,7 +137,7 @@ class _StreamBacking(BackingValue):
|
|
|
136
137
|
id: Num
|
|
137
138
|
index: Num
|
|
138
139
|
|
|
139
|
-
def __init__(self, stream_id: int, index: Num):
|
|
140
|
+
def __init__(self, stream_id: int, index: Num | int | float):
|
|
140
141
|
super().__init__()
|
|
141
142
|
self.id = Num._accept_(stream_id)
|
|
142
143
|
self.index = Num._accept_(index)
|
|
@@ -240,10 +241,10 @@ class Stream[T](Record):
|
|
|
240
241
|
# We still need to store something to preserve the key, so this is a special case.
|
|
241
242
|
_stream_set(self.offset, key, 0)
|
|
242
243
|
else:
|
|
243
|
-
for i, v in enumerate(value._to_list_()):
|
|
244
|
+
for i, v in enumerate(cast(Value, value)._to_list_()):
|
|
244
245
|
_stream_set(self.offset + i, key, Num(v))
|
|
245
246
|
|
|
246
|
-
def next_key(self, key: int | float) -> int:
|
|
247
|
+
def next_key(self, key: int | float) -> int | float:
|
|
247
248
|
"""Get the next key, or the key unchanged if it is the last key or the stream is empty.
|
|
248
249
|
|
|
249
250
|
If the key is in the stream and there is a next key, returns the next key.
|
|
@@ -251,13 +252,13 @@ class Stream[T](Record):
|
|
|
251
252
|
_check_can_read_stream()
|
|
252
253
|
return _stream_get_next_key(self.offset, key)
|
|
253
254
|
|
|
254
|
-
def next_key_or_default(self, key: int | float, default: int | float) -> int:
|
|
255
|
+
def next_key_or_default(self, key: int | float, default: int | float) -> int | float:
|
|
255
256
|
"""Get the next key, or the default value if there is no next key."""
|
|
256
257
|
_check_can_read_stream()
|
|
257
258
|
next_key = self.next_key(key)
|
|
258
259
|
return next_key if next_key > key else default
|
|
259
260
|
|
|
260
|
-
def previous_key(self, key: int | float) -> int:
|
|
261
|
+
def previous_key(self, key: int | float) -> int | float:
|
|
261
262
|
"""Get the previous key, or the key unchanged if it is the first key or the stream is empty.
|
|
262
263
|
|
|
263
264
|
If the key is in the stream and there is a previous key, returns the previous key.
|
|
@@ -265,7 +266,7 @@ class Stream[T](Record):
|
|
|
265
266
|
_check_can_read_stream()
|
|
266
267
|
return _stream_get_previous_key(self.offset, key)
|
|
267
268
|
|
|
268
|
-
def previous_key_or_default(self, key: int | float, default: int | float) -> int:
|
|
269
|
+
def previous_key_or_default(self, key: int | float, default: int | float) -> int | float:
|
|
269
270
|
"""Get the previous key, or the default value if there is no previous key."""
|
|
270
271
|
_check_can_read_stream()
|
|
271
272
|
previous_key = self.previous_key(key)
|
|
@@ -283,12 +284,12 @@ class Stream[T](Record):
|
|
|
283
284
|
previous_key = self.previous_key(key)
|
|
284
285
|
return previous_key < key
|
|
285
286
|
|
|
286
|
-
def next_key_inclusive(self, key: int | float) -> int:
|
|
287
|
+
def next_key_inclusive(self, key: int | float) -> int | float:
|
|
287
288
|
"""Like `next_key`, but returns the key itself if it is in the stream."""
|
|
288
289
|
_check_can_read_stream()
|
|
289
290
|
return key if key in self else self.next_key(key)
|
|
290
291
|
|
|
291
|
-
def previous_key_inclusive(self, key: int | float) -> int:
|
|
292
|
+
def previous_key_inclusive(self, key: int | float) -> int | float:
|
|
292
293
|
"""Like `previous_key`, but returns the key itself if it is in the stream."""
|
|
293
294
|
_check_can_read_stream()
|
|
294
295
|
return key if key in self else self.previous_key(key)
|
|
@@ -508,21 +509,20 @@ class StreamGroup[T, Size](Record):
|
|
|
508
509
|
_check_can_read_or_write_stream()
|
|
509
510
|
assert index in self
|
|
510
511
|
# Size 0 elements still need 1 stream to preserve the key.
|
|
511
|
-
|
|
512
|
+
t = self.type_var_value(T)
|
|
513
|
+
return Stream[t](max(1, sizeof(self.element_type())) * index + self.offset)
|
|
512
514
|
|
|
513
515
|
|
|
514
516
|
class _StreamAscIterator[T](Record, SonolusIterator[tuple[int | float, T]]):
|
|
515
517
|
stream: Stream[T]
|
|
516
518
|
current_key: int | float
|
|
517
519
|
|
|
518
|
-
def
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
def advance(self):
|
|
525
|
-
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
520
|
+
def next(self) -> Maybe[tuple[int | float, T]]:
|
|
521
|
+
if self.current_key in self.stream:
|
|
522
|
+
result = (self.current_key, self.stream[self.current_key])
|
|
523
|
+
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
524
|
+
return Some(result)
|
|
525
|
+
return Nothing
|
|
526
526
|
|
|
527
527
|
|
|
528
528
|
class _StreamBoundedAscIterator[T](Record, SonolusIterator[tuple[int | float, T]]):
|
|
@@ -530,42 +530,36 @@ class _StreamBoundedAscIterator[T](Record, SonolusIterator[tuple[int | float, T]
|
|
|
530
530
|
current_key: int | float
|
|
531
531
|
end_key: int | float
|
|
532
532
|
|
|
533
|
-
def
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
def advance(self):
|
|
540
|
-
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
533
|
+
def next(self) -> Maybe[tuple[int | float, T]]:
|
|
534
|
+
if self.current_key in self.stream and self.current_key <= self.end_key:
|
|
535
|
+
result = (self.current_key, self.stream[self.current_key])
|
|
536
|
+
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
537
|
+
return Some(result)
|
|
538
|
+
return Nothing
|
|
541
539
|
|
|
542
540
|
|
|
543
541
|
class _StreamDescIterator[T](Record, SonolusIterator[tuple[int | float, T]]):
|
|
544
542
|
stream: Stream[T]
|
|
545
543
|
current_key: int | float
|
|
546
544
|
|
|
547
|
-
def
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
def advance(self):
|
|
554
|
-
self.current_key = self.stream.previous_key_or_default(self.current_key, -inf)
|
|
545
|
+
def next(self) -> Maybe[tuple[int | float, T]]:
|
|
546
|
+
if self.current_key in self.stream:
|
|
547
|
+
result = (self.current_key, self.stream[self.current_key])
|
|
548
|
+
self.current_key = self.stream.previous_key_or_default(self.current_key, -inf)
|
|
549
|
+
return Some(result)
|
|
550
|
+
return Nothing
|
|
555
551
|
|
|
556
552
|
|
|
557
553
|
class _StreamAscKeyIterator[T](Record, SonolusIterator[int | float]):
|
|
558
554
|
stream: Stream[T]
|
|
559
555
|
current_key: int | float
|
|
560
556
|
|
|
561
|
-
def
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
def advance(self):
|
|
568
|
-
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
557
|
+
def next(self) -> Maybe[int | float]:
|
|
558
|
+
if self.current_key in self.stream:
|
|
559
|
+
result = self.current_key
|
|
560
|
+
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
561
|
+
return Some(result)
|
|
562
|
+
return Nothing
|
|
569
563
|
|
|
570
564
|
|
|
571
565
|
class _StreamBoundedAscKeyIterator[T](Record, SonolusIterator[int | float]):
|
|
@@ -573,42 +567,36 @@ class _StreamBoundedAscKeyIterator[T](Record, SonolusIterator[int | float]):
|
|
|
573
567
|
current_key: int | float
|
|
574
568
|
end_key: int | float
|
|
575
569
|
|
|
576
|
-
def
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
def advance(self):
|
|
583
|
-
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
570
|
+
def next(self) -> Maybe[int | float]:
|
|
571
|
+
if self.current_key in self.stream and self.current_key <= self.end_key:
|
|
572
|
+
result = self.current_key
|
|
573
|
+
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
574
|
+
return Some(result)
|
|
575
|
+
return Nothing
|
|
584
576
|
|
|
585
577
|
|
|
586
578
|
class _StreamDescKeyIterator[T](Record, SonolusIterator[int | float]):
|
|
587
579
|
stream: Stream[T]
|
|
588
580
|
current_key: int | float
|
|
589
581
|
|
|
590
|
-
def
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
def advance(self):
|
|
597
|
-
self.current_key = self.stream.previous_key_or_default(self.current_key, -inf)
|
|
582
|
+
def next(self) -> Maybe[int | float]:
|
|
583
|
+
if self.current_key in self.stream:
|
|
584
|
+
result = self.current_key
|
|
585
|
+
self.current_key = self.stream.previous_key_or_default(self.current_key, -inf)
|
|
586
|
+
return Some(result)
|
|
587
|
+
return Nothing
|
|
598
588
|
|
|
599
589
|
|
|
600
590
|
class _StreamAscValueIterator[T](Record, SonolusIterator[T]):
|
|
601
591
|
stream: Stream[T]
|
|
602
592
|
current_key: int | float
|
|
603
593
|
|
|
604
|
-
def
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
def advance(self):
|
|
611
|
-
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
594
|
+
def next(self) -> Maybe[T]:
|
|
595
|
+
if self.current_key in self.stream:
|
|
596
|
+
result = self.stream[self.current_key]
|
|
597
|
+
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
598
|
+
return Some(result)
|
|
599
|
+
return Nothing
|
|
612
600
|
|
|
613
601
|
|
|
614
602
|
class _StreamBoundedAscValueIterator[T](Record, SonolusIterator[T]):
|
|
@@ -616,28 +604,24 @@ class _StreamBoundedAscValueIterator[T](Record, SonolusIterator[T]):
|
|
|
616
604
|
current_key: int | float
|
|
617
605
|
end_key: int | float
|
|
618
606
|
|
|
619
|
-
def
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
def advance(self):
|
|
626
|
-
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
607
|
+
def next(self) -> Maybe[T]:
|
|
608
|
+
if self.current_key in self.stream and self.current_key <= self.end_key:
|
|
609
|
+
result = self.stream[self.current_key]
|
|
610
|
+
self.current_key = self.stream.next_key_or_default(self.current_key, inf)
|
|
611
|
+
return Some(result)
|
|
612
|
+
return Nothing
|
|
627
613
|
|
|
628
614
|
|
|
629
615
|
class _StreamDescValueIterator[T](Record, SonolusIterator[T]):
|
|
630
616
|
stream: Stream[T]
|
|
631
617
|
current_key: int | float
|
|
632
618
|
|
|
633
|
-
def
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
def advance(self):
|
|
640
|
-
self.current_key = self.stream.previous_key_or_default(self.current_key, -inf)
|
|
619
|
+
def next(self) -> Maybe[T]:
|
|
620
|
+
if self.current_key in self.stream:
|
|
621
|
+
result = self.stream[self.current_key]
|
|
622
|
+
self.current_key = self.stream.previous_key_or_default(self.current_key, -inf)
|
|
623
|
+
return Some(result)
|
|
624
|
+
return Nothing
|
|
641
625
|
|
|
642
626
|
|
|
643
627
|
@native_function(Op.StreamGetNextKey)
|
sonolus/script/transform.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from math import cos, sin
|
|
2
|
-
from typing import Self
|
|
3
4
|
|
|
4
5
|
from sonolus.script.interval import lerp, remap
|
|
5
6
|
from sonolus.script.quad import Quad, QuadLike
|
|
@@ -27,7 +28,7 @@ class Transform2d(Record):
|
|
|
27
28
|
a22: float
|
|
28
29
|
|
|
29
30
|
@classmethod
|
|
30
|
-
def new(cls) ->
|
|
31
|
+
def new(cls) -> Transform2d:
|
|
31
32
|
"""Create a new identity transform.
|
|
32
33
|
|
|
33
34
|
Returns:
|
|
@@ -56,7 +57,7 @@ class Transform2d(Record):
|
|
|
56
57
|
b20: float,
|
|
57
58
|
b21: float,
|
|
58
59
|
b22: float,
|
|
59
|
-
) ->
|
|
60
|
+
) -> Transform2d:
|
|
60
61
|
# Multiply by b on the left (b @ a)
|
|
61
62
|
a00 = self.a00 * b00 + self.a10 * b01 + self.a20 * b02
|
|
62
63
|
a01 = self.a01 * b00 + self.a11 * b01 + self.a21 * b02
|
|
@@ -79,7 +80,7 @@ class Transform2d(Record):
|
|
|
79
80
|
a22,
|
|
80
81
|
)
|
|
81
82
|
|
|
82
|
-
def translate(self, translation: Vec2, /) ->
|
|
83
|
+
def translate(self, translation: Vec2, /) -> Transform2d:
|
|
83
84
|
"""Translate along the x and y axes and return a new transform.
|
|
84
85
|
|
|
85
86
|
Args:
|
|
@@ -100,7 +101,7 @@ class Transform2d(Record):
|
|
|
100
101
|
1,
|
|
101
102
|
)
|
|
102
103
|
|
|
103
|
-
def scale(self, factor: Vec2, /) ->
|
|
104
|
+
def scale(self, factor: Vec2, /) -> Transform2d:
|
|
104
105
|
"""Scale about the origin and return a new transform.
|
|
105
106
|
|
|
106
107
|
Args:
|
|
@@ -121,7 +122,7 @@ class Transform2d(Record):
|
|
|
121
122
|
1,
|
|
122
123
|
)
|
|
123
124
|
|
|
124
|
-
def scale_about(self, factor: Vec2, /, pivot: Vec2) ->
|
|
125
|
+
def scale_about(self, factor: Vec2, /, pivot: Vec2) -> Transform2d:
|
|
125
126
|
"""Scale about the pivot and return a new transform.
|
|
126
127
|
|
|
127
128
|
Args:
|
|
@@ -133,7 +134,7 @@ class Transform2d(Record):
|
|
|
133
134
|
"""
|
|
134
135
|
return self.translate(-pivot).scale(factor).translate(pivot)
|
|
135
136
|
|
|
136
|
-
def rotate(self, angle: float, /) ->
|
|
137
|
+
def rotate(self, angle: float, /) -> Transform2d:
|
|
137
138
|
"""Rotate about the origin and return a new transform.
|
|
138
139
|
|
|
139
140
|
Args:
|
|
@@ -156,7 +157,7 @@ class Transform2d(Record):
|
|
|
156
157
|
1,
|
|
157
158
|
)
|
|
158
159
|
|
|
159
|
-
def rotate_about(self, angle: float, /, pivot: Vec2) ->
|
|
160
|
+
def rotate_about(self, angle: float, /, pivot: Vec2) -> Transform2d:
|
|
160
161
|
"""Rotate about the pivot and return a new transform.
|
|
161
162
|
|
|
162
163
|
Args:
|
|
@@ -168,7 +169,7 @@ class Transform2d(Record):
|
|
|
168
169
|
"""
|
|
169
170
|
return self.translate(-pivot).rotate(angle).translate(pivot)
|
|
170
171
|
|
|
171
|
-
def shear_x(self, m: float, /) ->
|
|
172
|
+
def shear_x(self, m: float, /) -> Transform2d:
|
|
172
173
|
"""Shear along the x-axis and return a new transform.
|
|
173
174
|
|
|
174
175
|
Args:
|
|
@@ -189,7 +190,7 @@ class Transform2d(Record):
|
|
|
189
190
|
1,
|
|
190
191
|
)
|
|
191
192
|
|
|
192
|
-
def shear_y(self, m: float, /) ->
|
|
193
|
+
def shear_y(self, m: float, /) -> Transform2d:
|
|
193
194
|
"""Shear along the y-axis and return a new transform.
|
|
194
195
|
|
|
195
196
|
Args:
|
|
@@ -210,7 +211,7 @@ class Transform2d(Record):
|
|
|
210
211
|
1,
|
|
211
212
|
)
|
|
212
213
|
|
|
213
|
-
def simple_perspective_x(self, x: float, /) ->
|
|
214
|
+
def simple_perspective_x(self, x: float, /) -> Transform2d:
|
|
214
215
|
"""Apply perspective along the x-axis with vanishing point at the given x coordinate and return a new transform.
|
|
215
216
|
|
|
216
217
|
Args:
|
|
@@ -231,7 +232,7 @@ class Transform2d(Record):
|
|
|
231
232
|
1,
|
|
232
233
|
)
|
|
233
234
|
|
|
234
|
-
def simple_perspective_y(self, y: float, /) ->
|
|
235
|
+
def simple_perspective_y(self, y: float, /) -> Transform2d:
|
|
235
236
|
"""Apply perspective along the y-axis with vanishing point at the given y coordinate and return a new transform.
|
|
236
237
|
|
|
237
238
|
Args:
|
|
@@ -252,7 +253,7 @@ class Transform2d(Record):
|
|
|
252
253
|
1,
|
|
253
254
|
)
|
|
254
255
|
|
|
255
|
-
def perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) ->
|
|
256
|
+
def perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) -> Transform2d:
|
|
256
257
|
"""Apply a perspective transformation along the x-axis and return a new transform.
|
|
257
258
|
|
|
258
259
|
Args:
|
|
@@ -268,7 +269,7 @@ class Transform2d(Record):
|
|
|
268
269
|
.translate(Vec2(foreground_x, 0))
|
|
269
270
|
)
|
|
270
271
|
|
|
271
|
-
def perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) ->
|
|
272
|
+
def perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) -> Transform2d:
|
|
272
273
|
"""Apply a perspective transformation along the y-axis and return a new transform.
|
|
273
274
|
|
|
274
275
|
Args:
|
|
@@ -284,7 +285,7 @@ class Transform2d(Record):
|
|
|
284
285
|
.translate(Vec2(0, foreground_y))
|
|
285
286
|
)
|
|
286
287
|
|
|
287
|
-
def inverse_perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) ->
|
|
288
|
+
def inverse_perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) -> Transform2d:
|
|
288
289
|
"""Apply the inverse of a perspective transformation along the x-axis and return a new transform.
|
|
289
290
|
|
|
290
291
|
Args:
|
|
@@ -300,7 +301,7 @@ class Transform2d(Record):
|
|
|
300
301
|
.simple_perspective_x(-vanishing_point.x + foreground_x)
|
|
301
302
|
)
|
|
302
303
|
|
|
303
|
-
def inverse_perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) ->
|
|
304
|
+
def inverse_perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) -> Transform2d:
|
|
304
305
|
"""Apply the inverse of a perspective transformation along the y-axis and return a new transform.
|
|
305
306
|
|
|
306
307
|
Args:
|
|
@@ -316,7 +317,7 @@ class Transform2d(Record):
|
|
|
316
317
|
.simple_perspective_y(-vanishing_point.y + foreground_y)
|
|
317
318
|
)
|
|
318
319
|
|
|
319
|
-
def normalize(self) ->
|
|
320
|
+
def normalize(self) -> Transform2d:
|
|
320
321
|
"""Normalize the transform to have a 1 in the bottom right corner and return a new transform.
|
|
321
322
|
|
|
322
323
|
This may fail in some special cases involving perspective transformations where the bottom right corner is 0.
|
|
@@ -336,7 +337,7 @@ class Transform2d(Record):
|
|
|
336
337
|
1,
|
|
337
338
|
)
|
|
338
339
|
|
|
339
|
-
def compose(self, other:
|
|
340
|
+
def compose(self, other: Transform2d, /) -> Transform2d:
|
|
340
341
|
"""Compose with another transform which is applied after this transform and return a new transform.
|
|
341
342
|
|
|
342
343
|
Args:
|
|
@@ -357,7 +358,7 @@ class Transform2d(Record):
|
|
|
357
358
|
other.a22,
|
|
358
359
|
)
|
|
359
360
|
|
|
360
|
-
def compose_before(self, other:
|
|
361
|
+
def compose_before(self, other: Transform2d, /) -> Transform2d:
|
|
361
362
|
"""Compose with another transform which is applied before this transform and return a new transform.
|
|
362
363
|
|
|
363
364
|
Args:
|
|
@@ -412,7 +413,7 @@ class InvertibleTransform2d(Record):
|
|
|
412
413
|
inverse: Transform2d
|
|
413
414
|
|
|
414
415
|
@classmethod
|
|
415
|
-
def new(cls) ->
|
|
416
|
+
def new(cls) -> InvertibleTransform2d:
|
|
416
417
|
"""Create a new identity transform.
|
|
417
418
|
|
|
418
419
|
Returns:
|
|
@@ -423,7 +424,7 @@ class InvertibleTransform2d(Record):
|
|
|
423
424
|
inverse=Transform2d.new(),
|
|
424
425
|
)
|
|
425
426
|
|
|
426
|
-
def translate(self, translation: Vec2, /) ->
|
|
427
|
+
def translate(self, translation: Vec2, /) -> InvertibleTransform2d:
|
|
427
428
|
"""Translate along the x and y axes and return a new transform.
|
|
428
429
|
|
|
429
430
|
Args:
|
|
@@ -437,7 +438,7 @@ class InvertibleTransform2d(Record):
|
|
|
437
438
|
inverse=Transform2d.new().translate(-translation).compose(self.inverse),
|
|
438
439
|
)
|
|
439
440
|
|
|
440
|
-
def scale(self, factor: Vec2, /) ->
|
|
441
|
+
def scale(self, factor: Vec2, /) -> InvertibleTransform2d:
|
|
441
442
|
"""Scale about the origin and return a new transform.
|
|
442
443
|
|
|
443
444
|
Args:
|
|
@@ -451,7 +452,7 @@ class InvertibleTransform2d(Record):
|
|
|
451
452
|
inverse=Transform2d.new().scale(Vec2.one() / factor).compose(self.inverse),
|
|
452
453
|
)
|
|
453
454
|
|
|
454
|
-
def scale_about(self, factor: Vec2, /, pivot: Vec2) ->
|
|
455
|
+
def scale_about(self, factor: Vec2, /, pivot: Vec2) -> InvertibleTransform2d:
|
|
455
456
|
"""Scale about the pivot and return a new transform.
|
|
456
457
|
|
|
457
458
|
Args:
|
|
@@ -466,7 +467,7 @@ class InvertibleTransform2d(Record):
|
|
|
466
467
|
inverse=Transform2d.new().scale_about(Vec2.one() / factor, pivot).compose(self.inverse),
|
|
467
468
|
)
|
|
468
469
|
|
|
469
|
-
def rotate(self, angle: float, /) ->
|
|
470
|
+
def rotate(self, angle: float, /) -> InvertibleTransform2d:
|
|
470
471
|
"""Rotate about the origin and return a new transform.
|
|
471
472
|
|
|
472
473
|
Args:
|
|
@@ -480,7 +481,7 @@ class InvertibleTransform2d(Record):
|
|
|
480
481
|
inverse=Transform2d.new().rotate(-angle).compose(self.inverse),
|
|
481
482
|
)
|
|
482
483
|
|
|
483
|
-
def rotate_about(self, angle: float, /, pivot: Vec2) ->
|
|
484
|
+
def rotate_about(self, angle: float, /, pivot: Vec2) -> InvertibleTransform2d:
|
|
484
485
|
"""Rotate about the pivot and return a new transform.
|
|
485
486
|
|
|
486
487
|
Args:
|
|
@@ -495,7 +496,7 @@ class InvertibleTransform2d(Record):
|
|
|
495
496
|
inverse=Transform2d.new().rotate_about(-angle, pivot).compose(self.inverse),
|
|
496
497
|
)
|
|
497
498
|
|
|
498
|
-
def shear_x(self, m: float, /) ->
|
|
499
|
+
def shear_x(self, m: float, /) -> InvertibleTransform2d:
|
|
499
500
|
"""Shear along the x-axis and return a new transform.
|
|
500
501
|
|
|
501
502
|
Args:
|
|
@@ -509,7 +510,7 @@ class InvertibleTransform2d(Record):
|
|
|
509
510
|
inverse=Transform2d.new().shear_x(-m).compose(self.inverse),
|
|
510
511
|
)
|
|
511
512
|
|
|
512
|
-
def shear_y(self, m: float, /) ->
|
|
513
|
+
def shear_y(self, m: float, /) -> InvertibleTransform2d:
|
|
513
514
|
"""Shear along the y-axis and return a new transform.
|
|
514
515
|
|
|
515
516
|
Args:
|
|
@@ -523,7 +524,7 @@ class InvertibleTransform2d(Record):
|
|
|
523
524
|
inverse=Transform2d.new().shear_y(-m).compose(self.inverse),
|
|
524
525
|
)
|
|
525
526
|
|
|
526
|
-
def simple_perspective_x(self, x: float, /) ->
|
|
527
|
+
def simple_perspective_x(self, x: float, /) -> InvertibleTransform2d:
|
|
527
528
|
"""Apply perspective along the x-axis with vanishing point at the given x coordinate and return a new transform.
|
|
528
529
|
|
|
529
530
|
Args:
|
|
@@ -537,7 +538,7 @@ class InvertibleTransform2d(Record):
|
|
|
537
538
|
inverse=Transform2d.new().simple_perspective_x(-x).compose(self.inverse),
|
|
538
539
|
)
|
|
539
540
|
|
|
540
|
-
def simple_perspective_y(self, y: float, /) ->
|
|
541
|
+
def simple_perspective_y(self, y: float, /) -> InvertibleTransform2d:
|
|
541
542
|
"""Apply perspective along the y-axis with vanishing point at the given y coordinate and return a new transform.
|
|
542
543
|
|
|
543
544
|
Args:
|
|
@@ -551,7 +552,7 @@ class InvertibleTransform2d(Record):
|
|
|
551
552
|
inverse=Transform2d.new().simple_perspective_y(-y).compose(self.inverse),
|
|
552
553
|
)
|
|
553
554
|
|
|
554
|
-
def perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) ->
|
|
555
|
+
def perspective_x(self, foreground_x: float, vanishing_point: Vec2, /) -> InvertibleTransform2d:
|
|
555
556
|
"""Apply a perspective transformation along the x-axis and return a new transform.
|
|
556
557
|
|
|
557
558
|
Args:
|
|
@@ -566,7 +567,7 @@ class InvertibleTransform2d(Record):
|
|
|
566
567
|
inverse=Transform2d.new().inverse_perspective_x(foreground_x, vanishing_point).compose(self.inverse),
|
|
567
568
|
)
|
|
568
569
|
|
|
569
|
-
def perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) ->
|
|
570
|
+
def perspective_y(self, foreground_y: float, vanishing_point: Vec2, /) -> InvertibleTransform2d:
|
|
570
571
|
"""Apply a perspective transformation along the y-axis and return a new transform.
|
|
571
572
|
|
|
572
573
|
Args:
|
|
@@ -581,7 +582,7 @@ class InvertibleTransform2d(Record):
|
|
|
581
582
|
inverse=Transform2d.new().inverse_perspective_y(foreground_y, vanishing_point).compose(self.inverse),
|
|
582
583
|
)
|
|
583
584
|
|
|
584
|
-
def normalize(self) ->
|
|
585
|
+
def normalize(self) -> InvertibleTransform2d:
|
|
585
586
|
"""Normalize the transform to have a 1 in the bottom right corner and return a new transform.
|
|
586
587
|
|
|
587
588
|
This may fail in some special cases involving perspective transformations where the bottom right corner is 0.
|
|
@@ -594,7 +595,7 @@ class InvertibleTransform2d(Record):
|
|
|
594
595
|
inverse=self.inverse.normalize(),
|
|
595
596
|
)
|
|
596
597
|
|
|
597
|
-
def compose(self, other:
|
|
598
|
+
def compose(self, other: InvertibleTransform2d, /) -> InvertibleTransform2d:
|
|
598
599
|
"""Compose with another invertible transform which is applied after this transform and return a new transform.
|
|
599
600
|
|
|
600
601
|
Args:
|
|
@@ -608,7 +609,7 @@ class InvertibleTransform2d(Record):
|
|
|
608
609
|
inverse=other.inverse.compose(self.inverse),
|
|
609
610
|
)
|
|
610
611
|
|
|
611
|
-
def compose_before(self, other:
|
|
612
|
+
def compose_before(self, other: InvertibleTransform2d, /) -> InvertibleTransform2d:
|
|
612
613
|
"""Compose with another invertible transform which is applied before this transform and return a new transform.
|
|
613
614
|
|
|
614
615
|
Args:
|
sonolus/script/values.py
CHANGED
|
@@ -5,25 +5,25 @@ from sonolus.script.num import Num
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
@meta_fn
|
|
8
|
-
def alloc[T](type_: type[T]) -> T:
|
|
8
|
+
def alloc[T](type_: type[T]) -> T: # type: ignore
|
|
9
9
|
"""Return an uninitialized instance of the given type.
|
|
10
10
|
|
|
11
11
|
Use this carefully as reading from uninitialized memory can lead to unexpected behavior.
|
|
12
12
|
"""
|
|
13
13
|
type_ = validate_concrete_type(type_)
|
|
14
14
|
if ctx():
|
|
15
|
-
return type_._alloc_()
|
|
15
|
+
return type_._alloc_() # type: ignore
|
|
16
16
|
else:
|
|
17
|
-
return type_._alloc_()._as_py_()
|
|
17
|
+
return type_._alloc_()._as_py_() # type: ignore
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
@meta_fn
|
|
21
|
-
def zeros[T](type_: type[T]) -> T:
|
|
21
|
+
def zeros[T](type_: type[T]) -> T: # type: ignore
|
|
22
22
|
"""Make a new instance of the given type initialized with zeros.
|
|
23
23
|
|
|
24
24
|
Generally works the same as the unary `+` operator on record and array types.
|
|
25
25
|
"""
|
|
26
|
-
return validate_concrete_type(type_)._zero_()
|
|
26
|
+
return validate_concrete_type(type_)._zero_() # type: ignore
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
@meta_fn
|
|
@@ -32,18 +32,18 @@ def copy[T](value: T) -> T:
|
|
|
32
32
|
|
|
33
33
|
Generally works the same as the unary `+` operator on records and arrays.
|
|
34
34
|
"""
|
|
35
|
-
value = validate_value(value)
|
|
35
|
+
value = validate_value(value) # type: ignore
|
|
36
36
|
if ctx():
|
|
37
|
-
return value._copy_()
|
|
37
|
+
return value._copy_() # type: ignore
|
|
38
38
|
else:
|
|
39
|
-
return value._copy_()._as_py_()
|
|
39
|
+
return value._copy_()._as_py_() # type: ignore
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def swap[T](a: T, b: T):
|
|
43
43
|
"""Swap the values of the two provided mutable values."""
|
|
44
44
|
temp = copy(a)
|
|
45
|
-
a @= b
|
|
46
|
-
b @= temp
|
|
45
|
+
a @= b # type: ignore
|
|
46
|
+
b @= temp # type: ignore
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
@meta_fn
|