Better Scene mobject management

This commit is contained in:
Grant Sanderson 2016-07-19 11:07:26 -07:00
parent 889c31f590
commit a87b58a633
2 changed files with 34 additions and 12 deletions

View file

@ -16,6 +16,8 @@ class Animation(object):
"run_time" : DEFAULT_ANIMATION_RUN_TIME,
"rate_func" : smooth,
"name" : None,
#Does this animation add or remove a mobject form the screen
"remover" : False,
}
def __init__(self, mobject, **kwargs):
mobject = instantiate(mobject)
@ -63,6 +65,9 @@ class Animation(object):
#Typically ipmlemented by subclass
pass
def is_remover(self):
return self.remover
def clean_up(self):
self.update(1)

View file

@ -79,12 +79,12 @@ class Scene(object):
Mobjects will be displayed, from background to foreground,
in the order with which they are entered.
Scene class only keeps track of pointful monjects, all
grouping structure is forgotten as far as Scene is concerned
Scene class only keeps track of top-level monjects, all
concerns with submobjects is left to animations and subclass
implementations of the construct method.
"""
if not all_elements_are_instances(mobjects, Mobject):
raise Exception("Adding something which is not a mobject")
mobjects = self.extract_mobjects_with_points(*mobjects)
old_mobjects = filter(lambda m : m not in mobjects, self.mobjects)
self.mobjects = old_mobjects + list(mobjects)
return self
@ -95,14 +95,12 @@ class Scene(object):
by calling add_mobjects_among(locals().values())
"""
mobjects = filter(lambda x : isinstance(x, Mobject), values)
mobjects = self.extract_mobjects_with_points(*mobjects)
self.add(*mobjects)
return self
def remove(self, *mobjects):
if not all_elements_are_instances(mobjects, Mobject):
raise Exception("Removing something which is not a mobject")
mobjects = self.extract_mobjects_with_points(*mobjects)
# mobjects = filter(lambda m : m in self.mobjects, mobjects)
if len(mobjects) == 0:
return
@ -138,12 +136,18 @@ class Scene(object):
return animations
def separate_moving_and_static_mobjects(self, *animations):
"""
During an animation, the only mobjects directly influencing
display are those with points. This allows for the case
where you might have intersections between the families of
animated mobjects and static mobjects
"""
moving_mobjects = self.extract_mobjects_with_points(
*[anim.mobject for anim in animations]
)
static_mobjects = filter(
lambda m : m not in moving_mobjects,
self.mobjects
lambda m : m not in moving_mobjects,
self.extract_mobjects_with_points(*self.mobjects)
)
return moving_mobjects, static_mobjects
@ -164,14 +168,12 @@ class Scene(object):
raise Warning("Called Scene.play with no animations")
return
self.num_animations += 1
self.add(*[anim.mobject for anim in animations])
self.mobjects_from_last_animation = []
animations = self.align_run_times(*animations, **kwargs)
moving_mobjects, static_mobjects = \
self.separate_moving_and_static_mobjects(*animations)
self.update_frame(
static_mobjects,
include_submobjects = False
)
self.update_frame(static_mobjects)
static_image = self.get_frame()
for t in self.get_time_progression(animations):
@ -179,10 +181,25 @@ class Scene(object):
animation.update(t / animation.run_time)
self.update_frame(moving_mobjects, static_image)
self.frames.append(self.get_frame())
self.clean_up_animations(*animations)
return self
def clean_up_animations(self, *animations):
for animation in animations:
animation.clean_up()
if animation.is_remover():
self.remove(animation.mobject)
else:
self.add(animation.mobject)
self.mobjects_from_last_animation.append(animation.mobject)
return self
def get_mobjects_from_last_animation(self):
if hasattr(self, "mobjects_from_last_animation"):
return self.mobjects_from_last_animation
return []
def play_over_time_range(self, t0, t1, *animations):
needed_scene_time = max(abs(t0), abs(t1))
existing_scene_time = len(self.frames)*self.frame_duration