mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Have mobjects keep track of a consistent shader data array to avoid unneeded numpy initializing
This commit is contained in:
parent
c654ca4506
commit
5df2d3db33
3 changed files with 52 additions and 36 deletions
|
@ -41,6 +41,9 @@ class Mobject(Container):
|
|||
"frag_shader_file": "",
|
||||
"render_primative": moderngl.TRIANGLE_STRIP,
|
||||
"texture_path": "",
|
||||
"shader_dtype": [
|
||||
('point', np.float32, (3,)),
|
||||
]
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
@ -55,6 +58,7 @@ class Mobject(Container):
|
|||
self.reset_points()
|
||||
self.init_points()
|
||||
self.init_colors()
|
||||
self.init_shader_data()
|
||||
|
||||
def __str__(self):
|
||||
return str(self.name)
|
||||
|
@ -110,7 +114,7 @@ class Mobject(Container):
|
|||
if camera is None:
|
||||
from manimlib.camera.camera import Camera
|
||||
camera = Camera()
|
||||
camera.capture_mobject(self)
|
||||
camera.capture(self)
|
||||
return camera.get_image()
|
||||
|
||||
def show(self, camera=None):
|
||||
|
@ -1125,6 +1129,18 @@ class Mobject(Container):
|
|||
pass
|
||||
|
||||
# For shaders
|
||||
def init_shader_data(self):
|
||||
self.shader_data = np.zeros(len(self.points), dtype=self.shader_dtype)
|
||||
|
||||
def get_shader_data_array(self, size, name="shader_data"):
|
||||
# If possible, try to populate an existing array, rather
|
||||
# than recreating it each frame
|
||||
arr = getattr(self, name)
|
||||
if arr.size != size:
|
||||
new_arr = np.resize(arr, size)
|
||||
setattr(self, name, new_arr)
|
||||
return new_arr
|
||||
return arr
|
||||
|
||||
def get_shader_info_list(self):
|
||||
return [self.get_shader_info()]
|
||||
|
|
|
@ -15,6 +15,11 @@ class ImageMobject(Mobject):
|
|||
"opacity": 1,
|
||||
"vert_shader_file": "image_vert.glsl",
|
||||
"frag_shader_file": "image_frag.glsl",
|
||||
"shader_dtype": [
|
||||
('point', np.float32, (3,)),
|
||||
('im_coords', np.float32, (2,)),
|
||||
('opacity', np.float32, (1,)),
|
||||
]
|
||||
}
|
||||
|
||||
def __init__(self, filename, **kwargs):
|
||||
|
@ -37,17 +42,10 @@ class ImageMobject(Mobject):
|
|||
self.set_opacity(self.opacity)
|
||||
|
||||
def get_shader_data(self):
|
||||
dtype = [
|
||||
('point', np.float32, (3,)),
|
||||
('im_coords', np.float32, (2,)),
|
||||
('opacity', np.float32, (1,)),
|
||||
]
|
||||
|
||||
data = np.zeros(len(self.points), dtype=dtype)
|
||||
data = self.get_shader_data_array(len(self.points))
|
||||
data["point"] = self.points
|
||||
data["im_coords"] = self.im_coords
|
||||
data["opacity"] = self.opacity
|
||||
|
||||
return data
|
||||
|
||||
def set_opacity(self, alpha, family=True):
|
||||
|
|
|
@ -57,11 +57,22 @@ class VMobject(Mobject):
|
|||
"joint_type": "auto",
|
||||
"render_primative": moderngl.TRIANGLES,
|
||||
"triangulation_locked": False,
|
||||
"fill_dtype": [
|
||||
('point', np.float32, (3,)),
|
||||
('color', np.float32, (4,)),
|
||||
('fill_all', np.float32, (1,)),
|
||||
('orientation', np.float32, (1,)),
|
||||
],
|
||||
"stroke_dtype": [
|
||||
("point", np.float32, (3,)),
|
||||
("prev_point", np.float32, (3,)),
|
||||
("next_point", np.float32, (3,)),
|
||||
("stroke_width", np.float32, (1,)),
|
||||
("color", np.float32, (4,)),
|
||||
("joint_type", np.float32, (1,)),
|
||||
]
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def get_group_class(self):
|
||||
return VGroup
|
||||
|
||||
|
@ -794,6 +805,10 @@ class VMobject(Mobject):
|
|||
return vmob
|
||||
|
||||
# For shaders
|
||||
def init_shader_data(self):
|
||||
self.fill_data = np.zeros(len(self.points), dtype=self.fill_dtype)
|
||||
self.stroke_data = np.zeros(len(self.points), dtype=self.stroke_dtype)
|
||||
|
||||
def get_shader_info_list(self):
|
||||
result = []
|
||||
if self.get_fill_opacity() > 0:
|
||||
|
@ -819,21 +834,12 @@ class VMobject(Mobject):
|
|||
return result
|
||||
|
||||
def get_stroke_shader_data(self):
|
||||
dtype = [
|
||||
("point", np.float32, (3,)),
|
||||
("prev_point", np.float32, (3,)),
|
||||
("next_point", np.float32, (3,)),
|
||||
("stroke_width", np.float32, (1,)),
|
||||
("color", np.float32, (4,)),
|
||||
("joint_type", np.float32, (1,)),
|
||||
]
|
||||
joint_type_to_code = {
|
||||
"auto": 0,
|
||||
"round": 1,
|
||||
"bevel": 2,
|
||||
"miter": 3,
|
||||
}
|
||||
points = self.points
|
||||
|
||||
rgbas = self.get_stroke_rgbas()
|
||||
if len(rgbas) > 1:
|
||||
|
@ -843,12 +849,12 @@ class VMobject(Mobject):
|
|||
if len(stroke_width) > 1:
|
||||
stroke_width = self.stretched_style_array_matching_points(stroke_width)
|
||||
|
||||
data = np.zeros(len(points), dtype=dtype)
|
||||
data['point'] = points
|
||||
data['prev_point'][:3] = points[-3:]
|
||||
data['prev_point'][3:] = points[:-3]
|
||||
data['next_point'][:-3] = points[3:]
|
||||
data['next_point'][-3:] = points[:3]
|
||||
data = self.get_shader_data_array(len(self.points), "stroke_data")
|
||||
data['point'] = self.points
|
||||
data['prev_point'][:3] = self.points[-3:]
|
||||
data['prev_point'][3:] = self.points[:-3]
|
||||
data['next_point'][:-3] = self.points[3:]
|
||||
data['next_point'][-3:] = self.points[:3]
|
||||
data['stroke_width'][:, 0] = stroke_width
|
||||
data['color'] = rgbas
|
||||
data['joint_type'] = joint_type_to_code[self.joint_type]
|
||||
|
@ -858,6 +864,7 @@ class VMobject(Mobject):
|
|||
for sm in self.family_members_with_points():
|
||||
sm.triangulation_locked = False
|
||||
sm.saved_triangulation = sm.get_triangulation()
|
||||
sm.saved_orientation = sm.get_orientation()
|
||||
sm.triangulation_locked = True
|
||||
return self
|
||||
|
||||
|
@ -873,6 +880,8 @@ class VMobject(Mobject):
|
|||
return sum((p0[:, 0] + p1[:, 0]) * (p1[:, 1] - p0[:, 1]))
|
||||
|
||||
def get_orientation(self):
|
||||
if self.triangulation_locked:
|
||||
return self.saved_orientation
|
||||
return np.sign(self.get_signed_polygonal_area())
|
||||
|
||||
def get_triangulation(self, orientation=None):
|
||||
|
@ -928,22 +937,15 @@ class VMobject(Mobject):
|
|||
return tri_indices
|
||||
|
||||
def get_fill_shader_data(self):
|
||||
dtype = [
|
||||
('point', np.float32, (3,)),
|
||||
('color', np.float32, (4,)),
|
||||
('fill_all', np.float32, (1,)),
|
||||
('orientation', np.float32, (1,)),
|
||||
]
|
||||
|
||||
points = self.points
|
||||
|
||||
orientation = self.get_orientation()
|
||||
tri_indices = self.get_triangulation(orientation)
|
||||
|
||||
# TODO, best way to enable multiple colors?
|
||||
rgbas = self.get_fill_rgbas()
|
||||
rgbas = self.get_fill_rgbas()[:1]
|
||||
|
||||
data = np.zeros(len(tri_indices), dtype=dtype)
|
||||
data = self.get_shader_data_array(len(tri_indices), "fill_data")
|
||||
data["point"] = points[tri_indices]
|
||||
data["color"] = rgbas
|
||||
# Assume the triangulation is such that the first n_points points
|
||||
|
|
Loading…
Add table
Reference in a new issue