|
@@ -0,0 +1,136 @@
|
|
|
+Vectors
|
|
|
+===
|
|
|
+
|
|
|
+This is a guide about the different built-in math objects: vectors, matrices, and quaternions. All
|
|
|
+of these will be referred to as "vector objects" or just "vectors". Vectors are useful because they
|
|
|
+can represent a multidimensional quantity (like a 3D position) using just a single value.
|
|
|
+
|
|
|
+```
|
|
|
+-- Without vectors
|
|
|
+function object:update(dt)
|
|
|
+ object.x = object.x + object.vx * dt
|
|
|
+ object.y = object.y + object.vy * dt
|
|
|
+ object.z = object.z + object.vz * dt
|
|
|
+end
|
|
|
+
|
|
|
+-- With vectors
|
|
|
+function object:update(dt)
|
|
|
+ object.position:add(object.velocity * dt)
|
|
|
+end
|
|
|
+```
|
|
|
+
|
|
|
+The following vector types are supported:
|
|
|
+
|
|
|
+- `vec2`
|
|
|
+- `vec3`
|
|
|
+- `vec4`
|
|
|
+- `quat`, a quaternion.
|
|
|
+- `mat4`, a 4D matrix.
|
|
|
+
|
|
|
+Most LÖVR functions that accept positions, orientations, transforms, velocities, etc. also accept
|
|
|
+vector objects, so they can be used interchangeably with numbers:
|
|
|
+
|
|
|
+```
|
|
|
+function lovr.draw()
|
|
|
+ -- position and size are vec3's, rotation is a quat
|
|
|
+ lovr.graphics.box('fill', position, size, rotation)
|
|
|
+end
|
|
|
+```
|
|
|
+
|
|
|
+Temporary vs. Permanent
|
|
|
+---
|
|
|
+
|
|
|
+Vectors can be created in two different ways: **permanent** and **temporary**.
|
|
|
+
|
|
|
+**Permanent** vectors behave like normal LÖVR objects. They are individual objects that are garbage
|
|
|
+collected when no longer needed. They're created using the usual `lovr.math.new<Type>` syntax:
|
|
|
+
|
|
|
+```
|
|
|
+self.position = lovr.math.newVec3(x, y, z)
|
|
|
+```
|
|
|
+
|
|
|
+**Temporary** vectors are created from a shared pool of vector objects. This makes them faster
|
|
|
+because they use temporary memory and do not need to be garbage collected. To make a temporary
|
|
|
+vector, leave off the `new` prefix:
|
|
|
+
|
|
|
+```
|
|
|
+local position = lovr.math.vec3(x, y, z)
|
|
|
+```
|
|
|
+
|
|
|
+As a further shorthand, these vector constructors are placed on the global scope. If you prefer to
|
|
|
+keep the global scope clean, this can be configured using the `t.math.globals` flag in `lovr.conf`.
|
|
|
+
|
|
|
+```
|
|
|
+local position = vec3(x1, y1, z1) + vec3(x2, y2, z2)
|
|
|
+```
|
|
|
+
|
|
|
+Temporary vectors, with all their speed, come with an important restriction: they can only be used
|
|
|
+during the frame in which they were created. Saving them into variables and using them later on
|
|
|
+will throw an error:
|
|
|
+
|
|
|
+```
|
|
|
+local position = vec3(1, 2, 3)
|
|
|
+
|
|
|
+function lovr.update(dt)
|
|
|
+ -- Reusing a temporary vector across frames will error:
|
|
|
+ position:add(vec3(dt))
|
|
|
+end
|
|
|
+```
|
|
|
+
|
|
|
+It's possible to overflow the temporary vector pool. If that happens, `lovr.math.drain` can be used
|
|
|
+to periodically drain the pool, invalidating any existing temporary vectors.
|
|
|
+
|
|
|
+Metamethods
|
|
|
+---
|
|
|
+
|
|
|
+Vectors have metamethods, allowing them to be used using the normal math operators like `+`, `-`,
|
|
|
+`*`, `/`, etc.
|
|
|
+
|
|
|
+```
|
|
|
+print(vec3(2, 4, 6) * .5 + vec3(10, 20, 30))
|
|
|
+```
|
|
|
+
|
|
|
+These metamethods will create new temporary vectors.
|
|
|
+
|
|
|
+Components and Swizzles
|
|
|
+---
|
|
|
+
|
|
|
+The raw components of a vector can be accessed like normal fields:
|
|
|
+
|
|
|
+```
|
|
|
+print(vec3(1, 2, 3).z) --> 3
|
|
|
+print(mat4()[16]) --> 1
|
|
|
+```
|
|
|
+
|
|
|
+Also, multiple fields can be accessed and combined into a new (temporary) vector, called swizzling:
|
|
|
+
|
|
|
+```
|
|
|
+local position = vec3(10, 5, 1)
|
|
|
+print(position.xy) --> vec2(10, 5)
|
|
|
+print(position.xyy) --> vec3(10, 5, 5)
|
|
|
+print(position.zyxz) --> vec4(1, 5, 10, 1)
|
|
|
+```
|
|
|
+
|
|
|
+The following fields are supported for vectors:
|
|
|
+
|
|
|
+- `x`, `y`, `z`, `w`
|
|
|
+- `r`, `g`, `b`, `a`
|
|
|
+- `s`, `t`, `p`, `q`
|
|
|
+
|
|
|
+Quaternions support `x`, `y`, `z`, and `w`.
|
|
|
+
|
|
|
+Matrices use numbers for accessing individual components in "column-major" order.
|
|
|
+
|
|
|
+All fields can also be assigned to.
|
|
|
+
|
|
|
+```
|
|
|
+-- Swap the components of a 2D vector
|
|
|
+v.xy = v.yx
|
|
|
+```
|
|
|
+
|
|
|
+The `unpack` function can be used (on any vector type) to access all of the individual components of
|
|
|
+a vector object. For quaternions you can choose whether you want to unpack the angle/axis
|
|
|
+representation or the raw quaternion components. Similarly, matrices support raw unpacking as well
|
|
|
+as decomposition into translation/scale/rotation values.
|
|
|
+
|
|
|
+See `lovr.math` for the detailed API reference pages for the different vector types.
|