21个版本 (10个破坏性版本)
| 0.11.1 | 2024年3月26日 |
|---|---|
| 0.10.3 | 2024年3月25日 |
| 0.10.0 | 2023年12月27日 |
| 0.9.0 | 2023年11月22日 |
| 0.4.1 | 2022年7月26日 |
#124 in 数学
每月850次下载
445KB
11K SLoC
使用glam的强类型向量数学
此crate使用bytemuck在glam之上实现零成本的强类型接口。
API与euclid相似,但更易于使用(尽管YMMV)。
glam的API设计目标之一是通过不滥用特性和泛型来避免复杂性。此crate与此相反。但它确实允许您在需要时轻松地降级到纯glam。
[^zero_cost]: 运行时零成本,在发布构建中。此crate可能会增加编译时间,并使调试构建变慢,因为代码量增加。
逐步快速入门指南
- 通过定义一个“unit”类型(可以是空的,不需要派生任何特性)来声明您的单位。
- 为该结构实现
Unit。Unit::Scalar确定用于向量组件的原始类型。 - 标量必须是
f32、f64、i32、u32、i64、u64、i16或u16。 - 基本原始标量也是它们自己的单位(“无类型”)。
示例
use glamour::prelude::*;
struct MyUnit;
impl Unit for MyUnit {
type Scalar = f32;
}
// Start using your new unit:
let vector: Vector4<MyUnit> = Vector4 { x: 1.0, y: 2.0, z: 3.0, w: 4.0 };
let size: Size2<MyUnit> = Size2 { width: 100.0, height: 200.0 };
// Use untyped units when needed:
let vector_untyped: &Vector4<f32> = vector.as_untyped();
// Use glam when needed:
let vector_raw: &glam::Vec4 = vector.as_raw();
功能开关
std- 启用glam/std功能。默认启用。libm- 在no_std编译时必需(间接启用glam/no_std)。mint- 启用与/自mint类型的转换。encase:启用向量类型和矩阵类型encase::ShaderType的实现,使它们能够在 GPU 着色器中使用。scalar-math:即使在目标架构支持的情况下,也不使用 SIMD 向量指令。注意,由于向量指令不受支持,此标志是运行 Miri 下的测试所必需的。间接启用glam/scalar-math功能。
优势
- 结构化类型构造有时更好,因为它不依赖于位置参数。它还允许我们给事物赋予更有意义的名称——例如,
Size2的成员称为width和height,而不是x和y。 - 当需要时,用户可以轻松地降级到普通的
glam类型。
相对于 glam
- 将一些正确性检查提升到类型系统。这可以防止某些常见的错误,例如在期望不同坐标空间的上下文中使用来自一个坐标空间的向量。
- 通过将期望作为函数签名的一部分进行注解,提高了 API 理解和代码可读性。
- 区分点、矢量和大小也可以防止某些类别的错误。例如,3D 中的 "变换" 操作对于点和矢量是不同的。
相对于 euclid
- 类型名称更简洁(单个泛型参数而不是两个)。
- 支持
bytemuck。
缺点
- API 严重依赖于元编程技巧。需要复杂的特质迷宫来支持目标。权衡可以总结为:简单性、易用性、类型安全——选择两个。这个 crate 选择易用性和类型安全。
- 泛型结构定义具有特质界限。这通常被认为是 Rust 中的反模式,但我们需要使用一个类型参数来编码两个事物,以支持向量类型的结构化构造,因此这是不可避免的。
相对于 glam
- 由于其简单性,
glam是一个非常易于接触的 API。 glam能够支持广泛的变换原语(例如,glam::Affine3A、glam::Quat等),用户有很多灵活性来为他们的用例选择最有效的类型。这些在glamour中都没有实现。
相对于 euclid
- 不能使用不同的标量与同一个单位标签。
- 任何类型都不能用作单位标签 - 它必须实现
Unit。
目标
- 强类型线性代数原语。
- 与
glam兼容。 - 在向量类型中支持一流的 字段结构表达式。
- 支持直接内存映射(例如,上传到GPU缓冲区)。
- 支持
no_std。 - 遵循
glamAPI 规范 - "最小惊讶原则"。 - 仅添加一些额外的几何原语,如 矩形、变换和 轴对齐框。
- 完全不产生运行时开销(与直接使用
glam相比)。待进行全面的基准测试。 - 100% 测试覆盖率。
非目标
- 复杂的线性代数。使用 nalgebra 或 Euclid 代替。
- 超过 4 维的向量大小(
glam所支持的最多维数)。 - 向量/矩阵大小的类型参数化。
- 非方阵。
- 封装所有
glamAPI。相反,我们在需要时使其非常容易(且性能良好)地降级到glam类型。 - 隐藏
glamAPI。在公共API中使用glam类型是可以的。 - 遵循 "AoSoA" 模式("额外宽"向量类型)。使用 ultraviolet 代替[^use_uv]。
[^use_uv]: Ultraviolet 支持 bytemuck,而且这个库中的类型实际上与非宽向量类型兼容,因此可能实际上可以工作(使用 bytemuck::cast() 和朋友),但没有任何保证。
性能
所有操作都应该与它们的 glam 对应物完全相同。对于发布构建,对开销有零容忍政策。
然而,在某些情况下,调试构建的性能也很重要。例如,对于视频游戏,它可能决定了在调试模式下是否可玩。
预计这个crate在调试构建中相对于 glam 会有约 2 倍的开销。这可能在将来得到缓解,但似乎即使 glam 本身也没有特别关注在调试构建中表现良好。
依赖项
~3.5MB
~100K SLoC