blob: 2bb3279aa8bdbc7975a2457bd6304864b37abc38 [file] [log] [blame] [edit]
// Copyright 2023 The Vello authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! Utility types
use vello_encoding::ConfigUniform;
#[derive(Clone, Copy, Default, Debug)]
#[repr(C)]
pub struct Vec2 {
pub x: f32,
pub y: f32,
}
impl std::ops::Add for Vec2 {
type Output = Vec2;
fn add(self, rhs: Self) -> Self {
Vec2 {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl std::ops::Sub for Vec2 {
type Output = Vec2;
fn sub(self, rhs: Self) -> Self {
Vec2 {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl std::ops::Mul<f32> for Vec2 {
type Output = Vec2;
fn mul(self, rhs: f32) -> Self {
Vec2 {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
impl Vec2 {
pub fn new(x: f32, y: f32) -> Self {
Vec2 { x, y }
}
pub fn dot(self, other: Vec2) -> f32 {
self.x * other.x + self.y * other.y
}
pub fn length(self) -> f32 {
self.x.hypot(self.y)
}
pub fn to_array(self) -> [f32; 2] {
[self.x, self.y]
}
pub fn from_array(a: [f32; 2]) -> Self {
Vec2 { x: a[0], y: a[1] }
}
pub fn mix(self, other: Vec2, t: f32) -> Self {
let x = self.x + (other.x - self.x) * t;
let y = self.y + (other.y - self.y) * t;
Vec2 { x, y }
}
}
pub struct Transform(pub [f32; 6]);
impl Transform {
pub fn apply(&self, p: Vec2) -> Vec2 {
let z = self.0;
let x = z[0] * p.x + z[2] * p.y + z[4];
let y = z[1] * p.x + z[3] * p.y + z[5];
Vec2 { x, y }
}
pub fn read(transform_base: u32, ix: u32, data: &[u32]) -> Transform {
let mut z = [0.0; 6];
let base = (transform_base + ix * 6) as usize;
for i in 0..6 {
z[i] = f32::from_bits(data[base + i]);
}
Transform(z)
}
}
pub fn span(a: f32, b: f32) -> u32 {
(a.max(b).ceil() - a.min(b).floor()).max(1.0) as u32
}
const DRAWTAG_NOP: u32 = 0;
/// Read draw tag, guarded by number of draw objects.
///
/// The `ix` argument is allowed to exceed the number of draw objects,
/// in which case a NOP is returned.
pub fn read_draw_tag_from_scene(config: &ConfigUniform, scene: &[u32], ix: u32) -> u32 {
if ix < config.layout.n_draw_objects {
let tag_ix = config.layout.draw_tag_base + ix;
scene[tag_ix as usize]
} else {
DRAWTAG_NOP
}
}