manim 0.17.0__py3-none-any.whl → 0.19.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.
- manim/__init__.py +11 -6
- manim/__main__.py +62 -19
- manim/_config/__init__.py +10 -9
- manim/_config/cli_colors.py +26 -9
- manim/_config/default.cfg +1 -3
- manim/_config/logger_utils.py +23 -13
- manim/_config/utils.py +662 -468
- manim/animation/animation.py +164 -18
- manim/animation/changing.py +34 -23
- manim/animation/composition.py +265 -67
- manim/animation/creation.py +208 -26
- manim/animation/fading.py +16 -18
- manim/animation/growing.py +35 -15
- manim/animation/indication.py +150 -76
- manim/animation/movement.py +56 -22
- manim/animation/numbers.py +64 -6
- manim/animation/rotation.py +78 -7
- manim/animation/specialized.py +6 -7
- manim/animation/speedmodifier.py +13 -10
- manim/animation/transform.py +14 -11
- manim/animation/transform_matching_parts.py +3 -4
- manim/animation/updaters/mobject_update_utils.py +152 -30
- manim/animation/updaters/update.py +10 -7
- manim/camera/camera.py +182 -118
- manim/camera/mapping_camera.py +34 -3
- manim/camera/moving_camera.py +95 -74
- manim/camera/multi_camera.py +23 -15
- manim/camera/three_d_camera.py +70 -52
- manim/cli/__init__.py +17 -0
- manim/cli/cfg/group.py +76 -44
- manim/cli/checkhealth/checks.py +192 -0
- manim/cli/checkhealth/commands.py +90 -0
- manim/cli/default_group.py +158 -25
- manim/cli/init/commands.py +33 -25
- manim/cli/plugins/commands.py +16 -3
- manim/cli/render/commands.py +72 -60
- manim/cli/render/ease_of_access_options.py +4 -3
- manim/cli/render/global_options.py +59 -17
- manim/cli/render/output_options.py +6 -5
- manim/cli/render/render_options.py +98 -33
- manim/constants.py +109 -59
- manim/data_structures.py +31 -0
- manim/mobject/frame.py +8 -5
- manim/mobject/geometry/__init__.py +1 -0
- manim/mobject/geometry/arc.py +277 -135
- manim/mobject/geometry/boolean_ops.py +32 -31
- manim/mobject/geometry/labeled.py +376 -0
- manim/mobject/geometry/line.py +192 -87
- manim/mobject/geometry/polygram.py +224 -58
- manim/mobject/geometry/shape_matchers.py +61 -25
- manim/mobject/geometry/tips.py +122 -48
- manim/mobject/graph.py +1027 -419
- manim/mobject/graphing/coordinate_systems.py +533 -278
- manim/mobject/graphing/functions.py +53 -32
- manim/mobject/graphing/number_line.py +123 -65
- manim/mobject/graphing/probability.py +88 -62
- manim/mobject/graphing/scale.py +33 -19
- manim/mobject/logo.py +118 -28
- manim/mobject/matrix.py +87 -83
- manim/mobject/mobject.py +912 -442
- manim/mobject/opengl/dot_cloud.py +16 -5
- manim/mobject/opengl/opengl_compatibility.py +4 -2
- manim/mobject/opengl/opengl_geometry.py +254 -153
- manim/mobject/opengl/opengl_image_mobject.py +3 -1
- manim/mobject/opengl/opengl_mobject.py +779 -482
- manim/mobject/opengl/opengl_point_cloud_mobject.py +41 -14
- manim/mobject/opengl/opengl_surface.py +14 -92
- manim/mobject/opengl/opengl_three_dimensions.py +12 -8
- manim/mobject/opengl/opengl_vectorized_mobject.py +98 -100
- manim/mobject/svg/brace.py +173 -41
- manim/mobject/svg/svg_mobject.py +139 -53
- manim/mobject/table.py +61 -68
- manim/mobject/text/code_mobject.py +193 -539
- manim/mobject/text/numbers.py +81 -34
- manim/mobject/text/tex_mobject.py +130 -78
- manim/mobject/text/text_mobject.py +288 -164
- manim/mobject/three_d/polyhedra.py +111 -13
- manim/mobject/three_d/three_d_utils.py +17 -8
- manim/mobject/three_d/three_dimensions.py +239 -106
- manim/mobject/types/image_mobject.py +50 -30
- manim/mobject/types/point_cloud_mobject.py +120 -75
- manim/mobject/types/vectorized_mobject.py +841 -408
- manim/mobject/value_tracker.py +105 -38
- manim/mobject/vector_field.py +50 -31
- manim/opengl/__init__.py +3 -3
- manim/plugins/__init__.py +14 -1
- manim/plugins/plugins_flags.py +10 -14
- manim/renderer/cairo_renderer.py +65 -50
- manim/renderer/opengl_renderer.py +89 -69
- manim/renderer/opengl_renderer_window.py +39 -18
- manim/renderer/shader.py +123 -87
- manim/renderer/shader_wrapper.py +44 -28
- manim/renderer/vectorized_mobject_rendering.py +38 -10
- manim/scene/moving_camera_scene.py +32 -3
- manim/scene/scene.py +507 -242
- manim/scene/scene_file_writer.py +371 -220
- manim/scene/section.py +20 -16
- manim/scene/three_d_scene.py +14 -22
- manim/scene/vector_space_scene.py +223 -129
- manim/scene/zoomed_scene.py +46 -41
- manim/typing.py +990 -0
- manim/utils/bezier.py +1823 -371
- manim/utils/caching.py +12 -5
- manim/utils/color/AS2700.py +236 -0
- manim/utils/color/BS381.py +318 -0
- manim/utils/color/DVIPSNAMES.py +96 -0
- manim/utils/color/SVGNAMES.py +179 -0
- manim/utils/color/X11.py +533 -0
- manim/utils/color/XKCD.py +952 -0
- manim/utils/color/__init__.py +61 -0
- manim/utils/color/core.py +1667 -0
- manim/utils/color/manim_colors.py +218 -0
- manim/utils/commands.py +48 -20
- manim/utils/config_ops.py +39 -19
- manim/utils/debug.py +8 -7
- manim/utils/deprecation.py +86 -39
- manim/utils/docbuild/__init__.py +17 -0
- manim/utils/docbuild/autoaliasattr_directive.py +236 -0
- manim/utils/docbuild/autocolor_directive.py +99 -0
- manim/utils/docbuild/manim_directive.py +94 -41
- manim/utils/docbuild/module_parsing.py +245 -0
- manim/utils/exceptions.py +6 -0
- manim/utils/family.py +5 -3
- manim/utils/family_ops.py +17 -4
- manim/utils/file_ops.py +27 -17
- manim/utils/hashing.py +55 -45
- manim/utils/images.py +13 -7
- manim/utils/ipython_magic.py +13 -7
- manim/utils/iterables.py +163 -120
- manim/utils/module_ops.py +66 -24
- manim/utils/opengl.py +77 -24
- manim/utils/parameter_parsing.py +32 -0
- manim/utils/paths.py +30 -33
- manim/utils/polylabel.py +235 -0
- manim/utils/qhull.py +218 -0
- manim/utils/rate_functions.py +98 -32
- manim/utils/simple_functions.py +25 -33
- manim/utils/sounds.py +7 -1
- manim/utils/space_ops.py +188 -115
- manim/utils/testing/__init__.py +17 -0
- manim/utils/testing/_frames_testers.py +13 -8
- manim/utils/testing/_show_diff.py +5 -3
- manim/utils/testing/_test_class_makers.py +34 -18
- manim/utils/testing/frames_comparison.py +37 -19
- manim/utils/tex.py +130 -198
- manim/utils/tex_file_writing.py +77 -47
- manim/utils/tex_templates.py +2 -1
- manim/utils/unit.py +6 -5
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/METADATA +64 -65
- manim-0.19.1.dist-info/RECORD +220 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/WHEEL +1 -1
- manim-0.19.1.dist-info/entry_points.txt +3 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE.community +1 -1
- manim/cli/new/group.py +0 -189
- manim/communitycolors.py +0 -9
- manim/gui/__init__.py +0 -0
- manim/gui/gui.py +0 -82
- manim/plugins/import_plugins.py +0 -43
- manim/utils/color.py +0 -552
- manim-0.17.0.dist-info/RECORD +0 -206
- manim-0.17.0.dist-info/entry_points.txt +0 -4
- /manim/cli/{new → checkhealth}/__init__.py +0 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE +0 -0
manim/renderer/shader_wrapper.py
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
|
+
import logging
|
|
4
5
|
import re
|
|
6
|
+
from collections.abc import Mapping, Sequence
|
|
5
7
|
from pathlib import Path
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
6
9
|
|
|
7
10
|
import moderngl
|
|
8
11
|
import numpy as np
|
|
12
|
+
import numpy.typing as npt
|
|
13
|
+
from typing_extensions import Self, TypeAlias
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from manim.typing import FloatRGBLike_Array
|
|
11
17
|
|
|
12
18
|
# Mobjects that should be rendered with
|
|
13
19
|
# the same shader will be organized and
|
|
@@ -15,6 +21,10 @@ from .. import logger
|
|
|
15
21
|
# of a dict holding all the relevant information
|
|
16
22
|
# to that shader
|
|
17
23
|
|
|
24
|
+
__all__ = ["ShaderWrapper"]
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger("manim")
|
|
27
|
+
|
|
18
28
|
|
|
19
29
|
def get_shader_dir():
|
|
20
30
|
return Path(__file__).parent / "shaders"
|
|
@@ -33,25 +43,31 @@ def find_file(file_name: Path, directories: list[Path]) -> Path:
|
|
|
33
43
|
raise OSError(f"{file_name} not Found")
|
|
34
44
|
|
|
35
45
|
|
|
46
|
+
_ShaderDType: TypeAlias = np.void
|
|
47
|
+
_ShaderData: TypeAlias = npt.NDArray[_ShaderDType]
|
|
48
|
+
|
|
49
|
+
|
|
36
50
|
class ShaderWrapper:
|
|
37
51
|
def __init__(
|
|
38
52
|
self,
|
|
39
|
-
vert_data=None,
|
|
40
|
-
vert_indices=None,
|
|
41
|
-
shader_folder=None,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
53
|
+
vert_data: _ShaderData = None,
|
|
54
|
+
vert_indices: Sequence[int] | None = None,
|
|
55
|
+
shader_folder: Path | str | None = None,
|
|
56
|
+
# A dictionary mapping names of uniform variables
|
|
57
|
+
uniforms: dict[str, float | tuple[float, ...]] | None = None,
|
|
58
|
+
# A dictionary mapping names to filepaths for textures.
|
|
59
|
+
texture_paths: Mapping[str, Path | str] | None = None,
|
|
60
|
+
depth_test: bool = False,
|
|
61
|
+
render_primitive: int | str = moderngl.TRIANGLE_STRIP,
|
|
46
62
|
):
|
|
47
|
-
self.vert_data = vert_data
|
|
48
|
-
self.vert_indices = vert_indices
|
|
49
|
-
self.vert_attributes = vert_data.dtype.names
|
|
50
|
-
self.shader_folder = Path(shader_folder or "")
|
|
51
|
-
self.uniforms = uniforms or {}
|
|
52
|
-
self.texture_paths = texture_paths or {}
|
|
53
|
-
self.depth_test = depth_test
|
|
54
|
-
self.render_primitive = str(render_primitive)
|
|
63
|
+
self.vert_data: _ShaderData = vert_data
|
|
64
|
+
self.vert_indices: Sequence[int] | None = vert_indices
|
|
65
|
+
self.vert_attributes: tuple[str, ...] | None = vert_data.dtype.names
|
|
66
|
+
self.shader_folder: Path = Path(shader_folder or "")
|
|
67
|
+
self.uniforms: dict[str, float | tuple[float, ...]] = uniforms or {}
|
|
68
|
+
self.texture_paths: Mapping[str, str | Path] = texture_paths or {}
|
|
69
|
+
self.depth_test: bool = depth_test
|
|
70
|
+
self.render_primitive: str = str(render_primitive)
|
|
55
71
|
self.init_program_code()
|
|
56
72
|
self.refresh_id()
|
|
57
73
|
|
|
@@ -66,7 +82,7 @@ class ShaderWrapper:
|
|
|
66
82
|
result.texture_paths = dict(self.texture_paths)
|
|
67
83
|
return result
|
|
68
84
|
|
|
69
|
-
def is_valid(self):
|
|
85
|
+
def is_valid(self) -> bool:
|
|
70
86
|
return all(
|
|
71
87
|
[
|
|
72
88
|
self.vert_data is not None,
|
|
@@ -75,10 +91,10 @@ class ShaderWrapper:
|
|
|
75
91
|
],
|
|
76
92
|
)
|
|
77
93
|
|
|
78
|
-
def get_id(self):
|
|
94
|
+
def get_id(self) -> str:
|
|
79
95
|
return self.id
|
|
80
96
|
|
|
81
|
-
def get_program_id(self):
|
|
97
|
+
def get_program_id(self) -> int:
|
|
82
98
|
return self.program_id
|
|
83
99
|
|
|
84
100
|
def create_id(self):
|
|
@@ -96,9 +112,9 @@ class ShaderWrapper:
|
|
|
96
112
|
),
|
|
97
113
|
)
|
|
98
114
|
|
|
99
|
-
def refresh_id(self):
|
|
100
|
-
self.program_id = self.create_program_id()
|
|
101
|
-
self.id = self.create_id()
|
|
115
|
+
def refresh_id(self) -> None:
|
|
116
|
+
self.program_id: int = self.create_program_id()
|
|
117
|
+
self.id: str = self.create_id()
|
|
102
118
|
|
|
103
119
|
def create_program_id(self):
|
|
104
120
|
return hash(
|
|
@@ -114,7 +130,7 @@ class ShaderWrapper:
|
|
|
114
130
|
self.shader_folder / f"{name}.glsl",
|
|
115
131
|
)
|
|
116
132
|
|
|
117
|
-
self.program_code = {
|
|
133
|
+
self.program_code: dict[str, str | None] = {
|
|
118
134
|
"vertex_shader": get_code("vert"),
|
|
119
135
|
"geometry_shader": get_code("geom"),
|
|
120
136
|
"fragment_shader": get_code("frag"),
|
|
@@ -123,18 +139,18 @@ class ShaderWrapper:
|
|
|
123
139
|
def get_program_code(self):
|
|
124
140
|
return self.program_code
|
|
125
141
|
|
|
126
|
-
def replace_code(self, old, new):
|
|
142
|
+
def replace_code(self, old: str, new: str) -> None:
|
|
127
143
|
code_map = self.program_code
|
|
128
|
-
for
|
|
144
|
+
for name, _code in code_map.items():
|
|
129
145
|
if code_map[name] is None:
|
|
130
146
|
continue
|
|
131
147
|
code_map[name] = re.sub(old, new, code_map[name])
|
|
132
148
|
self.refresh_id()
|
|
133
149
|
|
|
134
|
-
def combine_with(self, *shader_wrappers):
|
|
150
|
+
def combine_with(self, *shader_wrappers: "ShaderWrapper") -> Self: # noqa: UP037
|
|
135
151
|
# Assume they are of the same type
|
|
136
152
|
if len(shader_wrappers) == 0:
|
|
137
|
-
return
|
|
153
|
+
return self
|
|
138
154
|
if self.vert_indices is not None:
|
|
139
155
|
num_verts = len(self.vert_data)
|
|
140
156
|
indices_list = [self.vert_indices]
|
|
@@ -190,6 +206,6 @@ def get_shader_code_from_file(filename: Path) -> str | None:
|
|
|
190
206
|
return result
|
|
191
207
|
|
|
192
208
|
|
|
193
|
-
def get_colormap_code(rgb_list):
|
|
209
|
+
def get_colormap_code(rgb_list: FloatRGBLike_Array) -> str:
|
|
194
210
|
data = ",".join("vec3({}, {}, {})".format(*rgb) for rgb in rgb_list)
|
|
195
211
|
return f"vec3[{len(rgb_list)}]({data})"
|
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from collections.abc import Iterable, Sequence
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
4
6
|
|
|
5
7
|
import numpy as np
|
|
6
8
|
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from manim.renderer.opengl_renderer import (
|
|
11
|
+
OpenGLRenderer,
|
|
12
|
+
OpenGLVMobject,
|
|
13
|
+
)
|
|
14
|
+
from manim.typing import MatrixMN
|
|
15
|
+
|
|
7
16
|
from ..utils import opengl
|
|
8
17
|
from ..utils.space_ops import cross2d, earclip_triangulation
|
|
9
18
|
from .shader import Shader
|
|
10
19
|
|
|
20
|
+
__all__ = [
|
|
21
|
+
"render_opengl_vectorized_mobject_fill",
|
|
22
|
+
"render_opengl_vectorized_mobject_stroke",
|
|
23
|
+
]
|
|
24
|
+
|
|
11
25
|
|
|
12
|
-
def build_matrix_lists(
|
|
26
|
+
def build_matrix_lists(
|
|
27
|
+
mob: OpenGLVMobject,
|
|
28
|
+
) -> defaultdict[tuple[float, ...], list[OpenGLVMobject]]:
|
|
13
29
|
root_hierarchical_matrix = mob.hierarchical_model_matrix()
|
|
14
|
-
matrix_to_mobject_list =
|
|
30
|
+
matrix_to_mobject_list = defaultdict(list)
|
|
15
31
|
if mob.has_points():
|
|
16
32
|
matrix_to_mobject_list[tuple(root_hierarchical_matrix.ravel())].append(mob)
|
|
17
33
|
mobject_to_hierarchical_matrix = {mob: root_hierarchical_matrix}
|
|
@@ -31,7 +47,9 @@ def build_matrix_lists(mob):
|
|
|
31
47
|
return matrix_to_mobject_list
|
|
32
48
|
|
|
33
49
|
|
|
34
|
-
def render_opengl_vectorized_mobject_fill(
|
|
50
|
+
def render_opengl_vectorized_mobject_fill(
|
|
51
|
+
renderer: OpenGLRenderer, mobject: OpenGLVMobject
|
|
52
|
+
) -> None:
|
|
35
53
|
matrix_to_mobject_list = build_matrix_lists(mobject)
|
|
36
54
|
|
|
37
55
|
for matrix_tuple, mobject_list in matrix_to_mobject_list.items():
|
|
@@ -39,7 +57,11 @@ def render_opengl_vectorized_mobject_fill(renderer, mobject):
|
|
|
39
57
|
render_mobject_fills_with_matrix(renderer, model_matrix, mobject_list)
|
|
40
58
|
|
|
41
59
|
|
|
42
|
-
def render_mobject_fills_with_matrix(
|
|
60
|
+
def render_mobject_fills_with_matrix(
|
|
61
|
+
renderer: OpenGLRenderer,
|
|
62
|
+
model_matrix: MatrixMN,
|
|
63
|
+
mobjects: Iterable[OpenGLVMobject],
|
|
64
|
+
) -> None:
|
|
43
65
|
# Precompute the total number of vertices for which to reserve space.
|
|
44
66
|
# Note that triangulate_mobject() will cache its results.
|
|
45
67
|
total_size = 0
|
|
@@ -79,7 +101,7 @@ def render_mobject_fills_with_matrix(renderer, model_matrix, mobjects):
|
|
|
79
101
|
)
|
|
80
102
|
fill_shader.set_uniform(
|
|
81
103
|
"u_projection_matrix",
|
|
82
|
-
renderer.
|
|
104
|
+
renderer.camera.projection_matrix,
|
|
83
105
|
)
|
|
84
106
|
|
|
85
107
|
vbo = renderer.context.buffer(attributes.tobytes())
|
|
@@ -93,7 +115,7 @@ def render_mobject_fills_with_matrix(renderer, model_matrix, mobjects):
|
|
|
93
115
|
vbo.release()
|
|
94
116
|
|
|
95
117
|
|
|
96
|
-
def triangulate_mobject(mob):
|
|
118
|
+
def triangulate_mobject(mob: OpenGLVMobject) -> np.ndarray:
|
|
97
119
|
if not mob.needs_new_triangulation:
|
|
98
120
|
return mob.triangulation
|
|
99
121
|
|
|
@@ -187,14 +209,20 @@ def triangulate_mobject(mob):
|
|
|
187
209
|
return attributes
|
|
188
210
|
|
|
189
211
|
|
|
190
|
-
def render_opengl_vectorized_mobject_stroke(
|
|
212
|
+
def render_opengl_vectorized_mobject_stroke(
|
|
213
|
+
renderer: OpenGLRenderer, mobject: OpenGLVMobject
|
|
214
|
+
) -> None:
|
|
191
215
|
matrix_to_mobject_list = build_matrix_lists(mobject)
|
|
192
216
|
for matrix_tuple, mobject_list in matrix_to_mobject_list.items():
|
|
193
217
|
model_matrix = np.array(matrix_tuple).reshape((4, 4))
|
|
194
218
|
render_mobject_strokes_with_matrix(renderer, model_matrix, mobject_list)
|
|
195
219
|
|
|
196
220
|
|
|
197
|
-
def render_mobject_strokes_with_matrix(
|
|
221
|
+
def render_mobject_strokes_with_matrix(
|
|
222
|
+
renderer: OpenGLRenderer,
|
|
223
|
+
model_matrix: MatrixMN,
|
|
224
|
+
mobjects: Sequence[OpenGLVMobject],
|
|
225
|
+
) -> None:
|
|
198
226
|
# Precompute the total number of vertices for which to reserve space.
|
|
199
227
|
total_size = 0
|
|
200
228
|
for submob in mobjects:
|
|
@@ -274,7 +302,7 @@ def render_mobject_strokes_with_matrix(renderer, model_matrix, mobjects):
|
|
|
274
302
|
renderer.camera.unformatted_view_matrix @ model_matrix,
|
|
275
303
|
),
|
|
276
304
|
)
|
|
277
|
-
shader.set_uniform("u_projection_matrix", renderer.
|
|
305
|
+
shader.set_uniform("u_projection_matrix", renderer.camera.projection_matrix)
|
|
278
306
|
shader.set_uniform("manim_unit_normal", tuple(-mobjects[0].unit_normal[0]))
|
|
279
307
|
|
|
280
308
|
vbo = renderer.context.buffer(stroke_data.tobytes())
|
|
@@ -64,14 +64,37 @@ Examples
|
|
|
64
64
|
self.play(Restore(self.camera.frame))
|
|
65
65
|
self.wait()
|
|
66
66
|
|
|
67
|
+
.. manim:: SlidingMultipleScenes
|
|
68
|
+
|
|
69
|
+
class SlidingMultipleScenes(MovingCameraScene):
|
|
70
|
+
def construct(self):
|
|
71
|
+
def create_scene(number):
|
|
72
|
+
frame = Rectangle(width=16,height=9)
|
|
73
|
+
circ = Circle().shift(LEFT)
|
|
74
|
+
text = Tex(f"This is Scene {str(number)}").next_to(circ, RIGHT)
|
|
75
|
+
frame.add(circ,text)
|
|
76
|
+
return frame
|
|
77
|
+
|
|
78
|
+
group = VGroup(*(create_scene(i) for i in range(4))).arrange_in_grid(buff=4)
|
|
79
|
+
self.add(group)
|
|
80
|
+
self.camera.auto_zoom(group[0], animate=False)
|
|
81
|
+
for scene in group:
|
|
82
|
+
self.play(self.camera.auto_zoom(scene))
|
|
83
|
+
self.wait()
|
|
84
|
+
|
|
85
|
+
self.play(self.camera.auto_zoom(group, margin=2))
|
|
67
86
|
"""
|
|
68
87
|
|
|
69
88
|
from __future__ import annotations
|
|
70
89
|
|
|
71
90
|
__all__ = ["MovingCameraScene"]
|
|
72
91
|
|
|
92
|
+
from typing import Any
|
|
93
|
+
|
|
73
94
|
from manim.animation.animation import Animation
|
|
95
|
+
from manim.mobject.mobject import Mobject
|
|
74
96
|
|
|
97
|
+
from ..camera.camera import Camera
|
|
75
98
|
from ..camera.moving_camera import MovingCamera
|
|
76
99
|
from ..scene.scene import Scene
|
|
77
100
|
from ..utils.family import extract_mobject_family_members
|
|
@@ -83,15 +106,21 @@ class MovingCameraScene(Scene):
|
|
|
83
106
|
This is a Scene, with special configurations and properties that
|
|
84
107
|
make it suitable for cases where the camera must be moved around.
|
|
85
108
|
|
|
109
|
+
Note: Examples are included in the moving_camera_scene module
|
|
110
|
+
documentation, see below in the 'see also' section.
|
|
111
|
+
|
|
86
112
|
.. SEEALSO::
|
|
87
113
|
|
|
114
|
+
:mod:`.moving_camera_scene`
|
|
88
115
|
:class:`.MovingCamera`
|
|
89
116
|
"""
|
|
90
117
|
|
|
91
|
-
def __init__(
|
|
118
|
+
def __init__(
|
|
119
|
+
self, camera_class: type[Camera] = MovingCamera, **kwargs: Any
|
|
120
|
+
) -> None:
|
|
92
121
|
super().__init__(camera_class=camera_class, **kwargs)
|
|
93
122
|
|
|
94
|
-
def get_moving_mobjects(self, *animations: Animation):
|
|
123
|
+
def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]:
|
|
95
124
|
"""
|
|
96
125
|
This method returns a list of all of the Mobjects in the Scene that
|
|
97
126
|
are moving, that are also in the animations passed.
|
|
@@ -103,7 +132,7 @@ class MovingCameraScene(Scene):
|
|
|
103
132
|
"""
|
|
104
133
|
moving_mobjects = super().get_moving_mobjects(*animations)
|
|
105
134
|
all_moving_mobjects = extract_mobject_family_members(moving_mobjects)
|
|
106
|
-
movement_indicators = self.renderer.camera.get_mobjects_indicating_movement()
|
|
135
|
+
movement_indicators = self.renderer.camera.get_mobjects_indicating_movement() # type: ignore[union-attr]
|
|
107
136
|
for movement_indicator in movement_indicators:
|
|
108
137
|
if movement_indicator in all_moving_mobjects:
|
|
109
138
|
# When one of these is moving, the camera should
|