Created
February 2, 2019 09:55
-
-
Save spotco/90397a2dcb14b6b33204f0e35e95469e to your computer and use it in GitHub Desktop.
LVector3Opt.ModuleScript.lua
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- LVector3 class | |
| local TYPE_LVECTOR3 = "LVector3" | |
| local LVector3 = { | |
| __type = TYPE_LVECTOR3, | |
| TYPE_LVECTOR3 = TYPE_LVECTOR3 | |
| }; | |
| local mt = {__index = LVector3}; | |
| -- built-in functions | |
| local sqrt = math.sqrt; | |
| local acos = math.acos; | |
| local cos = math.cos; | |
| local sin = math.sin; | |
| -- meta-methods | |
| function mt.__eq(a, b) | |
| return a.X == b.X and a.Y == b.Y and a.Z == b.Z; | |
| end | |
| function mt.__add(a, b) | |
| local rtv = LVector3.new() | |
| rtv:store_add_result(a,b) | |
| return rtv | |
| end; | |
| function mt.__sub(a, b) | |
| local rtv = LVector3.new(); | |
| rtv:store_sub_result(a,b); | |
| return rtv; | |
| end; | |
| function mt.__mul(a, b) | |
| if (type(a) == "number") then | |
| return LVector3.new(a * b.X, a * b.Y, a * b.Z); | |
| elseif (type(b) == "number") then | |
| return LVector3.new(a.X * b, a.Y * b, a.Z * b); | |
| elseif (a.__type and a.__type == TYPE_LVECTOR3 and b.__type and b.__type == TYPE_LVECTOR3) then | |
| return LVector3.new(a.X * b.X, a.Y * b.Y, a.Z * b.Z); | |
| else | |
| error("attempt to multiply a LVector3 with an incompatible value type or nil"); | |
| end; | |
| end; | |
| function mt.__div(a, b) | |
| if (type(a) == "number") then | |
| return LVector3.new(a / b.X, a / b.Y, a / b.Z); | |
| elseif (type(b) == "number") then | |
| return LVector3.new(a.X / b, a.Y / b, a.Z / b); | |
| elseif (a.__type and a.__type == TYPE_LVECTOR3 and b.__type and b.__type == TYPE_LVECTOR3) then | |
| return LVector3.new(a.X / b.X, a.Y / b.Y, a.Z / b.Z); | |
| else | |
| error("attempt to divide a LVector3 with an incompatible value type or nil"); | |
| end; | |
| end; | |
| function mt.__unm(v) | |
| return LVector3.new(-v.X, -v.Y, -v.Z); | |
| end; | |
| function mt.__tostring(v) | |
| return v.X .. ", " .. v.Y .. ", " .. v.Z; | |
| end; | |
| mt.__metatable = false; | |
| -- public class | |
| function LVector3.new(x, y, z) | |
| local self = {}; | |
| self.X = x or 0; | |
| self.Y = y or 0; | |
| self.Z = z or 0; | |
| return setmetatable(self, mt); | |
| end; | |
| function LVector3:Unit() | |
| local rtv = LVector3.new() | |
| return rtv:store_normalized(self); | |
| end | |
| function LVector3:Magnitude() | |
| return sqrt(self.X^2 + self.Y^2 + self.Z^2); | |
| end | |
| --SPCHANGE (new methods) | |
| function LVector3:set(x,y,z) | |
| if x ~= nil then | |
| if typeof(x) ~= "number" then error("x") end | |
| self.X = x | |
| else | |
| self.X = 0 | |
| end | |
| if y ~= nil then | |
| if typeof(y) ~= "number" then error("y") end | |
| self.Y = y | |
| else | |
| self.Y = 0 | |
| end | |
| if z ~= nil then | |
| if typeof(z) ~= "number" then error("z") end | |
| self.Z = z | |
| else | |
| self.Z = 0 | |
| end | |
| return self; | |
| end; | |
| function LVector3:set_zero() | |
| self:set(0,0,0); | |
| end; | |
| function LVector3:to_vector3() | |
| return Vector3.new(self.X, self.Y, self.Z); | |
| end; | |
| function LVector3:from_vector3(vec) | |
| if typeof(vec) == "Vector2" then | |
| return self:set(vec.X, vec.Y, 0) | |
| else | |
| return self:set(vec.X, vec.Y, vec.Z) | |
| end | |
| end; | |
| function LVector3:store_normalized(vec) | |
| local magnitude = sqrt(vec.X^2 + vec.Y^2 + vec.Z^2); | |
| if magnitude > 0 then | |
| return self:set(vec.X / magnitude, vec.Y / magnitude, vec.Z / magnitude); | |
| else | |
| -- avoid 'nan' case | |
| return self:set(0, 0, 0); | |
| end; | |
| end; | |
| function LVector3:scale(sf) | |
| self.X = self.X * sf | |
| self.Y = self.Y * sf | |
| self.Z = self.Z * sf | |
| return self | |
| end; | |
| local _cached_store_lerp = nil | |
| function LVector3:store_lerp_result(a, b, t) | |
| if _cached_store_lerp == nil then _cached_store_lerp = LVector3.new() end | |
| _cached_store_lerp:store_sub_result(b,a) | |
| _cached_store_lerp:scale(t) | |
| self:store_add_result(a, _cached_store_lerp) | |
| return self | |
| end | |
| function LVector3:store_cross_result(a,b) | |
| self:set( | |
| a.Y * b.Z - a.Z * b.Y, | |
| a.Z * b.X - a.X * b.Z, | |
| a.X * b.Y - a.Y * b.X | |
| ); | |
| return self; | |
| end | |
| function LVector3:store_add_result(a, b) | |
| return self:set(a.X + b.X, a.Y + b.Y, a.Z + b.Z); | |
| end | |
| function LVector3:store_sub_result(a, b) | |
| return self:set(a.X - b.X, a.Y - b.Y, a.Z - b.Z); | |
| end | |
| function LVector3:Lerp(v3, t) | |
| local rtv = LVector3.new() | |
| rtv:store_lerp_result(self, v3, t) | |
| return rtv | |
| end; | |
| function LVector3:Dot(v3) | |
| return self.X * v3.X + self.Y * v3.Y + self.Z * v3.Z; | |
| end; | |
| function LVector3:Cross(v3) | |
| local rtv = LVector3.new(); | |
| rtv:store_cross_result(self, v3); | |
| return rtv; | |
| end; | |
| return LVector3; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment