Don't bevel corners on inner joints of quadratic bezier curves

This commit is contained in:
Grant Sanderson 2024-08-05 13:37:17 -05:00
parent 26249c34bb
commit c61c18486c

View file

@ -67,9 +67,9 @@ vec4 get_joint_product(vec3 v1, vec3 v2){
} }
vec3 project(vec3 vect, vec3 normal){ vec3 project(vec3 vect, vec3 unit_normal){
/* Project the vector onto the plane perpendicular to a given unit normal */ /* Project the vector onto the plane perpendicular to a given unit normal */
return vect - dot(vect, normal) * normal; return vect - dot(vect, unit_normal) * unit_normal;
} }
vec3 inverse_joint_product(vec3 vect, vec4 joint_product){ vec3 inverse_joint_product(vec3 vect, vec4 joint_product){
@ -87,7 +87,7 @@ vec3 inverse_joint_product(vec3 vect, vec4 joint_product){
} }
vec3 step_to_corner(vec3 point, vec3 unit_tan, vec3 unit_normal, vec4 joint_product){ vec3 step_to_corner(vec3 point, vec3 unit_tan, vec3 unit_normal, vec4 joint_product, bool inner_joint){
/* /*
Step the the left of a curve. Step the the left of a curve.
First a perpendicular direction is calculated, then it is adjusted First a perpendicular direction is calculated, then it is adjusted
@ -95,9 +95,9 @@ vec3 step_to_corner(vec3 point, vec3 unit_tan, vec3 unit_normal, vec4 joint_prod
*/ */
vec3 step = normalize(cross(unit_normal, unit_tan)); vec3 step = normalize(cross(unit_normal, unit_tan));
// Check if an adjustment is needed // Check if an adjustment is needed,
float cos_angle = joint_product.w; float cos_angle = joint_product.w;
if(abs(cos_angle) > 1 - 1e-5 || int(joint_type) == NO_JOINT){ if(inner_joint || int(joint_type) == NO_JOINT || cos_angle > 1 - 1e-5){
return step; return step;
} }
@ -107,11 +107,11 @@ vec3 step_to_corner(vec3 point, vec3 unit_tan, vec3 unit_normal, vec4 joint_prod
(cos_angle + 1.0) / sin_angle : (cos_angle + 1.0) / sin_angle :
(cos_angle - 1.0) / sin_angle; (cos_angle - 1.0) / sin_angle;
// return step + shift * unit_tan;
vec3 result = step + shift * unit_tan; vec3 result = step + shift * unit_tan;
if (length(result) > MITER_LIMIT){ if (length(result) > MITER_LIMIT){
result = MITER_LIMIT * normalize(result); result = MITER_LIMIT * normalize(result);
} }
return result; return result;
} }
@ -121,28 +121,31 @@ void emit_point_with_width(
vec3 tangent, vec3 tangent,
vec4 joint_product, vec4 joint_product,
float width, float width,
vec4 joint_color vec4 joint_color,
bool inner_joint
){ ){
// Normalize relevant vectors // Normalize relevant vectors
vec3 unit_tan; vec3 unit_tan;
vec4 unit_jp; vec4 unit_jp;
vec3 unit_normal; vec3 unit_normal;
if(bool(flat_stroke)){ vec3 to_camera = camera_position - point;
if(flat_stroke == 1.0){
unit_tan = normalize(tangent); unit_tan = normalize(tangent);
unit_jp = normalized_joint_product(joint_product); unit_jp = normalized_joint_product(joint_product);
unit_normal = get_joint_unit_normal(joint_product); unit_normal = get_joint_unit_normal(joint_product);
}else{ }else{
unit_normal = normalize(camera_position - point); unit_normal = normalize(to_camera);
unit_tan = normalize(project(tangent, unit_normal)); unit_tan = normalize(project(tangent, unit_normal));
vec3 adj_tan = inverse_joint_product(tangent, joint_product); vec3 adj_tan = inverse_joint_product(tangent, joint_product);
adj_tan = project(adj_tan, unit_normal); adj_tan = project(adj_tan, unit_normal);
unit_jp = normalized_joint_product(get_joint_product(unit_tan, adj_tan)); unit_jp = normalized_joint_product(get_joint_product(unit_tan, adj_tan));
} }
if(unit_normal.z < 0) unit_normal *= -1; // Choose the "outward" normal direction // Choose the "outward" normal direction
if(to_camera.z * dot(unit_normal, to_camera) < 0) unit_normal *= -1;
// Figure out the step from the point to the corners of the // Figure out the step from the point to the corners of the
// triangle strip around the polyline // triangle strip around the polyline
vec3 step = step_to_corner(point, unit_tan, unit_normal, unit_jp); vec3 step = step_to_corner(point, unit_tan, unit_normal, unit_jp, inner_joint);
// Set styling // Set styling
color = finalize_color(joint_color, point, unit_normal); color = finalize_color(joint_color, point, unit_normal);
@ -205,7 +208,8 @@ void main() {
tangent_on_quadratic(t, c1, c2), tangent_on_quadratic(t, c1, c2),
joint_products[i], joint_products[i],
mix(v_stroke_width[0], v_stroke_width[2], t), mix(v_stroke_width[0], v_stroke_width[2], t),
mix(v_color[0], v_color[2], t) mix(v_color[0], v_color[2], t),
(i > 0 && i < n_steps - 1) // Is this an inner joint
); );
} }
EndPrimitive(); EndPrimitive();