Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
10b77fe
gl matrix and jolt match.
treeform Apr 13, 2026
9e566e2
it works!
treeform Apr 13, 2026
b9377ba
we are back
treeform Apr 13, 2026
a4ce837
new math stuff
treeform Apr 13, 2026
03097cf
Fix the quats.
treeform Apr 13, 2026
74a3d59
add slerp test more things.
treeform Apr 13, 2026
58e1e2b
Test the new things.
treeform Apr 13, 2026
d9ed456
f
treeform Apr 13, 2026
c5cd218
f
treeform Apr 13, 2026
353d6b9
relative path
treeform Apr 14, 2026
0f6b348
Add GLSL
treeform Apr 14, 2026
a19820f
rename to conformance
treeform Apr 14, 2026
8ce4a78
foo...
treeform Apr 14, 2026
01f2c6f
make dump scripts same and use raw memory
treeform Apr 14, 2026
e3a613d
more match
treeform Apr 15, 2026
b987ee1
even more comp
treeform Apr 15, 2026
2ddb96d
f
treeform Apr 15, 2026
8cbd489
f
treeform Apr 15, 2026
4e3602c
do the native print too.
treeform Apr 15, 2026
d38e0e1
f
treeform Apr 15, 2026
9390666
undo
treeform Apr 15, 2026
657e5d2
no change
treeform Apr 15, 2026
c769756
testing more things!
treeform Apr 15, 2026
dd88dd0
Undo things, y-up default.
treeform Apr 15, 2026
6d7d3e8
Re do the tests based on the dump scripts.
treeform Apr 15, 2026
9e50c77
more tests
treeform Apr 15, 2026
acb2a52
add more tests
treeform Apr 15, 2026
8f18099
fix rotationOnly
treeform Apr 15, 2026
ae96d95
not all nim supports all
treeform Apr 15, 2026
0fe1a2e
update yaml
treeform Apr 15, 2026
5bdfe34
f
treeform Apr 15, 2026
4b6afbe
more stable inverse test
treeform Apr 15, 2026
7c3fc9f
fix js test
treeform Apr 15, 2026
af5d7ac
f
treeform Apr 16, 2026
723d91d
v3.0.0
treeform Apr 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ jobs:
- uses: treeform/setup-nim-action@v2
with:
nim-version: ${{ matrix.nim-version }}
- run: nim r tests/test_quaternion.nim
- run: nim r --gc:arc tests/test_quaternion.nim
- run: nim r -d:vmathObjBased tests/test_quaternion.nim
- run: nim r -d:vmathArrayBased tests/test_quaternion.nim
- run: nim js -r tests/test_quaternion.nim
- run: nim r tests/test.nim
- run: nim r --gc:arc tests/test.nim
- run: nim r -d:vmathObjBased tests/test.nim
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
!*.*

# normal ignores:
*.js
*.exe
nimcache
tests/test.js
66 changes: 51 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,21 +106,57 @@ This is the same system used in the GLTF file format.

