#vector-math #matrix-vector #linear-algebra #vector #matrix #quaternions

无需std glamour

使用glam的强类型线性代数

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 数学

Download history 73/week @ 2024-04-07 85/week @ 2024-04-14 236/week @ 2024-04-21 258/week @ 2024-04-28 160/week @ 2024-05-05 2/week @ 2024-05-12 87/week @ 2024-05-19 93/week @ 2024-05-26 100/week @ 2024-06-02 32/week @ 2024-06-09 15/week @ 2024-06-16 37/week @ 2024-06-23 8/week @ 2024-06-30 15/week @ 2024-07-07 454/week @ 2024-07-14 372/week @ 2024-07-21

每月850次下载

MIT/Apache

445KB
11K SLoC

使用glam的强类型向量数学

Build Status codecov-badge Latest Version docs Minimum Supported Rust Version

此crate使用bytemuckglam之上实现零成本的强类型接口。

API与euclid相似,但更易于使用(尽管YMMV)。

glam的API设计目标之一是通过不滥用特性和泛型来避免复杂性。此crate与此相反。但它确实允许您在需要时轻松地降级到纯glam

请参阅docs模块以获取详细文档。

[^zero_cost]: 运行时零成本,在发布构建中。此crate可能会增加编译时间,并使调试构建变慢,因为代码量增加。

逐步快速入门指南

  1. 通过定义一个“unit”类型(可以是空的,不需要派生任何特性)来声明您的单位。
  2. 为该结构实现UnitUnit::Scalar确定用于向量组件的原始类型。
  3. 标量必须是f32f64i32u32i64u64i16u16
  4. 基本原始标量也是它们自己的单位(“无类型”)。
示例
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 的成员称为 widthheight,而不是 xy
  • 当需要时,用户可以轻松地降级到普通的 glam 类型。
相对于 glam
  • 将一些正确性检查提升到类型系统。这可以防止某些常见的错误,例如在期望不同坐标空间的上下文中使用来自一个坐标空间的向量。
  • 通过将期望作为函数签名的一部分进行注解,提高了 API 理解和代码可读性。
  • 区分点、矢量和大小也可以防止某些类别的错误。例如,3D 中的 "变换" 操作对于点和矢量是不同的。
相对于 euclid
  • 类型名称更简洁(单个泛型参数而不是两个)。
  • 支持 bytemuck

缺点

  • API 严重依赖于元编程技巧。需要复杂的特质迷宫来支持目标。权衡可以总结为:简单性、易用性、类型安全——选择两个。这个 crate 选择易用性和类型安全。
  • 泛型结构定义具有特质界限。这通常被认为是 Rust 中的反模式,但我们需要使用一个类型参数来编码两个事物,以支持向量类型的结构化构造,因此这是不可避免的。
相对于 glam
  • 由于其简单性,glam 是一个非常易于接触的 API。
  • glam 能够支持广泛的变换原语(例如,glam::Affine3Aglam::Quat 等),用户有很多灵活性来为他们的用例选择最有效的类型。这些在 glamour 中都没有实现。
相对于 euclid
  • 不能使用不同的标量与同一个单位标签。
  • 任何类型都不能用作单位标签 - 它必须实现 Unit

目标

  • 强类型线性代数原语。
  • glam 兼容。
  • 在向量类型中支持一流的 字段结构表达式
  • 支持直接内存映射(例如,上传到GPU缓冲区)。
  • 支持 no_std
  • 遵循 glam API 规范 - "最小惊讶原则"。
  • 仅添加一些额外的几何原语,如 矩形变换轴对齐框
  • 完全不产生运行时开销(与直接使用 glam 相比)。待进行全面的基准测试。
  • 100% 测试覆盖率。

非目标

  • 复杂的线性代数。使用 nalgebraEuclid 代替。
  • 超过 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