6 个版本 (3 个破坏性更新)
0.4.1 | 2023 年 9 月 20 日 |
---|---|
0.4.0 | 2018 年 6 月 22 日 |
0.3.0 | 2018 年 1 月 7 日 |
0.2.1 | 2017 年 10 月 14 日 |
0.1.0 | 2017 年 9 月 9 日 |
#78 在 图形 API 中
每月下载 2,805 次
在 9 个 库中使用(直接使用 3 个)
75KB
2K SLoC
euler
3D 计算机图形学的数学库。
快速事实
- 围绕
cgmath
的包装,快速解决最常见的任务。 - 专门为 3D 计算机图形学设计。
- 布局和左右手性遵循 OpenGL 惯例。
- 所有角度均假设为弧度。
- 按设计,仅支持
f32
和f64
基础。 - 不区分 '点' 和 '向量' 类型。
演示
反向投影一条射线
let projection = mat4!();
let inverse_projection = projection.inverse();
let ndc = vec2!(-0.5, 0.5);
let eye = inverse_projection * vec4!(ndc, -1, 1);
let view = euler::Trs::new(vec3!(1, 0, -1), quat!(1, 0, 0; PI / 2.0), vec3!(1.0)).matrix();
let inverse_view = view.inverse();
let world = inverse_view * vec4!(eye.xy(), -1, 0);
let ray = world.xyz().normalize();
理由
为什么还要创建另一个数学库?
euler
的创建是对像 cgmath
、euclid
和 nalgebra
这样的流行现有库的常见设计选择的反应。作者认为,虽然这些库适用于广泛的用例,但它们并不足够简单,不能用于向量矩阵代码非常常见的应用程序代码,如 3D 游戏。作者认为这些库受到 '泛型病'(受到许多层抽象和/或泛型的困扰)的影响,以至于不适用于快速原型设计。
目标
作者希望提供一个库,
- 允许以声明性方式编写数学代码。
- 将泛型保持到最小。
- 不需要导入 traits 或预览模块即可使用任何功能。
- 使不同大小类型之间的转换变得简单直观,例如
vec2
到vec4
和mat4
到mat3
。 - 允许不同精度类型之间的直接转换,例如
dvec2
到/从vec2
。
作者打算通过模仿GLSL语法,利用Rust宏系统来实现上述目标。euler
宏的语法设计用来捕捉GLSL向量矩阵构造函数最常见的用法;然而,它并非旨在与GLSL的语法完全匹配。
问答
以下是对rust-gamedev社区成员提出的问题和评论的回复。
等等,你真的在用宏做这个吗‽
是的,因为Rust不允许函数重载。虽然可以使用euler
而不使用宏,但这会失去其意义!
这不是绕过了模块系统吗?
是的,这是当前状态下使用宏的副作用。然而,在3D游戏等应用中,向量矩阵代码非常常见,每次模块都要导入前缀、特性和类型别名,这无疑是一个不必要的麻烦。如果这让你感到不安,那么可能euler
并不适合你。
使用宏会增加编译时间吗?
可能会,但我个人没有注意到。由于库仅执行浅层宏展开(通常是单个函数调用),且通用代码非常少,因此假定编译时间是“足够快的”。
没有点类型,你怎么区分位置和方向向量变换呢?
库的立场是,通过数学而不是通过类型系统来明确变换向量。因此,当变换3D向量时,鼓励用户使用vec4!(xyz, 1)
来显式地进行位置向量的变换,以及使用vec4!(xyz, 0)
来显式地进行方向向量的变换。
许可协议
以下任一许可下授权:
- Apache License,版本2.0 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由你选择。
除非你明确表示,否则,根据Apache-2.0许可中定义的,任何有意提交以包含在你的作品中的贡献,都应如上所述双许可,不附加任何额外条款或条件。
依赖项
~1MB
~17K SLoC