vkm

package module
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 5, 2023 License: MIT Imports: 2 Imported by: 7

README

VKM

VKM is a simple vector and matrix math package written in Go, inspired by glm, and targeting 3D graphics programing.

VKM is specifically targeted at 3D graphics and is NOT inteded to be an all-purpose vector math or linear algebra package. It includes some variant types like Pt2 and Vec3 for convenience, but the primary matrix math functions rely on homogenous 3D vectors and points.

While this module can be used in any Go program wanting to work with 3D transformations, it was built to use with go-vk, a Go language binding for the Vulkan graphics API.

Usage

See the GoDoc for the full API.

VKM defines three primary types: Pt, Vec, and Matrix. All three are stored in column-major order and are fundamentally arrays of [4]float32. (Note: this explicitly means static arrays and not slices.)

We use float32, and not Go's default 64-bit floating point type, because Vulkan (generally) uses 32-bit floats on the GPU. As a consequence, and rather than constantly forcing float32 type casts, VKM uses the chewxy/math32 package for float32 operations and constants.

Examples

Create a basic transformation

You can generate a simple tranformation with the NewMat__ variants:

import "github.com/bbredesen/vkm"
// ...
transVec := vkm.NewVec(-1, -2, -3)
transMat := vkm.NewMatTranslate(transVec)

Rotations are measured in radians by default, but each rotation function has a "Deg" variant to use degrees. Rotation angles will scale with the length of the axis vector, so be sure to normalize the vector first:

import "github.com/chewxy/math32"
// ...
axisVec := vkm.NewVec(1, 1, 1).Normalize()
aRotationMat := vkm.NewMatRotate(axisVec, math32.Pi)
Multiply arbitrary matricies and points or vectors

Matrix multiplication happens in the order written when you directly call MultM, MultV, or MultP. The following code has the apparent effect of rotating the world before translating:

transformMat := myTranslationMat.MultM(myRotationMat)
Create a "readable" transformation

Transformations can be chained, as long as you have a matrix to start from. In this example, we apply a translation of -5 in the X direction, rotate around the Y axis by 45 degrees counterclockwise, and then translate by +5 in the X direction:

transVec := NewVec(-5, 0, 0)

m := Identity().
    Translate(transVec).
    RotateYDeg(-45).
    Translate(transVec.Invert())

When written in this form, we apply transformations in the order they are written. In practice, the code is actually right-multiplying each subsequent transformation, as in the previous example.

Performance Optimization TODO

All math in this library is currently writing in pure Go. Performance could benefit from using SIMD extensions on Intel/AMD CPUs, which will require writing those functions in assembly.

Documentation

Overview

Package vkm provides matrix math functions targeted at computer graphics. It was built for use with go-vk (https://github.com/bbredesen/go-vk), but should be appropriate for any graphics API expecting column-major matricies.

All matricies are 4x4. The Vec and Pt types are 4-component, homogenous column vectors. You can directly instantiate them via:

v := Vec{i, j, k, 0}
p := Pt{x, y, z, 1}

but it is recommended instead to call the New... functions to ensure that the fourth component is correctly set.

v := NewVec(i, j, k)
p := NewPt(x, y, z)

Convenience "zero value" functions for the Origin, ZeroVec, and Identity matrix are included.

Additionally, standard transformation matricies are provided. You can either generate the matrix directly:

NewMatTranslate(transVector)

or you can apply a transformation to an existing matrix:

myMat.Translate(transVector)

Note that applied transformations are left-multiplied, so m.Translate(v) = T(v) x m, whereas calling MultM will right-multiply: m.MultM(t) = m x t.

Index

Constants

This section is empty.

Variables

View Source
var ZeroPt = Origin

ZeroPt is a synonym for Origin()

Functions

This section is empty.

Types

type Mat

type Mat [4]Vec

Mat is a column-major 4x4 matrix of float32s. Because it is fundamentally an array of arrays, elements can be directly addressed via double brackets: m[col][row]

func Camera

func Camera(eye Pt, look Vec, up Vec) Mat

Camera creates a view matrix from the provided eye location, pointed along the direction vector. Camera will continue to look "forward" as you move the eye point, while LookAt will change the look direction to continue pointing at the focus point as the eye moves around.

func Identity

func Identity() Mat

Identity returns a 4x4 identity matrix

func InvertedDepthPerspective

func InvertedDepthPerspective(fov, aspect, near, far float32) Mat

InvertedDepthPerspective generates a Vulkan perspective matrix with depth "reversed". This means that you must set DepthCompareOp to vk.COMPARE_OP_GREATER, and clear the depth buffer to zero, instead of one. The reason you might use this perspective over the "standard" perspecvtive matrix is for greater depth precision. Floating point numbers are more precise as you approach 1.0, and the persepctive matrix tends to compress verticies towards the near projection plane, hence closer to 1.0 in the depth buffer.

Parameters for this function have the same meaning as Perspective

func LookAt

func LookAt(eye, focus Pt, up Vec) Mat

LookAt creates a view matrix from the provided eye and focus points, and an up vector. This function does NOT generate a persepctive matrix. Note that LookAt (and all projection helpers in this library) are based on Vulkan's clip space, which differs from OpenGL.

LookAt only orients the view from an arbitrary orientation down the positive Z axis. The up vector does not need to be orthagonal to the eye -> focus vector, but it cannot be parallel. Note that Vulkan's clip space is different than OpenGL: Z increases into the screen, Positive-Y is down the screen, and the clip boundaries are (-1 <= x <= 1, -1 <= y <= 1, 0 <= z <= 1).

func NewMatRotate

func NewMatRotate(axis Vec, theta float32) Mat

NewMatRotate generates a rotation by theta radians around an arbitrary axis. Note that axis is assumed to be a unit vector. The rotation angle will be scaled by the length of the axis vector.

func NewMatRotateDeg

func NewMatRotateDeg(axis Vec, deg float32) Mat

NewMatRotateDeg generates a rotation by deg degrees around an arbitrary axis. Note that axis is assumed to be a unit vector. The rotation angle will be scaled by the length of the axis vector.

func NewMatRotateX

func NewMatRotateX(theta float32) Mat

NewMatRotateX generates a CCW rotation around the X axis by theta radians

func NewMatRotateXDeg

func NewMatRotateXDeg(deg float32) Mat

NewMatRotateXDeg generates a CCW rotation around the X axis by deg degrees

func NewMatRotateY

func NewMatRotateY(theta float32) Mat

NewMatRotateY generates a CCW rotation around the Y axis by theta radians

func NewMatRotateYDeg

func NewMatRotateYDeg(deg float32) Mat

NewMatRotateYDeg generates a CCW rotation around the Y axis by deg degrees

func NewMatRotateZ

func NewMatRotateZ(theta float32) Mat

NewMatRotateZ generates a CCW rotation around the Z axis by theta radians

func NewMatRotateZDeg

func NewMatRotateZDeg(deg float32) Mat

NewMatRotateZDeg generates a CCW rotation around the Z axis by deg degrees

func NewMatScale

func NewMatScale(v Vec) Mat

NewMatScale creates a scaling matrix using v. A negative value on any axis will create a reflection across that axis.

func NewMatTranslate

func NewMatTranslate(v Vec) Mat

NewMatTranslate generates a translation matrix using v. Note that the fourth component of v is ignored and that component of the matrix is set to 1.0

func OrthoProjection

func OrthoProjection(width, height, near, far float32) Mat

Ortho generates an orthogonal projection matrix.

func Perspective

func Perspective(fov, aspect, near, far float32) Mat

Perspective generates a perspective projection matrix for Vulkan. Note that in Vulkan, the standard z clipping space is in the range [0..1], and x/y in the range [-1..1] (or rather -w to +w).

aspect is the ratio of width divided by height

fov is the vertical field of view measured in radians

near and far are the near and far bounds of the frustum

func PerspectiveDeg

func PerspectiveDeg(fovDeg, aspect, near, far float32) Mat

PerspectiveDeg generates a perspective projection matrix. This version accepts the FOV angle in degrees. See Perspective.

func (Mat) ApproximatelyEquals

func (m Mat) ApproximatelyEquals(n Mat, precision float32) bool

ApproximatelyEquals returns true if m and n are equal component-for-component to within `precision`. Use this function if comparing two calculated matrices to determine if they are equal to within a reasonable precision.

func (*Mat) AsBytes

func (m *Mat) AsBytes() []byte

func (Mat) Determinant

func (m Mat) Determinant() float32

func (Mat) Equals

func (m Mat) Equals(n Mat) bool

Equals returns true if m and n are exactly equal. Note that this function does not allow for "approximately equal" conditions, like many floating point comparison functions.

func (Mat) Inverse

func (m Mat) Inverse() Mat

Inverse returns the inverse matrix of m, i.e. the matrix such that m.MultM(m.Inverse()) yields the identity matrix.

func (Mat) MultM

func (m Mat) MultM(n Mat) Mat

MultM performs a matrix multiplication.

func (Mat) MultP

func (m Mat) MultP(v Pt) Pt

MultP computes a matrix multiplication on the provided point

func (Mat) MultV

func (m Mat) MultV(v Vec) Vec

MultV computes a matrix multiplication on the provided vector

func (Mat) Rotate

func (m Mat) Rotate(axis Vec, theta float32) Mat

Rotate applies an arbitrary rotation measured in radian around the provided axis to m and returns the resulting matrix.

func (Mat) RotateDeg

func (m Mat) RotateDeg(axis Vec, deg float32) Mat

RotateDeg applies an arbitrary rotation measured in degrees around the provided axis to m and returns the resulting matrix.

func (Mat) RotateX

func (m Mat) RotateX(theta float32) Mat

RotateX applies a rotation around the X axis to m and returns the resulting matrix.

func (Mat) RotateXDeg

func (m Mat) RotateXDeg(deg float32) Mat

RotateXDeg applies a rotation around the X axis to m and returns the resulting matrix.

func (Mat) RotateY

func (m Mat) RotateY(theta float32) Mat

RotateY applies a rotation around the Y axis to m and returns the resulting matrix.

func (Mat) RotateYDeg

func (m Mat) RotateYDeg(deg float32) Mat

RotateYDeg applies a rotation around the Y axis to m and returns the resulting matrix.

func (Mat) RotateZ

func (m Mat) RotateZ(theta float32) Mat

RotateZ applies a rotation around the Z axis to m and returns the resulting matrix.

func (Mat) RotateZDeg

func (m Mat) RotateZDeg(deg float32) Mat

RotateZDeg applies a rotation around the Z axis to m and returns the resulting matrix.

func (Mat) Scale

func (m Mat) Scale(v Vec) Mat

Scale applies a scale transformation to m and returns the result

func (Mat) Translate

func (m Mat) Translate(v Vec) Mat

Translate applys the translation of v to m and returns the resulting matrix.

func (Mat) Transpose

func (m Mat) Transpose() Mat

Transpose returns the transpose matrix of m.

type Pt

type Pt Vec

Pt represents a homogenous 3d point (x, y, z, and w components)

func AsPt

func AsPt(s []float32) Pt

AsPt onverts a slice of float32 to a Pt. If the slice has more than four elements, only the first four will be copied.

func NewPt

func NewPt(x, y, z float32) Pt

NewPt initilizes a homogenous point using the provided x, y, and z values

func Origin

func Origin() Pt

Origin is the X/Y/Z origin (0,0,0) as a homogenous point

func (Pt) Add

func (p Pt) Add(v Vec) Pt

Add returns the point where p is translated by v

func (Pt) Clone

func (p Pt) Clone() Pt

Clone creates an duplicate copy of a Pt

func (Pt) EqualTo

func (p Pt) EqualTo(q Pt) bool

EqualTo determines if two points are (approximately) equal. If any component differs by more than 0.00001, then the two points are not "equal"

func (Pt) FlattenToXY

func (p Pt) FlattenToXY() Pt2

func (Pt) Homogenize

func (p Pt) Homogenize() Pt

Homogenize on a Pt divides all components by the w coordinate

func (Pt) VecFrom

func (p Pt) VecFrom(q Pt) Vec

VecFrom returns a vector directed to this point, from the specified point q

func (Pt) VecTo

func (p Pt) VecTo(q Pt) Vec

VecTo returns a vector directed from this point to the specified point q

type Pt2

type Pt2 [2]float32

Pt2 is a 2d point (x and y components only), intended for use as texture coordinates.

func NewPt2

func NewPt2(x, y float32) Pt2

NewPt2 initializes a 2D point using the provided values

func Origin2

func Origin2() Pt2

func (Pt2) Add

func (p Pt2) Add(v Vec2) Pt2

func (Pt2) Clone

func (p Pt2) Clone() Pt2

Clone creates an duplicate copy of a Pt2

func (Pt2) Homogenize

func (p Pt2) Homogenize() Pt

Homogenize converts a Pt2 into a Pt, with z set to zero and the w component fixed to 1.0

func (Pt2) VecFrom

func (p Pt2) VecFrom(q Pt2) Vec2

VecFrom returns a vector directed to this point, from the specified point q

func (Pt2) VecTo

func (p Pt2) VecTo(q Pt2) Vec2

type Pt3

type Pt3 Vec3

Pt3 is a 3d point (x, y, and z components)

func NewPt3

func NewPt3(x, y, z float32) Pt3

NewPt3 initializes a 3D point using the provided values.

func Origin3

func Origin3() Pt3

func (Pt3) Add

func (p Pt3) Add(v Vec3) Pt3

func (Pt3) Clone

func (p Pt3) Clone() Pt3

Clone creates an duplicate copy of a Pt3

func (Pt3) Homogenize

func (p Pt3) Homogenize() Pt

Homogenize converts a Pt3 into a Pt, with the w component fixed to 1.0

func (Pt3) VecFrom

func (p Pt3) VecFrom(q Pt3) Vec3

VecFrom returns a vector directed to this point, from the specified point q

func (Pt3) VecTo

func (p Pt3) VecTo(q Pt3) Vec3

type Vec

type Vec [4]float32

Vec represents a homogenous 3d vector (i, j, k, and l components)

func AsVec

func AsVec(s []float32) Vec

AsVec converts a slice of float32 to a Vec. This function does not validate the input in any way, so if the slice has more than four elements, only the first four will be copied. If the slice has less than four elements, the remaining elements in the return value will be zeroes.

func NewVec

func NewVec(i, j, k float32) Vec

NewVec initializes a homogenous vector using the provided i, j, and k values

func UnitVecX

func UnitVecX() Vec

UnitVecX returns a unit vector in the positive X direction

func UnitVecY

func UnitVecY() Vec

UnitVecY returns a unit vector in the positive Y direction

func UnitVecZ

func UnitVecZ() Vec

UnitVecZ returns a unit vector in the positive Z direction

func ZeroVec

func ZeroVec() Vec

ZeroVec returns a homogenous zero vector

func (Vec) Add

func (v Vec) Add(u Vec) Vec

Add returns the sum of two vectors. Note that the w component from the input is ignored, and is clamped to zero on the output.

func (Vec) Clone

func (v Vec) Clone() Vec

Clone creates an duplicate copy of a Vec

func (Vec) Cross

func (v Vec) Cross(u Vec) Vec

Cross returns the cross product of v and u Note that the w component is ignored, though it should be zero for any homogenous vector

func (Vec) Dot

func (v Vec) Dot(u Vec) float32

Dot returns the dot product of v and u. Note that the w component is ignored, though it should be zero for any homogenous vector

func (Vec) Invert

func (v Vec) Invert() Vec

Invert returns a Vec of the same magnitude, pointed in the opposite direction

func (Vec) Length

func (v Vec) Length() float32

Length is the length in 3D space of v. This function calculates a square root, making it relatively expensive. Use Vec.SquareLength instead if you are comparing two vectors, or comparing against a constant length.

func (Vec) Normalize

func (v Vec) Normalize() Vec

Normalize returns a unit vector oriented in the same direction as v.

func (Vec) RotateZ

func (v Vec) RotateZ(theta float32) Vec

func (Vec) Scale

func (v Vec) Scale(factor float32) Vec

func (Vec) SquareLength

func (v Vec) SquareLength() float32

Calculates the dot product of v with itself, equal to the length of the vector squared. This is much more efficient than calling Length() if you are comparing the length of two vectors.

func (Vec) Sub

func (v Vec) Sub(u Vec) Vec

Sub returns the difference between two vectors. Note that the w component from the input is ignored, and is clamped to zero on the output.

type Vec2

type Vec2 [2]float32

Vec2 is a 2d vector (i and j components)

func (Vec2) Add

func (v Vec2) Add(u Vec2) Vec2

Add returns the sum of two vectors

func (Vec2) Dot

func (v Vec2) Dot(u Vec2) float32

func (Vec2) Homogenize

func (v Vec2) Homogenize() Vec

Homogenize converts a Vec2 in to a Vec, with the k and l components fixed to 0.0

func (Vec2) Invert

func (v Vec2) Invert() Vec2

Invert returns a Vec2 of the same magnitude, pointed in the opposite direction

func (Vec2) Length

func (v Vec2) Length() float32

Length is the length of v. This function calculates a square root, making it relatively expensive. Use Vec2.SquareLength instead if you are comparing two vectors, or comparing against a constant length.

func (Vec2) Normalize

func (v Vec2) Normalize() Vec2

func (Vec2) Scale

func (v Vec2) Scale(factor float32) Vec2

func (Vec2) SquareLength

func (v Vec2) SquareLength() float32

func (Vec2) Sub

func (v Vec2) Sub(u Vec2) Vec2

Sub returns the difference between two vectors

type Vec3

type Vec3 [3]float32

Vec3 is a 3d vector (i, j, and k components)

func (Vec3) Add

func (v Vec3) Add(u Vec3) Vec3

Add returns the sum of two vectors

func (Vec3) Dot

func (v Vec3) Dot(u Vec3) float32

func (Vec3) Homogenize

func (v Vec3) Homogenize() Vec

Homogenize converts a Vec3 into a Vec, with the l component fixed to 0.0

func (Vec3) Invert

func (v Vec3) Invert() Vec3

Invert returns a Vec3 of the same magnitude, pointed in the opposite direction

func (Vec3) Length

func (v Vec3) Length() float32

Length is the length in 3D space of v. This function calculates a square root, making it relatively expensive. Use Vec3.SquareLength instead if you are comparing two vectors, or comparing against a constant length.

func (Vec3) Normalize

func (v Vec3) Normalize() Vec3

func (Vec3) Scale

func (v Vec3) Scale(factor float32) Vec3

func (Vec3) SquareLength

func (v Vec3) SquareLength() float32

func (Vec3) Sub

func (v Vec3) Sub(u Vec3) Vec3

Sub returns the difference between two vectors

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL