From 54e412b118494bcd3e01683668d6313593d08580 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 07:11:46 +0300 Subject: [PATCH 01/12] Angle core __index optimizations --- .../gmod_wire_expression2/core/angle.lua | 266 +++++++++--------- 1 file changed, 140 insertions(+), 126 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/angle.lua b/lua/entities/gmod_wire_expression2/core/angle.lua index 19b44def4f..393413ab1c 100644 --- a/lua/entities/gmod_wire_expression2/core/angle.lua +++ b/lua/entities/gmod_wire_expression2/core/angle.lua @@ -1,6 +1,6 @@ -/******************************************************************************\ +--[[ Angle support -\******************************************************************************/ +--]] registerType("angle", "a", Angle(0, 0, 0), nil, @@ -11,9 +11,9 @@ registerType("angle", "a", Angle(0, 0, 0), end ) -local floor, ceil = math.floor, math.ceil +local floor, ceil, clamp = math.floor, math.ceil, math.Clamp -/******************************************************************************/ +-------------------------------------------------------------------------------- __e2setcost(1) -- approximated @@ -33,7 +33,8 @@ end -- Convert Vector -> Angle e2function angle ang(vector rv1) - return Angle(rv1[1], rv1[2], rv1[3]) + local rp1, ry1, rr1 = rv1:Unpack() + return Angle(rp1, ry1, rr1) end e2function number operator_is(angle this) @@ -43,31 +44,31 @@ end __e2setcost(1) e2function number operator>=(angle lhs, angle rhs) - return (lhs[1] >= rhs[1] - and lhs[2] >= rhs[2] - and lhs[3] >= rhs[3]) - and 1 or 0 + local lp, ly, lr = lhs:Unpack() + local rp, ry, rr = rhs:Unpack() + + return lp >= rp and ly >= ry and lr >= rr and 1 or 0 end e2function number operator<=(angle lhs, angle rhs) - return (lhs[1] <= rhs[1] - and lhs[2] <= rhs[2] - and lhs[3] <= rhs[3]) - and 1 or 0 + local lp, ly, lr = lhs:Unpack() + local rp, ry, rr = rhs:Unpack() + + return lp <= rp and ly <= ry and lr <= rr and 1 or 0 end e2function number operator>(angle lhs, angle rhs) - return (lhs[1] > rhs[1] - and lhs[2] > rhs[2] - and lhs[3] > rhs[3]) - and 1 or 0 + local lp, ly, lr = lhs:Unpack() + local rp, ry, rr = rhs:Unpack() + + return lp > rp and ly > ry and lr > rr and 1 or 0 end e2function number operator<(angle lhs, angle rhs) - return (lhs[1] < rhs[1] - and lhs[2] < rhs[2] - and lhs[3] < rhs[3]) - and 1 or 0 + local lp, ly, lr = lhs:Unpack() + local rp, ry, rr = rhs:Unpack() + + return lp < rp and ly < ry and lr < rr and 1 or 0 end __e2setcost(2) @@ -77,11 +78,13 @@ e2function angle operator_neg(angle rv1) end e2function angle operator+(rv1, angle rv2) - return Angle(rv1 + rv2[1], rv1 + rv2[2], rv1 + rv2[3]) + local rp2, ry2, rr2 = rv2:Unpack() + return Angle(rv1 + rp2, rv1 + ry2, rv1 + rr2) end e2function angle operator+(angle rv1, rv2) - return Angle(rv1[1] + rv2, rv1[2] + rv2, rv1[3] + rv2) + local rp1, ry1, rr1 = rv2:Unpack() + return Angle(rp1 + rv2, ry1 + rv2, rr1 + rv2) end e2function angle operator+(angle rv1, angle rv2) @@ -89,11 +92,13 @@ e2function angle operator+(angle rv1, angle rv2) end e2function angle operator-(rv1, angle rv2) - return Angle(rv1 - rv2[1], rv1 - rv2[2], rv1 - rv2[3]) + local rp2, ry2, rr2 = rv2:Unpack() + return Angle(rv1 - rp2, rv1 - ry2, rv1 - rr2) end e2function angle operator-(angle rv1, rv2) - return Angle(rv1[1] - rv2, rv1[2] - rv2, rv1[3] - rv2) + local rp1, ry1, rr1 = rv2:Unpack() + return Angle(rp1 - rv2, ry1 - rv2, rr1 - rv2) end e2function angle operator-(angle rv1, angle rv2) @@ -101,7 +106,7 @@ e2function angle operator-(angle rv1, angle rv2) end e2function angle operator*(angle rv1, angle rv2) - return Angle( rv1[1] * rv2[1], rv1[2] * rv2[2], rv1[3] * rv2[3] ) + return rv1 * rv2 end e2function angle operator*(rv1, angle rv2) @@ -114,37 +119,41 @@ end -- Yes this needs to be in pure lua. Angle/Vector operations in reverse order act as Angle / Number rather than Number / Angle properly. Amazing. e2function angle operator/(rv1, angle rv2) - return Angle( rv1 / rv2[1], rv1 / rv2[2], rv1 / rv2[3] ) + local rp2, ry2, rr2 = rv2:Unpack() + return Angle(rv1 / rp2, rv1 / ry2, rv1 / rr2) end e2function angle operator/(angle rv1, rv2) - return rv1 / rv2 + return rv1 / rv2 end e2function angle operator/(angle rv1, angle rv2) - return Angle( rv1[1] / rv2[1], rv1[2] / rv2[2], rv1[3] / rv2[3] ) + local rp1, ry1, rr1 = rv1:Unpack() + local rp2, ry2, rr2 = rv2:Unpack() + + return Angle(rp1 / rp2, ry1 / ry2, rr1 / rr2) end registerOperator("indexget", "an", "n", function(state, this, index) - return this[floor(math.Clamp(index, 1, 3) + 0.5)] + return this[floor(clamp(index, 1, 3) + 0.5)] end) registerOperator("indexset", "ann", "", function(state, this, index, value) - this[floor(math.Clamp(index, 1, 3) + 0.5)] = value + this[floor(clamp(index, 1, 3) + 0.5)] = value state.GlobalScope.vclk[this] = true end) e2function string operator+(string lhs, angle rhs) self.prf = self.prf + #lhs * 0.01 - return lhs .. ("ang(%g,%g,%g)"):format(rhs[1], rhs[2], rhs[3]) + return lhs .. string.format("ang(%g,%g,%g)", rhs:Unpack()) end e2function string operator+(angle lhs, string rhs) self.prf = self.prf + #rhs * 0.01 - return ("ang(%g,%g,%g)"):format(lhs[1], lhs[2], lhs[3]) .. rhs + return string.format("ang(%g,%g,%g)", rhs:Unpack()) .. rhs end -/******************************************************************************/ +-------------------------------------------------------------------------------- __e2setcost(5) @@ -197,159 +206,163 @@ e2function angle angle:setRoll(rv2) return ang end -/******************************************************************************/ +-------------------------------------------------------------------------------- __e2setcost(5) e2function angle round(angle rv1) - return Angle( - floor(rv1[1] + 0.5), - floor(rv1[2] + 0.5), - floor(rv1[3] + 0.5) - ) + local rp1, ry1, rr1 = rv1:Unpack() + return Angle(floor(rp1 + 0.5), floor(ry1 + 0.5), floor(rr1 + 0.5)) end e2function angle round(angle rv1, decimals) local shf = 10 ^ decimals - return Angle( - floor(rv1[1] * shf + 0.5) / shf, - floor(rv1[2] * shf + 0.5) / shf, - floor(rv1[3] * shf + 0.5) / shf - ) + local rp1, ry1, rr1 = rv1:Unpack() + + return Angle(floor(rp1 * shf + 0.5) / shf, floor(ry1 * shf + 0.5) / shf, floor(rr1 * shf + 0.5) / shf) end e2function angle ceil(angle rv1) - return Angle( - ceil(rv1[1]), - ceil(rv1[2]), - ceil(rv1[3]) - ) + local rp1, ry1, rr1 = rv1:Unpack() + return Angle(ceil(rp1), ceil(ry1), ceil(rr1)) end e2function angle ceil(angle rv1, decimals) local shf = 10 ^ decimals - return Angle( - ceil(rv1[1] * shf) / shf, - ceil(rv1[2] * shf) / shf, - ceil(rv1[3] * shf) / shf - ) + local rp1, ry1, rr1 = rv1:Unpack() + + return Angle(ceil(rp1 * shf) / shf, ceil(ry1 * shf) / shf, ceil(rr1 * shf) / shf) end e2function angle floor(angle rv1) - return Angle( - floor(rv1[1]), - floor(rv1[2]), - floor(rv1[3]) - ) + local rp1, ry1, rr1 = rv1:Unpack() + return Angle(floor(rp1), floor(ry1), floor(rr1)) end e2function angle floor(angle rv1, decimals) local shf = 10 ^ decimals - return Angle( - floor(rv1[1] * shf) / shf, - floor(rv1[2] * shf) / shf, - floor(rv1[3] * shf) / shf - ) + local rp1, ry1, rr1 = rv1:Unpack() + + return Angle(floor(rp1 * shf) / shf, floor(ry1 * shf) / shf, floor(rr1 * shf) / shf) end -- Performs modulo on p,y,r separately e2function angle mod(angle rv1, rv2) - local p,y,r - if rv1[1] >= 0 then - p = rv1[1] % rv2 - else p = rv1[1] % -rv2 end - if rv1[2] >= 0 then - y = rv1[2] % rv2 - else y = rv1[2] % -rv2 end - if rv1[3] >= 0 then - r = rv1[3] % rv2 - else r = rv1[3] % -rv2 end - return Angle(p, y, r) + local rp1, ry1, rr1 = rv1:Unpack() + return Angle(rp1 % (rp1 >= 0 and rv2 or -rv2), ry1 % (ry1 >= 0 and rv2 or -rv2), rr1 % (rr1 >= 0 and rv2 or -rv2)) end -- Modulo where divisors are defined as an angle e2function angle mod(angle rv1, angle rv2) - local p,y,r - if rv1[1] >= 0 then - p = rv1[1] % rv2[1] - else p = rv1[1] % -rv2[1] end - if rv1[2] >= 0 then - y = rv1[2] % rv2[2] - else y = rv1[2] % -rv2[2] end - if rv1[3] >= 0 then - y = rv1[3] % rv2[3] - else y = rv1[3] % -rv2[3] end - return Angle(p, y, r) + local rp1, ry1, rr1 = rv1:Unpack() + local rp2, ry2, rr2 = rv2:Unpack() + + return Angle(rp1 % (rp1 >= 0 and rp2 or -rp2), ry1 % (ry1 >= 0 and ry2 or -ry2), rr1 % (rr1 >= 0 and rr2 or -rr2)) end -- Clamp each p,y,r separately e2function angle clamp(angle rv1, rv2, rv3) - local p,y,r - - if rv1[1] < rv2 then p = rv2 - elseif rv1[1] > rv3 then p = rv3 - else p = rv1[1] end + local p, y, r + local rp1, ry1, rr1 = rv1:Unpack() + + if rp1 < rv2 then + p = rv2 + elseif rp1 > rv3 then + p = rv3 + else + p = rp1 + end - if rv1[2] < rv2 then y = rv2 - elseif rv1[2] > rv3 then y = rv3 - else y = rv1[2] end + if ry1 < rv2 then + y = rv2 + elseif ry1 > rv3 then + y = rv3 + else + y = ry1 + end - if rv1[3] < rv2 then r = rv2 - elseif rv1[3] > rv3 then r = rv3 - else r = rv1[3] end + if rr1 < rv2 then + r = rv2 + elseif rr1 > rv3 then + r = rv3 + else + r = rr1 + end return Angle(p, y, r) end -- Clamp according to limits defined by two min/max angles e2function angle clamp(angle rv1, angle rv2, angle rv3) - local p,y,r - - if rv1[1] < rv2[1] then p = rv2[1] - elseif rv1[1] > rv3[1] then p = rv3[1] - else p = rv1[1] end + local p, y, r + local rp1, ry1, rr1 = rv1:Unpack() + local rp2, ry2, rr2 = rv2:Unpack() + local rp3, ry3, rr3 = rv3:Unpack() + + if rp1 < rp2 then + p = rp2 + elseif rp1 > rp3 then + p = rp3 + else + p = rp1 + end - if rv1[2] < rv2[2] then y = rv2[2] - elseif rv1[2] > rv3[2] then y = rv3[2] - else y = rv1[2] end + if ry1 < ry2 then + y = ry2 + elseif ry1 > ry3 then + y = ry3 + else + y = ry1 + end - if rv1[3] < rv2[3] then r = rv2[3] - elseif rv1[3] > rv3[3] then r = rv3[3] - else r = rv1[3] end + if rr1 < rr2 then + r = rr2 + elseif rr1 > rr3 then + r = rr3 + else + r = rr1 + end return Angle(p, y, r) end -- Mix two angles by a given proportion (between 0 and 1) e2function angle mix(angle rv1, angle rv2, rv3) - local p = rv1[1] * rv3 + rv2[1] * (1-rv3) - local y = rv1[2] * rv3 + rv2[2] * (1-rv3) - local r = rv1[3] * rv3 + rv2[3] * (1-rv3) - return Angle(p, y, r) + local rp1, ry1, rr1 = rv1:Unpack() + local rp2, ry2, rr2 = rv2:Unpack() + + return Angle(rp1 * rv3 + rp2 * (1 - rv3), ry1 * rv3 + ry2 * (1 - rv3), rr1 * rv3 + rr2 * (1 - rv3)) end __e2setcost(2) -- Circular shift function: shiftr( p,y,r ) = ( r,p,y ) e2function angle shiftR(angle rv1) - return Angle(rv1[3], rv1[1], rv1[2]) + local rp1, ry1, rr1 = rv1:Unpack() + return Angle(rr1, rp1, ry1) end e2function angle shiftL(angle rv1) - return Angle(rv1[2], rv1[3], rv1[1]) + local rp1, ry1, rr1 = rv1:Unpack() + return Angle(ry1, rr1, rp1) end __e2setcost(5) -- Returns 1 if the angle lies between (or is equal to) the min/max angles e2function normal inrange(angle rv1, angle rv2, angle rv3) - if rv1[1] < rv2[1] then return 0 end - if rv1[2] < rv2[2] then return 0 end - if rv1[3] < rv2[3] then return 0 end + local rp1, ry1, rr1 = rv1:Unpack() + local rp2, ry2, rr2 = rv2:Unpack() - if rv1[1] > rv3[1] then return 0 end - if rv1[2] > rv3[2] then return 0 end - if rv1[3] > rv3[3] then return 0 end + if rp1 < rp2 then return 0 end + if ry1 < ry2 then return 0 end + if rr1 < rr2 then return 0 end + + local rp3, ry3, rr3 = rv3:Unpack() + + if rp1 > rp3 then return 0 end + if ry1 > ry3 then return 0 end + if rr1 > rr3 then return 0 end return 1 end @@ -357,7 +370,8 @@ end -- Rotate an angle around a vector by the given number of degrees e2function angle angle:rotateAroundAxis(vector axis, degrees) local ang = Angle(this) - ang:RotateAroundAxis( axis:GetNormalized(), degrees ) + ang:RotateAroundAxis(axis:GetNormalized(), degrees) + return ang end @@ -374,7 +388,7 @@ e2function angle toDeg(angle rv1) return rv1 * rad2deg end -/******************************************************************************/ +-------------------------------------------------------------------------------- e2function vector angle:forward() return this:Forward() @@ -388,8 +402,8 @@ e2function vector angle:up() return this:Up() end -e2function string toString(angle a) - return ("ang(%g,%g,%g)"):format(a[1], a[2], a[3]) +e2function string toString(angle ang) + return string.format("ang(%g,%g,%g)", ang:Unpack()) end -e2function string angle:toString() = e2function string toString(angle a) +e2function string angle:toString() = e2function string toString(angle ang) From e53e3aca4bc54d11204606aead5a4014c2ebb779 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 07:18:22 +0300 Subject: [PATCH 02/12] Fix typo --- lua/entities/gmod_wire_expression2/core/angle.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/angle.lua b/lua/entities/gmod_wire_expression2/core/angle.lua index 393413ab1c..d0568f6401 100644 --- a/lua/entities/gmod_wire_expression2/core/angle.lua +++ b/lua/entities/gmod_wire_expression2/core/angle.lua @@ -83,7 +83,7 @@ e2function angle operator+(rv1, angle rv2) end e2function angle operator+(angle rv1, rv2) - local rp1, ry1, rr1 = rv2:Unpack() + local rp1, ry1, rr1 = rv1:Unpack() return Angle(rp1 + rv2, ry1 + rv2, rr1 + rv2) end @@ -97,7 +97,7 @@ e2function angle operator-(rv1, angle rv2) end e2function angle operator-(angle rv1, rv2) - local rp1, ry1, rr1 = rv2:Unpack() + local rp1, ry1, rr1 = rv1:Unpack() return Angle(rp1 - rv2, ry1 - rv2, rr1 - rv2) end From 2e07f267ec16d54675fe09aee00d1e7b77baf200 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 07:23:53 +0300 Subject: [PATCH 03/12] More typo fixes --- lua/entities/gmod_wire_expression2/core/angle.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/angle.lua b/lua/entities/gmod_wire_expression2/core/angle.lua index d0568f6401..bb6ccb9bb6 100644 --- a/lua/entities/gmod_wire_expression2/core/angle.lua +++ b/lua/entities/gmod_wire_expression2/core/angle.lua @@ -150,7 +150,7 @@ end e2function string operator+(angle lhs, string rhs) self.prf = self.prf + #rhs * 0.01 - return string.format("ang(%g,%g,%g)", rhs:Unpack()) .. rhs + return string.format("ang(%g,%g,%g)", lhs:Unpack()) .. rhs end -------------------------------------------------------------------------------- From 1a7fd2aad0964103aa9929a85c51cb63a22f0b2a Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 07:57:19 +0300 Subject: [PATCH 04/12] Simplify a bit --- lua/entities/gmod_wire_expression2/core/angle.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/angle.lua b/lua/entities/gmod_wire_expression2/core/angle.lua index bb6ccb9bb6..ed10c0e967 100644 --- a/lua/entities/gmod_wire_expression2/core/angle.lua +++ b/lua/entities/gmod_wire_expression2/core/angle.lua @@ -32,9 +32,8 @@ e2function angle ang(rv1, rv2, rv3) end -- Convert Vector -> Angle -e2function angle ang(vector rv1) - local rp1, ry1, rr1 = rv1:Unpack() - return Angle(rp1, ry1, rr1) +e2function angle ang(vector vec) + return Angle(vec:Unpack()) end e2function number operator_is(angle this) From c6b049509cf1c47122431593b02300733aa05ac9 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:17:05 +0300 Subject: [PATCH 05/12] Optimize vector core too --- .../gmod_wire_expression2/core/vector.lua | 391 ++++++++++-------- 1 file changed, 224 insertions(+), 167 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/vector.lua b/lua/entities/gmod_wire_expression2/core/vector.lua index 06a05f2e56..612917d22d 100644 --- a/lua/entities/gmod_wire_expression2/core/vector.lua +++ b/lua/entities/gmod_wire_expression2/core/vector.lua @@ -7,6 +7,7 @@ local Vector = Vector local sqrt = math.sqrt local floor = math.floor local ceil = math.ceil +local clamp = math.Clamp local pi = math.pi local atan2 = math.atan2 local asin = math.asin @@ -67,7 +68,7 @@ end --- Convert Angle -> Vector e2function vector vec(angle ang) - return Vector(ang[1], ang[2], ang[3]) + return Vector(ang:Unpack()) end -------------------------------------------------------------------------------- @@ -85,11 +86,13 @@ e2function vector operator_neg(vector v) end e2function vector operator+(lhs, vector rhs) - return Vector(lhs + rhs[1], lhs + rhs[2], lhs + rhs[3]) + local rx, ry, rz = rhs:Unpack() + return Vector(lhs + rx, lhs + ry, lhs + rz) end e2function vector operator+(vector lhs, rhs) - return Vector(lhs[1] + rhs, lhs[2] + rhs, lhs[3] + rhs) + local lx, ly, lz = lhs:Unpack() + return Vector(lx + rhs, ly + rhs, lz + rhs) end e2function vector operator+(vector lhs, vector rhs) @@ -97,11 +100,13 @@ e2function vector operator+(vector lhs, vector rhs) end e2function vector operator-(lhs, vector rhs) - return Vector(lhs - rhs[1], lhs - rhs[2], lhs - rhs[3]) + local rx, ry, rz = rhs:Unpack() + return Vector(lhs - rx, lhs - ry, lhs - rz) end e2function vector operator-(vector lhs, rhs) - return Vector(lhs[1] - rhs, lhs[2] - rhs, lhs[3] - rhs) + local lx, ly, lz = lhs:Unpack() + return Vector(lx - rhs, ly - rhs, lz - rhs) end e2function vector operator-(vector lhs, vector rhs) @@ -117,12 +122,13 @@ e2function vector operator*(vector lhs, rhs) end e2function vector operator*(vector lhs, vector rhs) - return Vector( lhs[1] * rhs[1], lhs[2] * rhs[2], lhs[3] * rhs[3] ) + return lhs * rhs end -- Yes this needs to be in pure lua. Angle/Vector operations in reverse order act as Angle / Number rather than Number / Angle properly. Amazing. e2function vector operator/(lhs, vector rhs) - return Vector( lhs / rhs[1], lhs / rhs[2], lhs / rhs[3] ) + local rx, ry, rz = rhs:Unpack() + return Vector(lhs / rx, lhs / ry, lhs / rz) end e2function vector operator/(vector lhs, rhs) @@ -130,26 +136,29 @@ e2function vector operator/(vector lhs, rhs) end e2function vector operator/(vector lhs, vector rhs) - return Vector( lhs[1] / rhs[1], lhs[2] / rhs[2], lhs[3] / rhs[3] ) + local lx, ly, lz = lhs:Unpack() + local rx, ry, rz = rhs:Unpack() + + return Vector(lx / rx, ly / ry, lz / rz) end registerOperator("indexget", "vn", "n", function(state, this, index) - return this[floor(math.Clamp(index, 1, 3) + 0.5)] + return this[floor(clamp(index, 1, 3) + 0.5)] end) registerOperator("indexset", "vnn", "", function(state, this, index, value) - this[floor(math.Clamp(index, 1, 3) + 0.5)] = value + this[floor(clamp(index, 1, 3) + 0.5)] = value state.GlobalScope.vclk[this] = true end) e2function string operator+(string lhs, vector rhs) self.prf = self.prf + #lhs * 0.01 - return lhs .. ("vec(%g,%g,%g)"):format(rhs[1], rhs[2], rhs[3]) + return lhs .. string.format("vec(%g,%g,%g)", rhs:Unpack()) end e2function string operator+(vector lhs, string rhs) self.prf = self.prf + #rhs * 0.01 - return ("vec(%g,%g,%g)"):format(lhs[1], lhs[2], lhs[3]) .. rhs + return string.format("vec(%g,%g,%g)", lhs:Unpack()) .. rhs end -------------------------------------------------------------------------------- @@ -197,15 +206,15 @@ __e2setcost(5) --- Returns a random vector with its components between and e2function vector randvec(number min, number max) - local v = Vector() - v:Random(min, max) - return v + return VectorRand(min, max) end --- Returns a random vector between and e2function vector randvec(vector min, vector max) - local minx, miny, minz = min[1], min[2], min[3] - return Vector(minx+random()*(max[1]-minx), miny+random()*(max[2]-miny), minz+random()*(max[3]-minz)) + local minx, miny, minz = min:Unpack() + local maxx, maxy, maxz = max:Unpack() + + return Vector(minx + random() * (maxx - minx), miny + random() * (maxy - miny), minz + random() * (maxz - minz)) end -------------------------------------------------------------------------------- @@ -224,7 +233,7 @@ e2function number vector:distance(vector other) return this:Distance(other) end -e2function number vector:distance2( vector other ) +e2function number vector:distance2(vector other) return this:DistToSqr(other) end @@ -232,26 +241,30 @@ e2function vector vector:normalized() return this:GetNormalized() end -e2function number vector:dot( vector other ) +e2function number vector:dot(vector other) return this:Dot(other) end -e2function vector vector:cross( vector other ) +e2function vector vector:cross(vector other) return this:Cross(other) end __e2setcost(10) --- returns the outer product (tensor product) of two vectors -e2function matrix vector:outerProduct( vector other ) +e2function matrix vector:outerProduct(vector other) + local tx, ty, tz = this:Unpack() + local ox, oy, oz = other:Unpack() + return { - this[1] * this[1], this[1] * other[2], this[1] * other[3], - this[2] * this[1], this[2] * other[2], this[2] * other[3], - this[3] * this[1], this[3] * other[2], this[3] * other[3], + tx * tx, tx * oy, tx * oz, + ty * tx, ty * oy, ty * oz, + tz * tx, tz * oy, tz * oz, } end __e2setcost(15) + e2function vector vector:rotateAroundAxis(vector axis, degrees) local ca, sa = math.cos(degrees*deg2rad), math.sin(degrees*deg2rad) local x,y,z = axis[1], axis[2], axis[3] @@ -265,62 +278,64 @@ end __e2setcost(5) -e2function vector vector:rotate( angle ang ) - local v = Vector(this[1], this[2], this[3]) - v:Rotate(ang) - return v +e2function vector vector:rotate(angle ang) + local vec = Vector(this:Unpack()) + vec:Rotate(ang) + + return vec end -e2function vector vector:rotate( normal pitch, normal yaw, normal roll ) - local v = Vector(this[1], this[2], this[3]) - v:Rotate(Angle(pitch, yaw, roll)) - return v +e2function vector vector:rotate(normal pitch, normal yaw, normal roll) + local vec = Vector(this:Unpack()) + vec:Rotate(Angle(pitch, yaw, roll)) + + return vec end e2function vector2 vector:dehomogenized() - local w = this[3] - if w == 0 then return { this[1], this[2] } end - return { this[1]/w, this[2]/w } + local tx, ty, tz = this:Unpack() + if tz == 0 then return { tx, ty } end + + return { tx / tz, ty / tz } end e2function vector positive(vector rv1) - return Vector( - rv1[1] >= 0 and rv1[1] or -rv1[1], - rv1[2] >= 0 and rv1[2] or -rv1[2], - rv1[3] >= 0 and rv1[3] or -rv1[3] - ) + local rx1, ry1, rz1 = rv1:Unpack() + return Vector(rx1 >= 0 and rx1 or -rx1, ry1 >= 0 and ry1 or -ry1, rz1 >= 0 and rz1 or -rz1) end __e2setcost(3) --- Convert the magnitude of the vector to radians e2function vector toRad(vector rv1) - return Vector(rv1[1] * deg2rad, rv1[2] * deg2rad, rv1[3] * deg2rad) + return rv1 * deg2rad end --- Convert the magnitude of the vector to degrees e2function vector toDeg(vector rv1) - return Vector(rv1[1] * rad2deg, rv1[2] * rad2deg, rv1[3] * rad2deg) + return rv1 * rad2deg end -------------------------------------------------------------------------------- __e2setcost(5) ---- Returns a vector in the same direction as , with a length clamped between (min) and (max) -e2function vector clamp(vector Input, Min, Max) - if Min < 0 then Min = 0 end - local x,y,z = Input[1], Input[2], Input[3] - local length = x*x+y*y+z*z - if length < Min*Min then - length = Min*(length ^ -0.5) -- Min*(length ^ -0.5) <=> Min/sqrt(length) - elseif length > Max*Max then - length = Max*(length ^ -0.5) -- Max*(length ^ -0.5) <=> Max/sqrt(length) +--- Returns a vector in the same direction as , with a length clamped between and +e2function vector clamp(vector vec, min, max) + if min < 0 then min = 0 end + + local x, y, z = vec:Unpack() + local length = x * x + y * y + z * z + + if length < min * min then + length = min * (length ^ -0.5) + elseif length > max * max then + length = max * (length ^ -0.5) else - return Input + return Vector(vec) end - return Vector(x*length, y*length, z*length) + return vec * length end -------------------------------------------------------------------------------- @@ -343,17 +358,26 @@ __e2setcost(2) --- SET method that returns a new vector with x replaced e2function vector vector:setX(x) - return Vector(x, this[2], this[3]) + local vec = Vector(this) + vec.x = x + + return vec end --- SET method that returns a new vector with y replaced e2function vector vector:setY(y) - return Vector(this[1], y, this[3]) + local vec = Vector(this) + vec.y = y + + return vec end --- SET method that returns a new vector with z replaced e2function vector vector:setZ(z) - return Vector(this[1], this[2], z) + local vec = Vector(this) + vec.z = z + + return vec end -------------------------------------------------------------------------------- @@ -361,54 +385,39 @@ end __e2setcost(6) e2function vector round(vector rv1) - return Vector( - floor(rv1[1] + 0.5), - floor(rv1[2] + 0.5), - floor(rv1[3] + 0.5) - ) + local rx1, ry1, rz1 = rv1:Unpack() + return Vector(floor(rx1 + 0.5), floor(ry1 + 0.5), floor(rz1 + 0.5)) end e2function vector round(vector rv1, decimals) local shf = 10 ^ decimals - return Vector( - floor(rv1[1] * shf + 0.5) / shf, - floor(rv1[2] * shf + 0.5) / shf, - floor(rv1[3] * shf + 0.5) / shf - ) + local rx1, ry1, rz1 = rv1:Unpack() + + return Vector(floor(rx1 * shf + 0.5) / shf, floor(ry1 * shf + 0.5) / shf, floor(rz1 * shf + 0.5) / shf) end -e2function vector ceil( vector rv1 ) - return Vector( - ceil(rv1[1]), - ceil(rv1[2]), - ceil(rv1[3]) - ) +e2function vector ceil(vector rv1) + local rx1, ry1, rz1 = rv1:Unpack() + return Vector(ceil(rx1), ceil(ry1), ceil(rz1)) end e2function vector ceil(vector rv1, decimals) local shf = 10 ^ decimals - return Vector ( - ceil(rv1[1] * shf) / shf, - ceil(rv1[2] * shf) / shf, - ceil(rv1[3] * shf) / shf - ) + local rx1, ry1, rz1 = rv1:Unpack() + + return Vector(ceil(rx1 * shf) / shf, ceil(ry1 * shf) / shf, ceil(rz1 * shf) / shf) end e2function vector floor(vector rv1) - return Vector( - floor(rv1[1]), - floor(rv1[2]), - floor(rv1[3]) - ) + local rx1, ry1, rz1 = rv1:Unpack() + return Vector(floor(rx1), floor(ry1), floor(rz1)) end e2function vector floor(vector rv1, decimals) local shf = 10 ^ decimals - return Vector( - floor(rv1[1] * shf) / shf, - floor(rv1[2] * shf) / shf, - floor(rv1[3] * shf) / shf - ) + local rx1, ry1, rz1 = rv1:Unpack() + + return Vector(floor(rx1 * shf) / shf, floor(ry1 * shf) / shf, floor(rz1 * shf) / shf) end __e2setcost(10) @@ -424,54 +433,63 @@ end --- component-wise min/max e2function vector maxVec(vector rv1, vector rv2) - return Vector( - rv1[1] > rv2[1] and rv1[1] or rv2[1], - rv1[2] > rv2[2] and rv1[2] or rv2[2], - rv1[3] > rv2[3] and rv1[3] or rv2[3] - ) + local rx1, ry1, rz1 = rv1:Unpack() + local rx2, ry2, rz2 = rv2:Unpack() + + return Vector(rx1 > rx2 and rx1 or rx2, ry1 > ry2 and ry1 or ry2, rz1 > rz2 and rz1 or rz2) end e2function vector minVec(vector rv1, vector rv2) - return Vector( - rv1[1] < rv2[1] and rv1[1] or rv2[1], - rv1[2] < rv2[2] and rv1[2] or rv2[2], - rv1[3] < rv2[3] and rv1[3] or rv2[3] - ) + local rx1, ry1, rz1 = rv1:Unpack() + local rx2, ry2, rz2 = rv2:Unpack() + + return Vector(rx1 < rx2 and rx1 or rx2, ry1 < ry2 and ry1 or ry2, rz1 < rz2 and rz1 or rz2) end --- Performs modulo on x,y,z separately e2function vector mod(vector rv1, rv2) - return Vector( - rv1[1] >= 0 and rv1[1] % rv2 or rv1[1] % -rv2, - rv1[2] >= 0 and rv1[2] % rv2 or rv1[2] % -rv2, - rv1[3] >= 0 and rv1[3] % rv2 or rv1[3] % -rv2 - ) + local rx1, ry1, rz1 = rv1:Unpack() + return Vector(rx1 % (rx1 >= 0 and rv2 or -rv2), ry1 % (ry1 >= 0 and rv2 or -rv2), rz1 % (rz1 >= 0 and rv2 or -rv2)) end --- Modulo where divisors are defined as a vector e2function vector mod(vector rv1, vector rv2) - return Vector( - rv1[1] >= 0 and rv1[1] % rv2[1] or rv1[1] % -rv2[1], - rv1[2] >= 0 and rv1[2] % rv2[2] or rv1[2] % -rv2[2], - rv1[3] >= 0 and rv1[3] % rv2[3] or rv1[3] % -rv2[3] - ) + local rx1, ry1, rz1 = rv1:Unpack() + local rx2, ry2, rz2 = rv2:Unpack() + + return Vector(rx1 % (rx1 >= 0 and rx2 or -rx2), ry1 % (ry1 >= 0 and ry2 or -ry2), rz1 % (rz1 >= 0 and rz2 or -rz2)) end --- Clamp according to limits defined by two min/max vectors e2function vector clamp(vector value, vector min, vector max) - local x,y,z - - if value[1] < min[1] then x = min[1] - elseif value[1] > max[1] then x = max[1] - else x = value[1] end + local x, y, z + local rx1, ry1, rz1 = value:Unpack() + local rx2, ry2, rz2 = min:Unpack() + local rx3, ry3, rz3 = max:Unpack() + + if rx1 < rx2 then + p = rx2 + elseif rx1 > rx3 then + p = rx3 + else + p = rx1 + end - if value[2] < min[2] then y = min[2] - elseif value[2] > max[2] then y = max[2] - else y = value[2] end + if ry1 < ry2 then + y = ry2 + elseif ry1 > ry3 then + y = ry3 + else + y = ry1 + end - if value[3] < min[3] then z = min[3] - elseif value[3] > max[3] then z = max[3] - else z = value[3] end + if rz1 < rz2 then + r = rz2 + elseif rz1 > rz3 then + r = rz3 + else + r = rz1 + end return Vector(x, y, z) end @@ -497,25 +515,32 @@ __e2setcost(2) --- Circular shift function: shiftR(vec(x,y,z)) = vec(z,x,y) e2function vector shiftR(vector vec) - return Vector(vec[3], vec[1], vec[2]) + local x, y, z = vec:Unpack() + return Vector(z, x, y) end --- Circular shift function: shiftL(vec(x,y,z)) = vec(y,z,x) e2function vector shiftL(vector vec) - return Vector(vec[2], vec[3], vec[1]) + local x, y, z = vec:Unpack() + return Vector(y, z, x) end __e2setcost(5) --- Returns 1 if the vector lies between (or is equal to) the min/max vectors e2function number inrange(vector vec, vector min, vector max) - if vec[1] < min[1] then return 0 end - if vec[2] < min[2] then return 0 end - if vec[3] < min[3] then return 0 end + local rx1, ry1, rz1 = vec:Unpack() + local rx2, ry2, rz2 = min:Unpack() - if vec[1] > max[1] then return 0 end - if vec[2] > max[2] then return 0 end - if vec[3] > max[3] then return 0 end + if rx1 < rx2 then return 0 end + if ry1 < ry2 then return 0 end + if rz1 < rz2 then return 0 end + + local rx3, ry3, rz3 = max:Unpack() + + if rx1 > rx3 then return 0 end + if ry1 > ry3 then return 0 end + if rz1 > rz3 then return 0 end return 1 end @@ -534,24 +559,52 @@ end -------------------------------------------------------------------------------- -local contents = {} -for k,v in pairs(_G) do - if (k:sub(1,9) == "CONTENTS_") then - contents[v] = k:sub(10):lower() - end -end +local contents = { + [0] = "empty", + [1] = "solid", + [2] = "window", + [4] = "aux", + [8] = "grate", + [16] = "slime", + [32] = "water", + [64] = "blocklos", + [128] = "opaque", + [256] = "testfogvolume", + [512] = "team4", + [1024] = "team3", + [2048] = "team1", + [4096] = "team2", + [8192] = "ignore_nodraw_opaque", + [16384] = "moveable", + [32768] = "areaportal", + [65536] = "playerclip", + [131072] = "monsterclip", + [262144] = "current_0", + [524288] = "current_90", + [1048576] = "current_180", + [2097152] = "current_270", + [4194304] = "current_up", + [8388608] = "current_down", + [16777216] = "origin", + [33554432] = "monster", + [67108864] = "debris", + [134217728] = "detail", + [268435456] = "translucent", + [536870912] = "ladder", + [1073741824] = "hitbox" +} local cachemeta = {} - local cache_parts_array = setmetatable({ [0] = {} }, cachemeta) local cache_lookup_table = setmetatable({ [0] = { empty = true } }, cachemeta) local cache_concatenated_parts = setmetatable({ [0] = "empty" }, cachemeta) -local function generateContents( n ) +local function generateContents(n) local parts_array, lookup_table = {}, {} for i = 0, 30 do local v = bit.lshift(1, i) + if bit.band(n, v) ~= 0 then local name = contents[v] lookup_table[name] = true @@ -560,10 +613,10 @@ local function generateContents( n ) end concatenated_parts = table.concat(parts_array, ",") - cache_parts_array[n] = parts_array cache_lookup_table[n] = lookup_table cache_concatenated_parts[n] = concatenated_parts + return concatenated_parts end @@ -572,27 +625,28 @@ function cachemeta:__index(n) return rawget(self, n) end -__e2setcost( 20 ) +__e2setcost(20) -e2function number pointHasContent( vector point, string has ) - local cont = cache_lookup_table[util.PointContents(Vector(point[1], point[2], point[3]))] +e2function number pointHasContent(vector point, string has) + local contents = cache_lookup_table[util.PointContents(Vector(point[1], point[2], point[3]))] + has = string.lower(string.gsub(has, " ", "_")) - has = has:gsub(" ", "_"):lower() - - for m in has:gmatch("([^,]+),?") do - if cont[m] then return 1 end + for m in string.gmatch(has, "([^,]+),?") do + if contents[m] then + return 1 + end end return 0 end -__e2setcost( 15 ) +__e2setcost(15) -e2function string pointContents( vector point ) +e2function string pointContents(vector point) return cache_concatenated_parts[util.PointContents(point)] end -e2function array pointContentsArray( vector point ) +e2function array pointContentsArray(vector point) return cache_parts_array[util.PointContents(point)] end @@ -601,77 +655,80 @@ end __e2setcost(15) --- Converts a local position/angle to a world position/angle and returns the position -e2function vector toWorld( vector localpos, angle localang, vector worldpos, angle worldang ) +e2function vector toWorld(vector localpos, angle localang, vector worldpos, angle worldang) return LocalToWorld(localpos, localang, worldpos, worldang) end --- Converts a local position/angle to a world position/angle and returns the angle -e2function angle toWorldAng( vector localpos, angle localang, vector worldpos, angle worldang ) +e2function angle toWorldAng(vector localpos, angle localang, vector worldpos, angle worldang) local _, ang = LocalToWorld(localpos, localang, worldpos, worldang) return ang end --- Converts a local position/angle to a world position/angle and returns both in an array -e2function array toWorldPosAng( vector localpos, angle localang, vector worldpos, angle worldang ) +e2function array toWorldPosAng(vector localpos, angle localang, vector worldpos, angle worldang) return { LocalToWorld(localpos,localang,worldpos,worldang) } end --- Converts a world position/angle to a local position/angle and returns the position -e2function vector toLocal( vector localpos, angle localang, vector worldpos, angle worldang ) - return WorldToLocal(localpos,localang,worldpos,worldang) +e2function vector toLocal(vector localpos, angle localang, vector worldpos, angle worldang) + return WorldToLocal(localpos, localang, worldpos, worldang) end --- Converts a world position/angle to a local position/angle and returns the angle -e2function angle toLocalAng( vector localpos, angle localang, vector worldpos, angle worldang ) +e2function angle toLocalAng(vector localpos, angle localang, vector worldpos, angle worldang) local _, ang = WorldToLocal(localpos, localang, worldpos, worldang) return ang end --- Converts a world position/angle to a local position/angle and returns both in an array -e2function array toLocalPosAng( vector localpos, angle localang, vector worldpos, angle worldang ) - local pos, ang = WorldToLocal(localpos,localang,worldpos,worldang) - return {pos, ang} +e2function array toLocalPosAng(vector localpos, angle localang, vector worldpos, angle worldang) + local pos, ang = WorldToLocal(localpos, localang, worldpos, worldang) + return { pos, ang } end -------------------------------------------------------------------------------- -- Credits to Wizard of Ass for bearing(v,a,v) and elevation(v,a,v) -local ANG_ZERO = angle_zero +local angle_zero = angle_zero + e2function number bearing(vector originpos, angle originangle, vector pos) - pos = WorldToLocal(pos, ANG_ZERO, originpos, originangle) + pos = WorldToLocal(pos, angle_zero, originpos, originangle) return rad2deg * -atan2(pos.y, pos.x) end e2function number elevation(vector originpos, angle originangle, vector pos) - pos = WorldToLocal(pos, ANG_ZERO, originpos, originangle) + pos = WorldToLocal(pos, angle_zero, originpos, originangle) + local len = pos:Length() if len < 0 then return 0 end + return rad2deg * asin(pos.z / len) end e2function angle heading(vector originpos,angle originangle, vector pos) - pos = WorldToLocal(pos, ANG_ZERO, originpos, originangle) - - local bearing = rad2deg*-atan2(pos.y, pos.x) + pos = WorldToLocal(pos, angle_zero, originpos, originangle) local len = pos:Length() + local posx, posy, posz = pos:Unpack() + local bearing = rad2deg * -atan2(posy, posx) if len < 0 then return Angle(0, bearing, 0) end - return Angle(rad2deg*asin(pos.z / len), bearing, 0) + + return Angle(rad2deg * asin(posz / len), bearing, 0) end -------------------------------------------------------------------------------- -__e2setcost( 10 ) - +__e2setcost(10) e2function number vector:isInWorld() - if util.IsInWorld(this) then return 1 else return 0 end + return util.IsInWorld(this) and 1 or 0 end -__e2setcost( 5 ) +__e2setcost(5) -e2function string toString(vector v) - return ("vec(%g,%g,%g)"):format(v[1], v[2], v[3]) +e2function string toString(vector vec) + return string.format("vec(%g,%g,%g)", vec:Unpack()) end --- Gets the vector nicely formatted as a string "[X,Y,Z]" From b2c75e4ddb03573a38de328b65260862a9d9f7b3 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:18:40 +0300 Subject: [PATCH 06/12] Lint pass --- lua/entities/gmod_wire_expression2/core/vector.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/vector.lua b/lua/entities/gmod_wire_expression2/core/vector.lua index 612917d22d..dcf0515a0d 100644 --- a/lua/entities/gmod_wire_expression2/core/vector.lua +++ b/lua/entities/gmod_wire_expression2/core/vector.lua @@ -254,7 +254,7 @@ __e2setcost(10) --- returns the outer product (tensor product) of two vectors e2function matrix vector:outerProduct(vector other) local tx, ty, tz = this:Unpack() - local ox, oy, oz = other:Unpack() + local _, oy, oz = other:Unpack() return { tx * tx, tx * oy, tx * oz, From 908e8345a0762e1e8a33e0a48dfb77f5e49ba8b4 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:20:52 +0300 Subject: [PATCH 07/12] More optimizations/cleanups --- lua/entities/gmod_wire_expression2/core/vector.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/vector.lua b/lua/entities/gmod_wire_expression2/core/vector.lua index dcf0515a0d..c2a579b9b7 100644 --- a/lua/entities/gmod_wire_expression2/core/vector.lua +++ b/lua/entities/gmod_wire_expression2/core/vector.lua @@ -628,7 +628,7 @@ end __e2setcost(20) e2function number pointHasContent(vector point, string has) - local contents = cache_lookup_table[util.PointContents(Vector(point[1], point[2], point[3]))] + local contents = cache_lookup_table[util.PointContents(point)] has = string.lower(string.gsub(has, " ", "_")) for m in string.gmatch(has, "([^,]+),?") do @@ -667,7 +667,7 @@ end --- Converts a local position/angle to a world position/angle and returns both in an array e2function array toWorldPosAng(vector localpos, angle localang, vector worldpos, angle worldang) - return { LocalToWorld(localpos,localang,worldpos,worldang) } + return { LocalToWorld(localpos, localang, worldpos, worldang) } end --- Converts a world position/angle to a local position/angle and returns the position From 1caf376e3c7c0d58da4087e5fc1e5bc0e34c9cd3 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:28:04 +0300 Subject: [PATCH 08/12] Small rotateAroundAxis optimization too --- .../gmod_wire_expression2/core/vector.lua | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/vector.lua b/lua/entities/gmod_wire_expression2/core/vector.lua index c2a579b9b7..8c7638c0ba 100644 --- a/lua/entities/gmod_wire_expression2/core/vector.lua +++ b/lua/entities/gmod_wire_expression2/core/vector.lua @@ -9,6 +9,8 @@ local floor = math.floor local ceil = math.ceil local clamp = math.Clamp local pi = math.pi +local cos = math.cos +local sin = math.sin local atan2 = math.atan2 local asin = math.asin local rad2deg = 180 / pi @@ -266,14 +268,18 @@ end __e2setcost(15) e2function vector vector:rotateAroundAxis(vector axis, degrees) - local ca, sa = math.cos(degrees*deg2rad), math.sin(degrees*deg2rad) - local x,y,z = axis[1], axis[2], axis[3] - local length = (x*x+y*y+z*z)^0.5 - x,y,z = x/length, y/length, z/length - - return Vector((ca + (x^2)*(1-ca)) * this[1] + (x*y*(1-ca) - z*sa) * this[2] + (x*z*(1-ca) + y*sa) * this[3], - (y*x*(1-ca) + z*sa) * this[1] + (ca + (y^2)*(1-ca)) * this[2] + (y*z*(1-ca) - x*sa) * this[3], - (z*x*(1-ca) - y*sa) * this[1] + (z*y*(1-ca) + x*sa) * this[2] + (ca + (z^2)*(1-ca)) * this[3]) + local x, y, z = axis:Unpack() + local tx, ty, tz = this:Unpack() + local ca, sa = cos(degrees * deg2rad), sin(degrees * deg2rad) + + local length = (x * x + y * y + z * z) ^ 0.5 + x, y, z = x / length, y / length, z / length + + return Vector( + (ca + (x ^ 2) * (1 - ca)) * tx + (x * y * (1 - ca) - z * sa) * ty + (x * z * (1 - ca) + y * sa) * tz, + (y * x * (1 - ca) + z * sa) * tx + (ca + (y ^ 2) * (1 - ca)) * ty + (y * z * (1 - ca) - x * sa) * tz, + (z * x * (1 - ca) - y * sa) * tx + (z * y * (1 - ca) + x * sa) * ty + (ca + (z ^ 2) * (1 - ca)) * tz + ) end __e2setcost(5) From 87167fdc423d4d6fee1d2c925cfdcee54c361d55 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:28:41 +0300 Subject: [PATCH 09/12] Small fix --- lua/entities/gmod_wire_expression2/core/vector.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/vector.lua b/lua/entities/gmod_wire_expression2/core/vector.lua index 8c7638c0ba..8239589a50 100644 --- a/lua/entities/gmod_wire_expression2/core/vector.lua +++ b/lua/entities/gmod_wire_expression2/core/vector.lua @@ -738,4 +738,4 @@ e2function string toString(vector vec) end --- Gets the vector nicely formatted as a string "[X,Y,Z]" -e2function string vector:toString() = e2function string toString(vector v) +e2function string vector:toString() = e2function string toString(vector vec) From c7314919b47afc42417459268b61158f7ca65dd5 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 21:41:22 +0300 Subject: [PATCH 10/12] Fix vector:outerProduct(vector other) --- .../gmod_wire_expression2/core/vector.lua | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/vector.lua b/lua/entities/gmod_wire_expression2/core/vector.lua index 8239589a50..3c4586a9c8 100644 --- a/lua/entities/gmod_wire_expression2/core/vector.lua +++ b/lua/entities/gmod_wire_expression2/core/vector.lua @@ -256,12 +256,12 @@ __e2setcost(10) --- returns the outer product (tensor product) of two vectors e2function matrix vector:outerProduct(vector other) local tx, ty, tz = this:Unpack() - local _, oy, oz = other:Unpack() + local ox, oy, oz = other:Unpack() return { - tx * tx, tx * oy, tx * oz, - ty * tx, ty * oy, ty * oz, - tz * tx, tz * oy, tz * oz, + tx * ox, tx * oy, tx * oz, + ty * ox, ty * oy, ty * oz, + tz * ox, tz * oy, tz * oz, } end @@ -566,38 +566,38 @@ end -------------------------------------------------------------------------------- local contents = { - [0] = "empty", - [1] = "solid", - [2] = "window", - [4] = "aux", - [8] = "grate", - [16] = "slime", - [32] = "water", - [64] = "blocklos", - [128] = "opaque", - [256] = "testfogvolume", - [512] = "team4", - [1024] = "team3", - [2048] = "team1", - [4096] = "team2", - [8192] = "ignore_nodraw_opaque", - [16384] = "moveable", - [32768] = "areaportal", - [65536] = "playerclip", - [131072] = "monsterclip", - [262144] = "current_0", - [524288] = "current_90", - [1048576] = "current_180", - [2097152] = "current_270", - [4194304] = "current_up", - [8388608] = "current_down", - [16777216] = "origin", - [33554432] = "monster", - [67108864] = "debris", - [134217728] = "detail", - [268435456] = "translucent", - [536870912] = "ladder", - [1073741824] = "hitbox" + [0] = "empty", + [1] = "solid", + [2] = "window", + [4] = "aux", + [8] = "grate", + [16] = "slime", + [32] = "water", + [64] = "blocklos", + [128] = "opaque", + [256] = "testfogvolume", + [512] = "team4", + [1024] = "team3", + [2048] = "team1", + [4096] = "team2", + [8192] = "ignore_nodraw_opaque", + [16384] = "moveable", + [32768] = "areaportal", + [65536] = "playerclip", + [131072] = "monsterclip", + [262144] = "current_0", + [524288] = "current_90", + [1048576] = "current_180", + [2097152] = "current_270", + [4194304] = "current_up", + [8388608] = "current_down", + [16777216] = "origin", + [33554432] = "monster", + [67108864] = "debris", + [134217728] = "detail", + [268435456] = "translucent", + [536870912] = "ladder", + [1073741824] = "hitbox" } local cachemeta = {} From fe952768fabefd152930bc6404245392197257f8 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 16 Jul 2026 21:51:07 +0300 Subject: [PATCH 11/12] Fix other outerProduct functions too --- .../gmod_wire_expression2/core/vector2.lua | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/vector2.lua b/lua/entities/gmod_wire_expression2/core/vector2.lua index c5a7cedf9a..246179ac89 100644 --- a/lua/entities/gmod_wire_expression2/core/vector2.lua +++ b/lua/entities/gmod_wire_expression2/core/vector2.lua @@ -149,8 +149,8 @@ end -- returns the outer product (tensor product) of two vectors e2function matrix vector2:outerProduct(vector2 other) - return { this[1] * this[1], this[1] * other[2], - this[2] * this[1], this[2] * other[2] } + return { this[1] * other[1], this[1] * other[2], + this[2] * other[1], this[2] * other[2] } end e2function vector2 vector2:rotate(number rot) @@ -617,10 +617,10 @@ __e2setcost(15) registerFunction("outerProduct", "xv4:xv4", "xm4", function(self, args) local op1, op2 = args[2], args[3] local rv1, rv2 = op1[1](self, op1), op2[1](self, op2) - return { rv1[1] * rv1[1], rv1[1] * rv2[2], rv1[1] * rv2[3], rv1[1] * rv2[4], - rv1[2] * rv1[1], rv1[2] * rv2[2], rv1[2] * rv2[3], rv1[2] * rv2[4], - rv1[3] * rv1[1], rv1[3] * rv2[2], rv1[3] * rv2[3], rv1[3] * rv2[4], - rv1[4] * rv1[1], rv1[4] * rv2[2], rv1[4] * rv2[3], rv1[4] * rv2[4] } + return { rv1[1] * rv2[1], rv1[1] * rv2[2], rv1[1] * rv2[3], rv1[1] * rv2[4], + rv1[2] * rv2[1], rv1[2] * rv2[2], rv1[2] * rv2[3], rv1[2] * rv2[4], + rv1[3] * rv2[1], rv1[3] * rv2[2], rv1[3] * rv2[3], rv1[3] * rv2[4], + rv1[4] * rv2[1], rv1[4] * rv2[2], rv1[4] * rv2[3], rv1[4] * rv2[4] } end) __e2setcost(7) @@ -799,23 +799,23 @@ end) registerFunction("maxVec", "xv4xv4", "xv4", function(self, args) local op1, op2 = args[2], args[3] local rv1, rv2 = op1[1](self, op1), op2[1](self, op2) - local x, y, z, w + local x, y, z, w if rv1[1] > rv2[1] then x = rv1[1] else x = rv2[1] end - if rv1[2] > rv2[2] then y = rv1[2] else y = rv2[2] end + if rv1[2] > rv2[2] then y = rv1[2] else y = rv2[2] end if rv1[3] > rv2[3] then z = rv1[3] else z = rv2[3] end - if rv1[4] > rv2[4] then w = rv1[4] else w = rv2[4] end - return {x, y, z, w} + if rv1[4] > rv2[4] then w = rv1[4] else w = rv2[4] end + return {x, y, z, w} end) registerFunction("minVec", "xv4xv4", "xv4", function(self, args) local op1, op2 = args[2], args[3] local rv1, rv2 = op1[1](self, op1), op2[1](self, op2) - local x, y, z, w + local x, y, z, w if rv1[1] < rv2[1] then x = rv1[1] else x = rv2[1] end - if rv1[2] < rv2[2] then y = rv1[2] else y = rv2[2] end + if rv1[2] < rv2[2] then y = rv1[2] else y = rv2[2] end if rv1[3] < rv2[3] then z = rv1[3] else z = rv2[3] end - if rv1[4] < rv2[4] then w = rv1[4] else w = rv2[4] end - return {x, y, z, w} + if rv1[4] < rv2[4] then w = rv1[4] else w = rv2[4] end + return {x, y, z, w} end) -- Performs modulo on x, y, z separately From 5cefd33844b55d2612c88b6ffac3d6d5d597ed9f Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Sat, 18 Jul 2026 03:25:16 +0300 Subject: [PATCH 12/12] Replace with enums --- .../gmod_wire_expression2/core/vector.lua | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/vector.lua b/lua/entities/gmod_wire_expression2/core/vector.lua index 3c4586a9c8..18a00bcc24 100644 --- a/lua/entities/gmod_wire_expression2/core/vector.lua +++ b/lua/entities/gmod_wire_expression2/core/vector.lua @@ -566,38 +566,38 @@ end -------------------------------------------------------------------------------- local contents = { - [0] = "empty", - [1] = "solid", - [2] = "window", - [4] = "aux", - [8] = "grate", - [16] = "slime", - [32] = "water", - [64] = "blocklos", - [128] = "opaque", - [256] = "testfogvolume", - [512] = "team4", - [1024] = "team3", - [2048] = "team1", - [4096] = "team2", - [8192] = "ignore_nodraw_opaque", - [16384] = "moveable", - [32768] = "areaportal", - [65536] = "playerclip", - [131072] = "monsterclip", - [262144] = "current_0", - [524288] = "current_90", - [1048576] = "current_180", - [2097152] = "current_270", - [4194304] = "current_up", - [8388608] = "current_down", - [16777216] = "origin", - [33554432] = "monster", - [67108864] = "debris", - [134217728] = "detail", - [268435456] = "translucent", - [536870912] = "ladder", - [1073741824] = "hitbox" + [CONTENTS_EMPTY] = "empty", + [CONTENTS_SOLID] = "solid", + [CONTENTS_WINDOW] = "window", + [CONTENTS_AUX] = "aux", + [CONTENTS_GRATE] = "grate", + [CONTENTS_SLIME] = "slime", + [CONTENTS_WATER] = "water", + [CONTENTS_BLOCKLOS] = "blocklos", + [CONTENTS_OPAQUE] = "opaque", + [CONTENTS_TESTFOGVOLUME] = "testfogvolume", + [CONTENTS_TEAM4] = "team4", + [CONTENTS_TEAM3] = "team3", + [CONTENTS_TEAM1] = "team1", + [CONTENTS_TEAM2] = "team2", + [CONTENTS_IGNORE_NODRAW_OPAQUE] = "ignore_nodraw_opaque", + [CONTENTS_MOVEABLE] = "moveable", + [CONTENTS_AREAPORTAL] = "areaportal", + [CONTENTS_PLAYERCLIP] = "playerclip", + [CONTENTS_MONSTERCLIP] = "monsterclip", + [CONTENTS_CURRENT_0] = "current_0", + [CONTENTS_CURRENT_90] = "current_90", + [CONTENTS_CURRENT_180] = "current_180", + [CONTENTS_CURRENT_270] = "current_270", + [CONTENTS_CURRENT_UP] = "current_up", + [CONTENTS_CURRENT_DOWN] = "current_down", + [CONTENTS_ORIGIN] = "origin", + [CONTENTS_MONSTER] = "monster", + [CONTENTS_DEBRIS] = "debris", + [CONTENTS_DETAIL] = "detail", + [CONTENTS_TRANSLUCENT] = "translucent", + [CONTENTS_LADDER] = "ladder", + [CONTENTS_HITBOX] = "hitbox" } local cachemeta = {}