mirror of
https://github.com/3b1b/manim.git
synced 2025-07-29 04:53:34 +08:00
Track unit normal for fill
This commit is contained in:
@ -62,8 +62,9 @@ class VMobject(Mobject):
|
|||||||
('joint_product', np.float32, (4,)),
|
('joint_product', np.float32, (4,)),
|
||||||
('fill_rgba', np.float32, (4,)),
|
('fill_rgba', np.float32, (4,)),
|
||||||
('base_point', np.float32, (3,)),
|
('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']
|
stroke_data_names = ['point', 'stroke_rgba', 'stroke_width', 'joint_product']
|
||||||
|
|
||||||
fill_render_primitive: int = moderngl.TRIANGLE_STRIP
|
fill_render_primitive: int = moderngl.TRIANGLE_STRIP
|
||||||
@ -827,8 +828,25 @@ class VMobject(Mobject):
|
|||||||
points[1] - points[0],
|
points[1] - points[0],
|
||||||
points[2] - points[1],
|
points[2] - points[1],
|
||||||
)
|
)
|
||||||
|
self.data["unit_normal"][:] = normal
|
||||||
return 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):
|
def ensure_positive_orientation(self, recurse=True):
|
||||||
for mob in self.get_family(recurse):
|
for mob in self.get_family(recurse):
|
||||||
if mob.get_unit_normal()[2] < 0:
|
if mob.get_unit_normal()[2] < 0:
|
||||||
@ -1148,6 +1166,7 @@ class VMobject(Mobject):
|
|||||||
self.refresh_triangulation()
|
self.refresh_triangulation()
|
||||||
if refresh_joints:
|
if refresh_joints:
|
||||||
self.get_joint_products(refresh=True)
|
self.get_joint_products(refresh=True)
|
||||||
|
self.get_unit_normal()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@triggers_refreshed_triangulation
|
@triggers_refreshed_triangulation
|
||||||
@ -1157,16 +1176,14 @@ class VMobject(Mobject):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
@triggers_refreshed_triangulation
|
@triggers_refreshed_triangulation
|
||||||
def reverse_points(self):
|
def reverse_points(self, recurse: bool = True):
|
||||||
# This will reset which anchors are
|
# This will reset which anchors are
|
||||||
# considered path ends
|
# considered path ends
|
||||||
for mob in self.get_family():
|
for mob in self.get_family(recurse):
|
||||||
if not mob.has_points():
|
if not mob.has_points():
|
||||||
continue
|
continue
|
||||||
inner_ends = mob.get_subpath_end_indices()[:-1]
|
inner_ends = mob.get_subpath_end_indices()[:-1]
|
||||||
mob.data["point"][inner_ends + 1] = mob.data["point"][inner_ends + 2]
|
mob.data["point"][inner_ends + 1] = mob.data["point"][inner_ends + 2]
|
||||||
super().reverse_points()
|
|
||||||
return self
|
|
||||||
|
|
||||||
@triggers_refreshed_triangulation
|
@triggers_refreshed_triangulation
|
||||||
def set_data(self, data: np.ndarray):
|
def set_data(self, data: np.ndarray):
|
||||||
@ -1248,11 +1265,12 @@ class VMobject(Mobject):
|
|||||||
back_stroke_data = []
|
back_stroke_data = []
|
||||||
for submob in family:
|
for submob in family:
|
||||||
if submob.has_fill():
|
if submob.has_fill():
|
||||||
submob.data["base_point"][:] = submob.data["point"][0]
|
data = submob.data[fill_names]
|
||||||
fill_datas.append(submob.data[fill_names])
|
data["base_point"][:] = data["point"][0]
|
||||||
|
fill_datas.append(data)
|
||||||
if self._use_winding_fill:
|
if self._use_winding_fill:
|
||||||
# Add dummy
|
# Add dummy
|
||||||
fill_datas.append(submob.data[fill_names][-1:])
|
fill_datas.append(data[-1:])
|
||||||
else:
|
else:
|
||||||
fill_indices.append(submob.get_triangulation())
|
fill_indices.append(submob.get_triangulation())
|
||||||
if submob.has_stroke():
|
if submob.has_stroke():
|
||||||
|
@ -7,6 +7,7 @@ in float fill_all;
|
|||||||
in float orientation;
|
in float orientation;
|
||||||
in vec2 uv_coords;
|
in vec2 uv_coords;
|
||||||
in vec3 point;
|
in vec3 point;
|
||||||
|
in vec3 unit_normal;
|
||||||
|
|
||||||
out vec4 frag_color;
|
out vec4 frag_color;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ out vec4 frag_color;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
if (color.a == 0) discard;
|
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
|
We want negatively oriented triangles to be canceled with positively
|
||||||
oriented ones. The easiest way to do this is to give them negative alpha,
|
oriented ones. The easiest way to do this is to give them negative alpha,
|
||||||
|
@ -9,11 +9,13 @@ in vec3 verts[3];
|
|||||||
in vec4 v_color[3];
|
in vec4 v_color[3];
|
||||||
in vec3 v_base_point[3];
|
in vec3 v_base_point[3];
|
||||||
in float v_vert_index[3];
|
in float v_vert_index[3];
|
||||||
|
in vec3 v_unit_normal[3];
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
out float fill_all;
|
out float fill_all;
|
||||||
out float orientation;
|
out float orientation;
|
||||||
out vec3 point;
|
out vec3 point;
|
||||||
|
out vec3 unit_normal;
|
||||||
// uv space is where the curve coincides with y = x^2
|
// uv space is where the curve coincides with y = x^2
|
||||||
out vec2 uv_coords;
|
out vec2 uv_coords;
|
||||||
|
|
||||||
@ -26,12 +28,18 @@ const vec2 SIMPLE_QUADRATIC[3] = vec2[3](
|
|||||||
|
|
||||||
// Analog of import for manim only
|
// Analog of import for manim only
|
||||||
#INSERT get_gl_Position.glsl
|
#INSERT get_gl_Position.glsl
|
||||||
#INSERT get_unit_normal.glsl
|
|
||||||
|
|
||||||
|
|
||||||
void emit_triangle(vec3 points[3], vec4 v_color[3]){
|
void emit_triangle(vec3 points[3], vec4 v_color[3]){
|
||||||
vec3 unit_normal = get_unit_normal(points[0], points[1], points[2]);
|
unit_normal = v_unit_normal[1];
|
||||||
orientation = winding ? sign(unit_normal.z) : 1.0;
|
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++){
|
for(int i = 0; i < 3; i++){
|
||||||
uv_coords = SIMPLE_QUADRATIC[i];
|
uv_coords = SIMPLE_QUADRATIC[i];
|
||||||
|
@ -3,15 +3,18 @@
|
|||||||
in vec3 point;
|
in vec3 point;
|
||||||
in vec4 fill_rgba;
|
in vec4 fill_rgba;
|
||||||
in vec3 base_point;
|
in vec3 base_point;
|
||||||
|
in vec3 unit_normal;
|
||||||
|
|
||||||
out vec3 verts; // Bezier control point
|
out vec3 verts; // Bezier control point
|
||||||
out vec4 v_color;
|
out vec4 v_color;
|
||||||
out vec3 v_base_point;
|
out vec3 v_base_point;
|
||||||
|
out vec3 v_unit_normal;
|
||||||
out float v_vert_index;
|
out float v_vert_index;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
verts = point;
|
verts = point;
|
||||||
v_color = fill_rgba;
|
v_color = fill_rgba;
|
||||||
v_base_point = base_point;
|
v_base_point = base_point;
|
||||||
|
v_unit_normal = unit_normal;
|
||||||
v_vert_index = gl_VertexID;
|
v_vert_index = gl_VertexID;
|
||||||
}
|
}
|
Reference in New Issue
Block a user