diff --git a/manimlib/mobject/types/vectorized_mobject.py b/manimlib/mobject/types/vectorized_mobject.py index a26cac2a..5aea17c9 100644 --- a/manimlib/mobject/types/vectorized_mobject.py +++ b/manimlib/mobject/types/vectorized_mobject.py @@ -62,8 +62,9 @@ class VMobject(Mobject): ('joint_product', np.float32, (4,)), ('fill_rgba', np.float32, (4,)), ('base_point', np.float32, (3,)), + ('unit_normal', np.float32, (3,)), ]) - fill_data_names = ['point', 'fill_rgba', 'base_point'] + fill_data_names = ['point', 'fill_rgba', 'base_point', 'unit_normal'] stroke_data_names = ['point', 'stroke_rgba', 'stroke_width', 'joint_product'] fill_render_primitive: int = moderngl.TRIANGLE_STRIP @@ -827,8 +828,25 @@ class VMobject(Mobject): points[1] - points[0], points[2] - points[1], ) + self.data["unit_normal"][:] = normal return normal + def refresh_unit_normal(self): + self.get_unit_normal() + return self + + def rotate( + self, + angle: float, + axis: Vect3 = OUT, + about_point: Vect3 | None = None, + **kwargs + ): + super().rotate(angle, axis, about_point, **kwargs) + for mob in self.get_family(): + mob.refresh_unit_normal() + return self + def ensure_positive_orientation(self, recurse=True): for mob in self.get_family(recurse): if mob.get_unit_normal()[2] < 0: @@ -1148,6 +1166,7 @@ class VMobject(Mobject): self.refresh_triangulation() if refresh_joints: self.get_joint_products(refresh=True) + self.get_unit_normal() return self @triggers_refreshed_triangulation @@ -1157,16 +1176,14 @@ class VMobject(Mobject): return self @triggers_refreshed_triangulation - def reverse_points(self): + def reverse_points(self, recurse: bool = True): # This will reset which anchors are # considered path ends - for mob in self.get_family(): + for mob in self.get_family(recurse): if not mob.has_points(): continue inner_ends = mob.get_subpath_end_indices()[:-1] mob.data["point"][inner_ends + 1] = mob.data["point"][inner_ends + 2] - super().reverse_points() - return self @triggers_refreshed_triangulation def set_data(self, data: np.ndarray): @@ -1248,11 +1265,12 @@ class VMobject(Mobject): back_stroke_data = [] for submob in family: if submob.has_fill(): - submob.data["base_point"][:] = submob.data["point"][0] - fill_datas.append(submob.data[fill_names]) + data = submob.data[fill_names] + data["base_point"][:] = data["point"][0] + fill_datas.append(data) if self._use_winding_fill: # Add dummy - fill_datas.append(submob.data[fill_names][-1:]) + fill_datas.append(data[-1:]) else: fill_indices.append(submob.get_triangulation()) if submob.has_stroke(): diff --git a/manimlib/shaders/quadratic_bezier_fill/frag.glsl b/manimlib/shaders/quadratic_bezier_fill/frag.glsl index a7467b49..199efbec 100644 --- a/manimlib/shaders/quadratic_bezier_fill/frag.glsl +++ b/manimlib/shaders/quadratic_bezier_fill/frag.glsl @@ -7,6 +7,7 @@ in float fill_all; in float orientation; in vec2 uv_coords; in vec3 point; +in vec3 unit_normal; out vec4 frag_color; @@ -14,7 +15,7 @@ out vec4 frag_color; void main() { if (color.a == 0) discard; - frag_color = finalize_color(color, point, vec3(0.0, 0.0, 1.0)); + frag_color = finalize_color(color, point, unit_normal); /* We want negatively oriented triangles to be canceled with positively oriented ones. The easiest way to do this is to give them negative alpha, diff --git a/manimlib/shaders/quadratic_bezier_fill/geom.glsl b/manimlib/shaders/quadratic_bezier_fill/geom.glsl index f8083c42..4a0d6c70 100644 --- a/manimlib/shaders/quadratic_bezier_fill/geom.glsl +++ b/manimlib/shaders/quadratic_bezier_fill/geom.glsl @@ -9,11 +9,13 @@ in vec3 verts[3]; in vec4 v_color[3]; in vec3 v_base_point[3]; in float v_vert_index[3]; +in vec3 v_unit_normal[3]; out vec4 color; out float fill_all; out float orientation; out vec3 point; +out vec3 unit_normal; // uv space is where the curve coincides with y = x^2 out vec2 uv_coords; @@ -26,12 +28,18 @@ const vec2 SIMPLE_QUADRATIC[3] = vec2[3]( // Analog of import for manim only #INSERT get_gl_Position.glsl -#INSERT get_unit_normal.glsl void emit_triangle(vec3 points[3], vec4 v_color[3]){ - vec3 unit_normal = get_unit_normal(points[0], points[1], points[2]); - orientation = winding ? sign(unit_normal.z) : 1.0; + unit_normal = v_unit_normal[1]; + orientation = 1.0; + if(winding){ + orientation = sign(determinant(mat3( + v_unit_normal[1], + points[1] - points[0], + points[2] - points[0] + ))); + } for(int i = 0; i < 3; i++){ uv_coords = SIMPLE_QUADRATIC[i]; diff --git a/manimlib/shaders/quadratic_bezier_fill/vert.glsl b/manimlib/shaders/quadratic_bezier_fill/vert.glsl index 5818216a..a15752c4 100644 --- a/manimlib/shaders/quadratic_bezier_fill/vert.glsl +++ b/manimlib/shaders/quadratic_bezier_fill/vert.glsl @@ -3,15 +3,18 @@ in vec3 point; in vec4 fill_rgba; in vec3 base_point; +in vec3 unit_normal; out vec3 verts; // Bezier control point out vec4 v_color; out vec3 v_base_point; +out vec3 v_unit_normal; out float v_vert_index; void main(){ verts = point; v_color = fill_rgba; v_base_point = base_point; + v_unit_normal = unit_normal; v_vert_index = gl_VertexID; } \ No newline at end of file