diff --git a/manimlib/animation/animation.py b/manimlib/animation/animation.py index e7cd2f03..c6e3eeec 100644 --- a/manimlib/animation/animation.py +++ b/manimlib/animation/animation.py @@ -29,17 +29,20 @@ class Animation(object): self.mobject = mobject def begin(self): - # mobject = self.mobject - # # Make sure it's all up to date - # mobject.update() - # mobject.suspend_updating() + mobject = self.mobject # Keep track of where it started - self.starting_mobject = self.mobject.copy() - self.update(0) + self.starting_mobject = mobject.copy() + # All calls to mobject's internal updaters + # during the animation, either from this Animation + # or from the surrounding scene, should do nothing. + # It is, however, okay and desirable to call + # self.starting_mobject's internal updaters + mobject.suspend_updating() + self.interpolate(0) def finish(self): + self.interpolate(1) self.mobject.resume_updating() - self.update(1) def clean_up_from_scene(self, scene): if self.is_remover(): @@ -58,13 +61,27 @@ class Animation(object): return self def update_mobjects(self, dt): + """ + Updates things like starting_mobject, and (for + Transforms) target_mobject. Note, since typically + (always?) self.mobject will have its updating + suspended during the animation, this will do + nothing to self.mobject. + """ for mob in self.get_all_mobjects(): mob.update(dt) - def update(self, alpha): + def interpolate(self, alpha): alpha = np.clip(alpha, 0, 1) self.interpolate_mobject(self.rate_func(alpha)) + def update(self, alpha): + """ + This method shouldn't exist, but it's here to + keep many old scenes from breaking + """ + self.interpolate(alpha) + def interpolate_mobject(self, alpha): families = self.get_all_families_zipped() for i, mobs in enumerate(families): @@ -102,12 +119,8 @@ class Animation(object): self.get_all_mobjects() ))) - def filter_out(self, *filter_functions): - self.filter_functions += filter_functions - return self - - def set_run_time(self, time): - self.run_time = time + def set_run_time(self, run_time): + self.run_time = run_time return self def get_run_time(self): diff --git a/manimlib/animation/creation.py b/manimlib/animation/creation.py index 251a5ce4..4398e4f8 100644 --- a/manimlib/animation/creation.py +++ b/manimlib/animation/creation.py @@ -139,7 +139,7 @@ class FadeOut(Transform): def clean_up_from_scene(self, scene=None): Transform.clean_up_from_scene(self, scene) - self.update(0) + self.interpolate(0) class FadeIn(Transform): diff --git a/manimlib/animation/transform.py b/manimlib/animation/transform.py index 0619ba60..4441c63f 100644 --- a/manimlib/animation/transform.py +++ b/manimlib/animation/transform.py @@ -29,43 +29,12 @@ class Transform(Animation): self.target_mobject = target_mobject self.init_path_func() - def begin(self): - mobject = self.mobject - target = self.target_mobject - # Note, this potentially changes the structure - # of both mobject and target_mobject - mobject.align_data(target) - super().begin() - # Copy target_mobject so as to not mess with caller - # self.original_target_mobject = self.target_mobject - self.target_mobject.update() - self.target_mobject.suspend_updating() - self.target_copy = self.target_mobject.copy() - - def finish(self): - super().finish() - self.target_mobject.resume_updating() - - def clean_up_from_scene(self, scene): - super().clean_up_from_scene(scene) - if self.replace_mobject_with_target_in_scene: - scene.remove(self.mobject) - scene.add(self.target_mobject) - def __str__(self): return "{}To{}".format( - super().__str__(self), + super().__str__(), str(self.target_mobject) ) - def update_config(self, **kwargs): - Animation.update_config(self, **kwargs) - if "path_arc" in kwargs: - self.path_func = path_along_arc( - kwargs["path_arc"], - kwargs.get("path_arc_axis", OUT) - ) - def init_path_func(self): if self.path_func is not None: return @@ -77,11 +46,43 @@ class Transform(Animation): self.path_arc_axis, ) - def get_all_mobjects(self): - return self.mobject, self.starting_mobject, self.target_mobject + def begin(self): + # Use a copy of target_mobject for the align_data + # call so that the actual target_mobject stays + # preserved. + self.target_copy = self.target_mobject.copy() + # Note, this potentially changes the structure + # of both mobject and target_mobject + self.mobject.align_data(self.target_copy) + super().begin() - def interpolate_submobject(self, submob, start, end, alpha): - submob.interpolate(start, end, alpha, self.path_func) + def clean_up_from_scene(self, scene): + super().clean_up_from_scene(scene) + if self.replace_mobject_with_target_in_scene: + scene.remove(self.mobject) + scene.add(self.target_mobject) + + def update_config(self, **kwargs): + Animation.update_config(self, **kwargs) + if "path_arc" in kwargs: + self.path_func = path_along_arc( + kwargs["path_arc"], + kwargs.get("path_arc_axis", OUT) + ) + + def get_all_mobjects(self): + return [ + self.mobject, + self.starting_mobject, + self.target_mobject, + self.target_copy, + ] + + def interpolate_submobject(self, submob, start, target, target_copy, alpha): + submob.interpolate( + start, target_copy, + alpha, self.path_func + ) return self @@ -278,7 +279,7 @@ class TransformAnimations(Transform): start_anim.mobject = self.starting_mobject end_anim.mobject = self.target_mobject - def update(self, alpha): - self.start_anim.update(alpha) - self.end_anim.update(alpha) - Transform.update(self, alpha) + def interpolate(self, alpha): + self.start_anim.interpolate(alpha) + self.end_anim.interpolate(alpha) + Transform.interpolate(self, alpha) diff --git a/manimlib/scene/scene.py b/manimlib/scene/scene.py index 3d57f45e..f71f6a71 100644 --- a/manimlib/scene/scene.py +++ b/manimlib/scene/scene.py @@ -483,7 +483,9 @@ class Scene(Container): for t in self.get_animation_time_progression(animations): dt = 1 / self.camera.frame_rate for animation in animations: - animation.update(t / animation.run_time) + animation.update_mobjects(dt) + animation.interpolate(t / animation.run_time) + self.continual_update(dt) self.update_frame(moving_mobjects, static_image) self.add_frames(self.get_frame())