Update vector-library.md

This commit is contained in:
Jack 2024-08-31 17:43:49 -05:00 committed by GitHub
parent f4e728494f
commit df7b31404a
Signed by: DevComp
GPG key ID: B5690EEEBB952194

View file

@ -14,63 +14,59 @@ The default metatable for vectors should now be the `vector` library. While buff
### Library functions & constants ### 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 new vector with the given components. When in 4-wide mode takes a fourth `w` argument. None of the arguments are optional.
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.
`vector.magnitude(vec: vector): number` `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` `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` `vector.dot(vec1: vector, vec2: vector): number`
Returns the dot product of two vectors. Returns the dot product of two vectors. Uses all components, even in 4-wide mode.
`vector.floor(vec: vector): vector`
Equivalent of `math.floor` for vectors.
`vector.ceil(vec: vector): vector`
Equivalent of `math.ceil` for vectors.
`vector.angle(vec1: vector, vec2: vector, axis: vector?): number` `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` `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` `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` `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` `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` `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 ### Arithmetic operations
Primitive operators for vectors are already implemented, so this RFC doesn't concern vector arithmetic. 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. A new primitive `vector` type should be added to the type system.
## Future Work
A better vector constructor with new syntax, such as `<x, y, z>` 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 ## 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. 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 ### 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. 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.
Another alternative to vector creation is special syntax for creating buffers, such as `<x, y, z>`, or `[x, y, z]`. This would require a lot more complexity & discussion, however it would fall more in line with the other primitive types.
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. 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.