diff --git a/docs/vector-library.md b/docs/vector-library.md index 73fe7f8..199fd2f 100644 --- a/docs/vector-library.md +++ b/docs/vector-library.md @@ -14,63 +14,59 @@ The default metatable for vectors should now be the `vector` library. While buff ### Library functions & constants -This RFC proposes the following basic functions & constants as a starting point, but as with all builtin libraries, future RFCs can propose additional functions. +This RFC proposes the following basic functions and constants. ---- +`vector.create(x: number, y: number, z: number): vector` -`vector(x: number, y: number, z: number)` - -Creates a vector with 3 components: x, y, z. If the `LUA_VECTOR_SIZE` configuration option is set to 4, a fourth argument `w: number?` will be introduced. - -Due to the common usage of vectors, vector creation should be ergonomic. Therefore, it is probably worth breaking the `create()` naming standard. +Creates a new vector with the given components. When in 4-wide mode takes a fourth `w` argument. None of the arguments are optional. `vector.magnitude(vec: vector): number` -Calculates the magnitude of a given vector. +Calculates the magnitude of a given vector. When in 4-wide mode, this includes the fourth component. -`vector.normalized(vec: vector): vector` +`vector.normalize(vec: vector): vector` -Returns the normalized version (aka unit vector) of a given vector. +Returns the normalized version (aka unit vector) of a given vector. When in 4-wide mode, this includes the fourth component. `vector.cross(vec1: vector, vec2: vector): vector` -Returns the cross product of two vectors. If 4-wide vectors are enabled, this function will ignore the fourth component, and return the 3-dimensional cross product. +Returns the cross product of two vectors. If 4-wide vectors are enabled, this function will ignore the fourth component and return the 3-dimensional cross product. `vector.dot(vec1: vector, vec2: vector): number` -Returns the dot product of two vectors. - -`vector.floor(vec: vector): vector` - -Equivalent of `math.floor` for vectors. - -`vector.ceil(vec: vector): vector` - -Equivalent of `math.ceil` for vectors. +Returns the dot product of two vectors. Uses all components, even in 4-wide mode. `vector.angle(vec1: vector, vec2: vector, axis: vector?): number` -Returns the angle between two vectors in radians. The axis, if specified, is used to determine the sign of the angle. +Returns the angle between two vectors in radians. The axis, if specified, is used to determine the sign of the angle. If 4-wide vectors are enabled, this function will ignore the fourth component and return the 3-dimensional angle. + +`vector.floor(vec: vector): vector` + +Applies `math.floor` component-wise for each vector. Equivalent of: `vector(math.floor(vec.x), etc)`. + +`vector.ceil(vec: vector): vector` + +Applies `math.ceil` component-wise for each vector. Equivalent of: `vector(math.ceil(vec.x), etc)`. `vector.abs(vec: vector): vector` -Applies math.abs component-wise for each vector. Equivalent of: `vector(math.abs(vec.x), ect)`. +Applies `math.abs` component-wise for each vector. Equivalent of: `vector(math.abs(vec.x), etc)`. `vector.sign(vec: vector): vector` -Applies `math.sign` component-wise for each vector. Equivalent of: `vector(math.sign(vec.x), ect)`. +Applies `math.sign` component-wise for each vector. Equivalent of: `vector(math.sign(vec.x), etc)`. `vector.clamp(vec: vector, min: vector, max: vector): vector` -Applies `math.clamp` component-wise for each vector. Equivalent of: `vector(math.clamp(vec.x, min.x, max.x), ect)`. +Applies `math.clamp` component-wise for each vector. Equivalent of: `vector(math.clamp(vec.x, min.x, max.x), etc)`. `vector.max(...: vector): vector` -Applies `math.max` component-wise for each vector. Equivalent of: `vector(math.max((...).x), ect)`. +Applies `math.max` component-wise for each vector. Equivalent of: `vector(math.max((...).x), etc)`. `vector.min(...: vector): vector` -Applies `math.min` component-wise for each vector. Equivalent of: `vector(math.min((...).x), ect)`. +Applies `math.min` component-wise for each vector. Equivalent of: `vector(math.min((...).x), etc)`. --- @@ -84,16 +80,6 @@ Vector where `x=1, y=1, z=1, w?=1`. --- -### Buffer Library - -`buffer.writevector(b: buffer, offset: number, vec: vector)` - -Writes the vector into the buffer at the offset. Each component will be written as a f32. In four component mode, it will write all four components and write 16 bytes. In three component mode, it will write 12 bytes. - -`buffer.readvector(b: buffer, offset: number): vector` - -Reads a vector from the buffer at the offset. In four component mode it will read 16 bytes and in three component mode it will read 12 bytes. - ### Arithmetic operations Primitive operators for vectors are already implemented, so this RFC doesn't concern vector arithmetic. @@ -106,6 +92,12 @@ Currently, there are 2 compiler options relating to vectors, `vectorLib` & `vect A new primitive `vector` type should be added to the type system. +## Future Work + +A better vector constructor with new syntax, such as `` or `(x, y, z)` or `|x, y, z|` or `vector(x, y, z)` or `[x, y, z]` could be implemented. This would make code that does stuff with vectors much less verbose. + +The buffer library could include functions to work with vectors, such as `buffer.writevector2`, `buffer.writevector3`, and in 4-wide mode, `buffer.writevector4`. The corrosponding read functions would of course be included. + ## Drawbacks As per all additional globals, this creates a new global `vector`. This is a commonly used variable name, and many style guides will advise to avoid using `vector` as a variable name due to the global being added. @@ -120,9 +112,7 @@ Do nothing; vectors have an internal constructor, which lets the runtime impleme ### Alternative implementations -A more standard alternative to `vector(...)` could be something like `vector.create` or `vector.new`. This follows the standard set by `buffer.create`, `coroutine.create`, and `table.create`, and doesn't involve calling a table, which requires a metatable with `__call` to be set on the library. This breaks the standard previously set by Lua, as there is currently no library with a metatable set by default. - -Another alternative to vector creation is special syntax for creating buffers, such as ``, or `[x, y, z]`. This would require a lot more complexity & discussion, however it would fall more in line with the other primitive types. +The function `vector.create` could be skipped entirely in favor of syntax for creating vectors. This should not be done because a function for creating vectors will be nice to have no matter what. Instead of `vector.magnitude`, the magnitude could be derived from the vector's coordinates themselves, and be accessed by a property instead of a function. There is a downside to this: all current properties of vectors are hard-coded to the VM, so any new property to vectors requires a lot of additional complexity & changes to the VM to allow for this. A library function, however, would be trivial. An easy and quick workaround to the verbosity would be at the runtime/C API level. It's trivial to set the metatable of vectors to be the vector library: this allows for `vec:magnitude()` without much issue.