[glTF Spec 2.0](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#coordinate-system-and-units)

## OpenGL matrix column-major notation.

> [9.005](https://www.opengl.org/archives/resources/faq/technical/transformations.htm) For programming purposes, OpenGL matrices are 16-value arrays with base vectors laid out contiguously in memory. The translation components occupy the 13th, 14th, and 15th elements of the 16-element matrix, where indices are numbered from 1 to 16 as described in section 2.11.2 of the [OpenGL 2.1 Specification](https://registry.khronos.org/OpenGL/specs/gl/glspec21.pdf).
>
> Sadly, the use of column-major format in the spec and blue book has resulted in endless confusion in the OpenGL programming community. Column-major notation suggests that matrices are not laid out in memory as a programmer would expect.

OpenGL/GLSL/vmath vs Math/Specification notation:
```
mat4([
a, b, c, 0, | a d g x |
d, e, f, 0, | b e h y |
g, h, i, 0, | c f i z |
x, y, z, 1 | 0 0 0 1 |
])
```
## How does vmath compare to other libraries?

vmath follows the standard glTF / OpenGL conventions: right-handed coordinate system, column-major matrix storage, and math-style `[row, col]` indexing.

We run identical math operations across vmath, GLSL, [nim-glm](https://github.com/nickelsworth/nim-glm), [gl-matrix](https://github.com/toji/gl-matrix), and [Jolt Physics](https://github.com/jrouwe/JoltPhysics) and compare the generated dumps in [conformance/](conformance/).


| Feature | vmath | GLSL | nim-GLM | gl-matrix | Jolt Physics |
|----------------------------|:-----:|:----:|:-------:|:---------:|:------------:|
| Vectors | ✅ | ✅ | ✅ | ✅ | ✅ |
| Matrix memory layout | ✅ | ✅ | ✅ | ✅ | ✅ |
| Matrix multiply | ✅ | ✅ | ✅ | ✅ | ✅ |
| Matrix-vector multiply | ✅ | ✅ | ✅ | ✅ | ✅ |
| Rotation matrices | ✅ | ✅ | ✅ | ✅ | ✅ |
| Translation matrices | ✅ | ✅ | ✅ | ✅ | ✅ |
| Scale matrices | ✅ | ✅ | ✅ | ✅ | ✅ |
| Mat2 | ✅ | ✅ | ✅ | ✅ | N/A |
| Mat3 | ✅ | ✅ | ✅ | ✅ | N/A |
| Mat3 2D constructors. | ✅ | ✅ | ✅ | ✅ | N/A |
| Quaternion constructors | ✅ | ✅ | ✅ | ✅ | ✅ |
| Quaternion multiply | ✅ | ✅ | ✅ | ✅ | ✅ |
| Quaternion vector rotation | ✅ | ✅ | ✅ | ✅ | ✅ |
| Quaternion-matrix roundtrip| ✅ | ✅ | ✅ | ✅ | ✅ |
| Quaternion inverse | ✅ | ✅ | ✅ | ✅ | ✅ |
| Quaternion to axis-angle | ✅ | ✅ | ✅ | ✅ | ✅ |
| Matrix inverse | ✅ | ✅ | ✅ | ✅ | ✅ |
| Cross product | ✅ | ✅ | ✅ | ✅ | ✅ |
| Slerp | ✅ | ✅ | ✅ | ✅ | ✅ |
| fromTwoVectors | ✅ | ✅ | ✅ | ✅ | ✅ |
| Quat decomposition (sign) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Scaled-matrix decomposition| ✅ | ✅ | ✅ | ✅ | ✅ |
| LookAt matrix | ✅ | ✅ | ✅ | ✅ | ✅ |
| Perspective matrix | ✅ | ✅ | ✅ | ✅ | ❌ |
| Ortho matrix | ✅ | ✅ | ✅ | ✅ | N/A |
| Euler angle decomposition | ✅ | ✅ | ✅ | N/A | ✅ |
| Element access | ✅ | ✅ | ✅ | N/A | ❌ |

❌ **Perspective matrix**: Jolt Physics uses Z range `[0, 1]` (Vulkan/DirectX convention) while vmath uses Z range `[-1, 1]` (OpenGL convention). The X and Y scaling match, but Z-related elements differ.

❌ **Element access note**: Jolt does convention differs from vmath's math-style `[row, col]` interpretation it follows the DirectX/HLSL convention.

# 2.x.x to 3.0.0 vmath breaking changes:

Version `3.0.0` changed rotation to be CCW (counter-clockwise) and updated the quaternion conventions to match GLSL, GLM, gl-matrix. Added a multi-library conformance suite.

* **Rotation matrices (`rotateX`, `rotateY`, `rotateZ`, 2D `rotate`) now use standard CCW (counter-clockwise) convention.** The sin/cos sign placement in the rotation matrices was swapped. If your code relied on the old CW direction, please negate the angle.
* **Quaternion ↔ matrix conversion (`quat()`, `mat4()`) rewritten.** Uses the standard "biggest component" algorithm matching GLM/GLSL. The off-diagonal signs in `mat4(quat)` were swapped to match the new rotation direction.
* **`toAngles` corrected signs and added gimbal-lock clamping.** No longer negates the Y and Z angles to match the new rotation direction.
* **`fromTwoVectors(a, b)` now rotates `a` into `b`.** Previous behavior had that direction reversed.
* **`lookAt()` un-deprecated.** Restored with Y-up which is glTF/OpenGL convention.
* **New functions added:** `quatInverse`, `slerp`, `quatMultiply`, `quatRotate`, `quatRotateX/Y/Z`, `toAngles(quat)`, `mat4(DMat4)`, `dmat4(Mat4)`, and Mat2 operations (`*`, `transpose`, `determinant`, `inverse`).

# 1.x.x to 2.0.0 vmath breaking changes:
* New right-hand-Z-forward coordinate system and functions that care about
Expand Down
Loading