Skip to content

Instantly share code, notes, and snippets.

@spotco
Created February 2, 2019 09:55
Show Gist options
  • Select an option

  • Save spotco/90397a2dcb14b6b33204f0e35e95469e to your computer and use it in GitHub Desktop.

Select an option

Save spotco/90397a2dcb14b6b33204f0e35e95469e to your computer and use it in GitHub Desktop.
LVector3Opt.ModuleScript.lua
-- 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