Added improved non-clay text handling along with consistent origin and rotation API
This commit is contained in:
@@ -6,6 +6,7 @@ layout(location = 1) in vec2 f_local_or_uv;
|
||||
layout(location = 2) in vec4 f_params;
|
||||
layout(location = 3) in vec4 f_params2;
|
||||
layout(location = 4) flat in uint f_kind_flags;
|
||||
layout(location = 5) flat in float f_rotation;
|
||||
|
||||
// --- Output ---
|
||||
layout(location = 0) out vec4 out_color;
|
||||
@@ -82,6 +83,15 @@ float sdf_stroke(float d, float stroke_width) {
|
||||
return abs(d) - stroke_width * 0.5;
|
||||
}
|
||||
|
||||
// Rotate a 2D point by the negative of the given angle (inverse rotation).
|
||||
// Used to rotate the sampling frame opposite to the shape's rotation so that
|
||||
// the SDF evaluates correctly for the rotated shape.
|
||||
vec2 apply_rotation(vec2 p, float angle) {
|
||||
float cr = cos(-angle);
|
||||
float sr = sin(-angle);
|
||||
return mat2(cr, sr, -sr, cr) * p;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// main
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -113,11 +123,16 @@ void main() {
|
||||
soft = max(f_params2.z, 1.0);
|
||||
float stroke_px = f_params2.w;
|
||||
|
||||
d = sdRoundedBox(f_local_or_uv, b, r);
|
||||
vec2 p_local = f_local_or_uv;
|
||||
if (f_rotation != 0.0) {
|
||||
p_local = apply_rotation(p_local, f_rotation);
|
||||
}
|
||||
|
||||
d = sdRoundedBox(p_local, b, r);
|
||||
if ((flags & 1u) != 0u) d = sdf_stroke(d, stroke_px);
|
||||
}
|
||||
else if (kind == 2u) {
|
||||
// Circle
|
||||
// Circle — rotationally symmetric, no rotation needed
|
||||
float radius = f_params.x;
|
||||
soft = max(f_params.y, 1.0);
|
||||
float stroke_px = f_params.z;
|
||||
@@ -131,11 +146,16 @@ void main() {
|
||||
soft = max(f_params.z, 1.0);
|
||||
float stroke_px = f_params.w;
|
||||
|
||||
d = sdEllipse(f_local_or_uv, ab);
|
||||
vec2 p_local = f_local_or_uv;
|
||||
if (f_rotation != 0.0) {
|
||||
p_local = apply_rotation(p_local, f_rotation);
|
||||
}
|
||||
|
||||
d = sdEllipse(p_local, ab);
|
||||
if ((flags & 1u) != 0u) d = sdf_stroke(d, stroke_px);
|
||||
}
|
||||
else if (kind == 4u) {
|
||||
// Segment (capsule line)
|
||||
// Segment (capsule line) — no rotation (excluded)
|
||||
vec2 a = f_params.xy; // already in local physical pixels
|
||||
vec2 b = f_params.zw;
|
||||
float width = f_params2.x;
|
||||
@@ -144,7 +164,7 @@ void main() {
|
||||
d = sdSegment(f_local_or_uv, a, b) - width * 0.5;
|
||||
}
|
||||
else if (kind == 5u) {
|
||||
// Ring / Arc
|
||||
// Ring / Arc — rotation handled by CPU angle offset, no shader rotation
|
||||
float inner = f_params.x;
|
||||
float outer = f_params.y;
|
||||
float start_rad = f_params.z;
|
||||
@@ -157,10 +177,8 @@ void main() {
|
||||
// Angular clip
|
||||
float angle = atan(f_local_or_uv.y, f_local_or_uv.x);
|
||||
if (angle < 0.0) angle += 2.0 * PI;
|
||||
float ang_start = start_rad;
|
||||
float ang_end = end_rad;
|
||||
if (ang_start < 0.0) ang_start += 2.0 * PI;
|
||||
if (ang_end < 0.0) ang_end += 2.0 * PI;
|
||||
float ang_start = mod(start_rad, 2.0 * PI);
|
||||
float ang_end = mod(end_rad, 2.0 * PI);
|
||||
|
||||
float in_arc = (ang_end > ang_start)
|
||||
? ((angle >= ang_start && angle <= ang_end) ? 1.0 : 0.0) : ((angle >= ang_start || angle <= ang_end) ? 1.0 : 0.0);
|
||||
@@ -169,7 +187,7 @@ void main() {
|
||||
d = in_arc > 0.5 ? d_ring : 1e30;
|
||||
}
|
||||
else if (kind == 6u) {
|
||||
// Regular N-gon
|
||||
// Regular N-gon — has its own rotation in params, no Primitive.rotation used
|
||||
float radius = f_params.x;
|
||||
float rotation = f_params.y;
|
||||
float sides = f_params.z;
|
||||
|
||||
Reference in New Issue
Block a user