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
。 - 遵循
glam
API 规范 - "最小惊讶原则"。 - 仅添加一些额外的几何原语,如 矩形、变换和 轴对齐框。
- 完全不产生运行时开销(与直接使用
glam
相比)。待进行全面的基准测试。 - 100% 测试覆盖率。
非目标
- 复杂的线性代数。使用 nalgebra 或 Euclid 代替。
- 超过 4 维的向量大小(
glam
所支持的最多维数)。 - 向量/矩阵大小的类型参数化。
- 非方阵。
- 封装所有
glam
API。相反,我们在需要时使其非常容易(且性能良好)地降级到glam
类型。 - 隐藏
glam
API。在公共API中使用glam
类型是可以的。 - 遵循 "AoSoA" 模式("额外宽"向量类型)。使用 ultraviolet 代替[^use_uv]。
[^use_uv]: Ultraviolet 支持 bytemuck
,而且这个库中的类型实际上与非宽向量类型兼容,因此可能实际上可以工作(使用 bytemuck::cast()
和朋友),但没有任何保证。
性能
所有操作都应该与它们的 glam
对应物完全相同。对于发布构建,对开销有零容忍政策。
然而,在某些情况下,调试构建的性能也很重要。例如,对于视频游戏,它可能决定了在调试模式下是否可玩。
预计这个crate在调试构建中相对于 glam
会有约 2 倍的开销。这可能在将来得到缓解,但似乎即使 glam
本身也没有特别关注在调试构建中表现良好。
依赖项
~3.5MB
~100K SLoC