ranim 0.1.0-alpha.4

An animation engine inspired by manim and JAnim
Documentation
struct CameraUniforms {
    proj_mat: mat4x4<f32>,
    view_mat: mat4x4<f32>,
    half_frame_size: vec2<f32>,
}

@group(0) @binding(0) var<uniform> cam_uniforms : CameraUniforms;

// (x, y, z, is_closed)
@group(1) @binding(0) var<storage> points3d: array<vec4<f32>>;
// width
@group(1) @binding(1) var<storage> stroke_width: array<f32>;
// (x, y, is_closed, 0)
@group(1) @binding(2) var<storage, read_write> points2d: array<vec4<f32>>;
struct ClipBox {
    min_x: atomic<i32>,
    max_x: atomic<i32>,
    min_y: atomic<i32>,
    max_y: atomic<i32>,
    max_w: atomic<i32>,
}
@group(1) @binding(3) var<storage, read_write> clip_points: ClipBox;

@compute
@workgroup_size(256)
fn cs_main(
    @builtin(global_invocation_id) global_invocation_id: vec3<u32>,
    @builtin(num_workgroups) num_workgroups: vec3<u32>
) {
    let index = global_invocation_id.x;

    var point: vec4<f32>;
    point = cam_uniforms.proj_mat * cam_uniforms.view_mat * vec4(points3d[index].xyz, 1.0);
    let x = point.x / point.w * cam_uniforms.half_frame_size.x;
    let y = point.y / point.w * cam_uniforms.half_frame_size.y;

    atomicMin(&clip_points.min_x, i32(floor(x)));
    atomicMax(&clip_points.max_x, i32(ceil(x)));
    atomicMin(&clip_points.min_y, i32(floor(y)));
    atomicMax(&clip_points.max_y, i32(ceil(y)));
    atomicMax(&clip_points.max_w, i32(ceil(stroke_width[index/2])));

    points2d[index].x = x;
    points2d[index].y = y;
    points2d[index].z = points3d[index].w;
    // points2d[index].z = point.z;
}