├── .gitmodules ├── LICENSE ├── README.md ├── lib ├── vec2.lua ├── vec3.lua └── vec4.lua └── main.lua /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocornoc/ggvec/1817395cf414aa68d5a41ab1b59c4db42c0f451f/.gitmodules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Grayson Burton ( https://github.com/ocornoc/ ) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ggvec 2 | 3 | ggvec is a LuaJIT 2D, 3D, and 4D vector library. 4 | 5 | 6 | ## Technical Types 7 | 8 | These are the C types used to internally represent the vectors. 9 | 10 | | Vector type | C type | 11 | |-------------|------------| 12 | | 4D vectors |`struct {float x, y, z, w;}` | 13 | | 3D vectors |`struct {float x, y, z;}` | 14 | | 2D vectors |`struct {double x, y;}` | 15 | 16 | 4D and 3D vectors are only floats so that they can easily fit inside XMM registers. All vectors are 16-byte aligned and all members are packed. 17 | -------------------------------------------------------------------------------- /lib/vec2.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | --------------------------------------------------------------- 4 | 5 | ffi.cdef[[ 6 | struct __attribute__(( aligned(16) )) ggvec2_ct { __attribute__(( packed )) double x, y; }; 7 | ]] 8 | 9 | --------------------------------------------------------------- 10 | 11 | local vec2, vec2_mt 12 | 13 | local scream_in_agony = error 14 | local sqrt, acos, cos, sin = math.sqrt, math.acos, math.cos, math.sin 15 | 16 | vec2_mt = { 17 | __add = function(v1, v2) 18 | return vec2(v1.x + v2.x, v1.y + v2.y) 19 | end, 20 | 21 | __sub = function(v1, v2) 22 | return vec2(v1.x - v2.x, v1.y - v2.y) 23 | end, 24 | 25 | __mul = function(v1, v2) 26 | if type(v2) == "number" or not v2.isVec2 then 27 | return vec2(v1.x * v2, v1.y * v2) 28 | elseif v2.isVec2 then 29 | return v1.x * v2.x + v1.y * v2.y 30 | end 31 | end, 32 | 33 | __div = function(v1, n) 34 | if type(n) == "number" or not n.isVec2 then 35 | return vec2(v1.x / n, v1.y / n) 36 | else 37 | scream_in_agony("Vector divisors must be numbers!") 38 | end 39 | end, 40 | 41 | __len = function(self) 42 | return sqrt(self.x^2 + self.y^2) 43 | end, 44 | 45 | __tostring = function(self) 46 | return "(" .. tostring(self.x) .. ", " .. tostring(self.y) .. ")" 47 | end, 48 | 49 | __eq = function(v1, v2) 50 | return tostring(v1) == tostring(v2) 51 | end, 52 | 53 | __unm = function(self) 54 | return vec2(-self.x, -self.y) 55 | end, 56 | 57 | __index = { 58 | len = function(self) 59 | return #self 60 | end, 61 | 62 | angle_diff = function(v1, v2) 63 | return acos((v1 * v2) / (v1:len() * v2:len())) 64 | end, 65 | 66 | isVec = true, 67 | isVec2 = true, 68 | }, 69 | } 70 | 71 | vec2 = ffi.metatype("struct ggvec2_ct", vec2_mt) 72 | 73 | --------------------------------------------------------------- 74 | 75 | return vec2 76 | -------------------------------------------------------------------------------- /lib/vec3.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | --------------------------------------------------------------- 4 | 5 | ffi.cdef[[ 6 | struct __attribute__(( aligned(16) )) ggvec3_ct { __attribute__(( packed )) float x, y, z; }; 7 | ]] 8 | 9 | --------------------------------------------------------------- 10 | 11 | local vec3, vec3_mt 12 | 13 | local scream_in_agony = error 14 | local sqrt, acos, cos, sin = math.sqrt, math.acos, math.cos, math.sin 15 | 16 | vec3_mt = { 17 | __add = function(v1, v2) 18 | return vec3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z) 19 | end, 20 | 21 | __sub = function(v1, v2) 22 | return vec3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) 23 | end, 24 | 25 | __mul = function(v1, v2) 26 | if type(v2) == "number" or not v2.isVec3 then 27 | return vec3(v1.x * v2, v1.y * v2, v1.z * v2) 28 | elseif v2.isVec3 then 29 | return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z 30 | end 31 | end, 32 | 33 | __div = function(v1, n) 34 | if type(n) == "number" or not n.isVec3 then 35 | return vec3(v1.x / n, v1.y / n, v1.z / n) 36 | else 37 | scream_in_agony("Vector divisors must be numbers!") 38 | end 39 | end, 40 | 41 | __len = function(self) 42 | return sqrt(self.x^2 + self.y^2 + self.z^2) 43 | end, 44 | 45 | __tostring = function(self) 46 | return "(" .. tostring(self.x) .. ", " .. tostring(self.y) .. ", " .. tostring(self.z) .. ")" 47 | end, 48 | 49 | __eq = function(v1, v2) 50 | return tostring(v1) == tostring(v2) 51 | end, 52 | 53 | __unm = function(self) 54 | return vec3(-self.x, -self.y, -self.z) 55 | end, 56 | 57 | __index = { 58 | len = function(self) 59 | return #self 60 | end, 61 | 62 | angle_diff = function(v1, v2) 63 | return acos((v1 * v2) / (v1:len() * v2:len())) 64 | end, 65 | 66 | cross = function(v1, v2) 67 | return vec3((v1.y * v2.z) - (v1.z * v2.y), (v1.z * v2.x) - (v1.x * v2.z), (v1.x * v2.y) - (v1.y * v2.x)) 68 | end, 69 | 70 | isVec = true, 71 | isVec3 = true, 72 | }, 73 | } 74 | 75 | vec3 = ffi.metatype("struct ggvec3_ct", vec3_mt) 76 | 77 | --------------------------------------------------------------- 78 | 79 | return vec3 80 | -------------------------------------------------------------------------------- /lib/vec4.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | --------------------------------------------------------------- 4 | 5 | ffi.cdef[[ 6 | struct __attribute__(( aligned(16) )) ggvec4_ct { __attribute__(( packed )) float x, y, z, w; }; 7 | ]] 8 | 9 | --------------------------------------------------------------- 10 | 11 | local vec4, vec4_mt 12 | 13 | local scream_in_agony = error 14 | local sqrt, acos, cos, sin = math.sqrt, math.acos, math.cos, math.sin 15 | 16 | vec4_mt = { 17 | __add = function(v1, v2) 18 | return vec4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w) 19 | end, 20 | 21 | __sub = function(v1, v2) 22 | return vec4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w) 23 | end, 24 | 25 | __mul = function(v1, v2) 26 | if type(v2) == "number" or not v2.isVec4 then 27 | return vec4(v1.x * v2, v1.y * v2, v1.z * v2, v1.w * v2) 28 | elseif v2.isVec4 then 29 | return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w 30 | end 31 | end, 32 | 33 | __div = function(v1, n) 34 | if type(n) == "number" or not n.isVec4 then 35 | return vec4(v1.x / n, v1.y / n, v1.z / n, v1.w / n) 36 | else 37 | scream_in_agony("Vector divisors must be numbers!") 38 | end 39 | end, 40 | 41 | __len = function(self) 42 | return sqrt(self.x^2 + self.y^2 + self.z^2 + self.w^2) 43 | end, 44 | 45 | __tostring = function(self) 46 | return "(" .. tostring(self.x) .. ", " .. tostring(self.y) .. ", " .. tostring(self.z) .. ", " .. tostring(self.w) .. ")" 47 | end, 48 | 49 | __eq = function(v1, v2) 50 | return tostring(v1) == tostring(v2) 51 | end, 52 | 53 | __unm = function(self) 54 | return vec4(-self.x, -self.y, -self.z, -self.w) 55 | end, 56 | 57 | __index = { 58 | len = function(self) 59 | return #self 60 | end, 61 | 62 | angle_diff = function(v1, v2) 63 | return acos((v1 * v2) / (v1:len() * v2:len())) 64 | end, 65 | 66 | isVec = true, 67 | isVec4 = true, 68 | }, 69 | } 70 | 71 | vec4 = ffi.metatype("struct ggvec4_ct", vec4_mt) 72 | 73 | --------------------------------------------------------------- 74 | 75 | return vec4 76 | -------------------------------------------------------------------------------- /main.lua: -------------------------------------------------------------------------------- 1 | return { 2 | vec2 = require "lib.vec2", 3 | vec3 = require "lib.vec3", 4 | vec4 = require "lib.vec4", 5 | } 6 | --------------------------------------------------------------------------------