Shinmera / 3d-math

A library implementing the necessary linear algebra math for 2D and 3D computations
https://shinmera.github.io/3d-math/
zlib License
14 stars 2 forks source link

About 3d-math

This library implements types, operators, and algorithms commonly used in math for 2D and 3D graphics.

It supersedes and combines the prior libraries 3d-vectors, 3d-matrices, 3d-quaternions, and 3d-transfroms. The new API is largely but not entirely backwards compatible, and adds a lot of new functionality.

General API Conventions

The API is split over five packages for each data type:

With the org.shirakumo.fraf.math package combining them all into one. All packages are designed to be :used, and follow strict function name prefixing to avoid name clashes. The following naming rules apply:

Some example operations would be: v+, nm*, !qinv

For the data types themselves similar rules apply:

Some example types would be: vec2, dmatn, quat, vec* *mat3

The following feature flags indicate which types are supported:

If you would like to disable a specific type, push the corresponding :3d-math-no-* feature before compiling the library. By default (unsigned-byte 32) types are not available. In order to get them, you must similarly push :3d-math-u32 before compiling.

Vectors

The vectors API supports the following operations:

Matrices

The matrices API supports the following operations:

Quaternions

Quaternions represent a rotation or orientation in 3D space. The advantage over the matrix representation is that quaternions are not subject to gimbal lock and offer faster and more precise manipulation over time.

The quaternions API supports the following operations:

Dual Quaternions

Dual quaternions represent a rotation and a translation, without scaling. They can be useful as an alternative representation of transformations, as they preserve twists without loss, while linear matrix interpolation leads to a "squeezing" effect.

The dual-quaternions API supports the following operations:

Transforms

Transforms encapsulate a translation, rotation, and scaling, sometimes also referred to as a "gizmo". It allows encapsulating the transformation of an object without falling victim to gimbal lock or drifting precision from the transform matrix representation.

The transforms API supports the following operations:

Internal Organisation

Each data type is split off into its own module as follows:

Heavy use is made of the "type-templates"(https://shinmera.github.io/type-templates) system to allow generating the many, many different variants of operations for each type combination, as well as the complex dispatching behaviour.

The core template types are vec-type, mat-type, quat-type, quat2-type, and transform-type respectively. We also provide and heavily make use of the custom types f32, f64, u32 and i32 to define the contained immediate value types.

The shared functions and abbreviating macros used for quickly defining the common reductors, type dispatchers, etc. can be found in toolkit.lisp.

Stack Allocation

Given a suitably good compiler, such as recent SBCL versions, a lot of the 3d-math results can be stack-allocated to avoid triggering GC by declaring them dynamic-extent. Even relatively complex forms can be automatically transformed to stack allocations. To check whether this is successful, you can use sb-ext:stack-allocated-p on the value. In cases where the automatic inference fails or you need more precise control, you should be able to use the plain value constructors such as vec2, declare the variable the result is bound to to be dynamic-extent, and then proceed to use the destructive variants of the various operators such as nv+ or !v+ rather than v+.