Libraries and meta classes
From Filter Forge Wiki
Revision as of 11:17, 24 November 2011; view current revision
←Older revision | Newer revision→
←Older revision | Newer revision→
W.I.P.
Neither the forum or the filter library is suitable for publishing general Lua code like functions, meta classes and libraries. Use this wiki section to post the code you want to share. The Common Operations section in the Scripting Tips and Tricks article contains some examples, but these are really just to give a few basic scripting examples; This page is not limited to simple examples.
-- Sphinx.
Contents |
[edit]
About this page
[edit]
Using code
...
[edit]
Adding code
...
[edit]
Modifying code
...
[edit]
Useful functions
...
[edit]
Meta Classes
...
[edit]
Point Class
[edit]
Documentation
[edit]
Code
local point = {}
local point_mt = {}
function point.new(x,y)
return setmetatable({x, y}, point_mt)
end
-- Metatable setup, default operator handling
point_mt.__add = function(a,b)
-- a+b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
-- both ops are tables, assume xy points, e.g. p1 + p2
return setmetatable({a[1] + b[1], a[2] + b[2]}, point_mt)
else
-- op 'b' is a single value, eg: p1 + 3
return setmetatable({a[1] + b, a[2] + b}, point_mt)
end
elseif (tb == "table") then
-- op 'a' is a single value, case: 3 + p1
return setmetatable({a + b[1], a + b[2]}, point_mt)
end
-- no support for other types, let lua take care of errors
end
point_mt.__sub = function(a,b)
-- a-b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] - b[1], a[2] - b[2]}, point_mt)
else
return setmetatable({a[1] - b, a[2] - b}, point_mt)
end
elseif (tb == "table") then
return setmetatable({a - b[1], a - b[2]}, point_mt)
end
end
point_mt.__mul = function(a,b)
-- a*b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] * b[1], a[2] * b[2]}, point_mt)
else
return setmetatable({a[1] * b, a[2] * b}, point_mt)
end
elseif (tb == "table") then
return setmetatable({a * b[1], a * b[2]}, point_mt)
end
end
point_mt.__div = function(a,b)
-- a/b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] / b[1], a[2] / b[2]}, point_mt)
else
-- minor optimization
local r = 1 / b
return setmetatable({a[1] * r, a[2] * r}, point_mt)
end
elseif (tb == "table") then
return setmetatable({a / b[1], a / b[2]}, point_mt)
end
end
point_mt.__mod = function(a,b)
-- a % b == a - math.floor(a/b)*b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] % b[1], a[2] % b[2]}, point_mt)
else
-- minor optimization
local r = 1 / b
return setmetatable({a[1] - math.floor(a[1] * r) * b, a[2] - math.floor(a[2] * r) * b}, point_mt)
end
elseif (tb == "table") then
return setmetatable({a % b[1], a % b[2]}, point_mt)
end
end
point_mt.__unm = function(a)
-- -a
return setmetatable({-a[1], -a[2]}, point_mt)
end
point_mt.__len = function(a)
return 2
end
point_mt.__pow = function(a,b)
-- a^b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] ^ b[1], a[2] ^ b[2]}, point_mt)
else
return setmetatable({a[1] ^ b, a[2] ^ b}, point_mt)
end
elseif (tb == "table") then
return setmetatable({a ^ b[1], a ^ b[2]}, point_mt)
end
end
point_mt.__eq = function (a,b)
-- a = b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return (a[1] == b[1]) and (a[2] == b[2])
else
return (a[1] == b) and (a[2] == b)
end
elseif (tb == "table") then
return (a == b[1]) and (a == b[2])
end
return false
end
point_mt.__le = function (a,b)
-- a <= b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return (a[1] <= b[1]) and (a[2] <= b[2])
else
return (a[1] <= b) and (a[2] <= b)
end
elseif (tb == "table") then
return (a <= b[1]) and (a <= b[2])
end
return false
end
point_mt.__lt = function (a,b)
-- a < b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return (a[1] < b[1]) and (a[2] < b[2])
else
return (a[1] < b) and (a[2] < b)
end
elseif (tb == "table") then
return (a < b[1]) and (a < b[2])
end
return false
end
point_mt.__tostring = function (t)
return "x,y: ".. t[1]..", ".. t[2]
end
-- aux. meta methods -----------
point_mt.methods = {
x = function(t) return t[1] end,
y = function(t) return t[2] end,
length = function(t)
local x,y = t[1], t[2]
return math.sqrt(x*x + y*y)
end,
inverse_length = function(t)
-- 1 / length
local x,y = t[1], t[2]
return (x*x + y*y) ^ -0.5
end,
sum = function(t)
return t[1] + t[2]
end,
average = function(t)
return (t[1] + t[2]) * 0.5
end,
max = function(t)
return math.max(t[1], t[2])
end,
min = function(t)
return math.min(t[1], t[2])
end,
median = function(t)
return (t.min + t.max) * 0.5
end,
normalized = function(t)
-- minor optimization: 1 / sqrt(x) = x^-0.5
local x,y = t[1], t[2]
local l = (x*x + y*y) ^ -0.5
return setmetatable({x * l, y * l}, point_mt)
end,
inverse = function(t)
return setmetatable({1/t[1], 1/t[2]}, point_mt)
end,
swap_xy = function(t)
return setmetatable({t[2], t[1]}, point_mt)
end,
abs = function(t)
return setmetatable({math.abs(t[1]), math.abs(t[2])}, point_mt)
end,
copy = function(t)
return setmetatable({t[1], t[2]}, point_mt)
end
}
point_mt.__index = function (t, k)
return point_mt.methods[k](t)
end
[edit]
Vector Class
[edit]
Documentation
...
[edit]
Code
-- SPHINX - VECTOR CLASS ----------------------------------------------------------
local vector = {}
local vector_mt = {}
function vector.new(x,y,z)
return setmetatable({x,y,z}, vector_mt)
end
function vector.cross_product(v1, v2)
return setmetatable(
{vec1[2] * vec2[3] - vec1[3] * vec2[2];
vec1[3] * vec2[1] - vec1[1] * vec2[3];
vec1[1] * vec2[2] - vec1[2] * vec2[1]}, vector_mt)
end;
function vector.dot_product(v1, v2)
return (v1 * v2).sum
end;
-- Metatable setup, default operator handling
vector_mt.__add = function(a,b)
-- a+b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
-- both ops are tables, assume xyz vectors, e.g. vec1 + vec2
return setmetatable({a[1] + b[1], a[2] + b[2], a[3] + b[3]}, vector_mt)
else
-- op 'b' is a single value, eg: vec1 + 3
return setmetatable({a[1] + b, a[2] + b, a[3] + b}, vector_mt)
end
elseif (tb == "table") then
-- op 'a' is a single value, case: 3 + vec1
return setmetatable({a + b[1], a + b[2], a + b[3]}, vector_mt)
end
-- no support for other types, let lua take care of errors
end
vector_mt.__sub = function(a,b)
-- a-b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] - b[1], a[2] - b[2], a[3] - b[3]}, vector_mt)
else
return setmetatable({a[1] - b, a[2] - b, a[3] - b}, vector_mt)
end
elseif (tb == "table") then
return setmetatable({a - b[1], a - b[2], a - b[3]}, vector_mt)
end
end
vector_mt.__mul = function(a,b)
-- a*b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] * b[1], a[2] * b[2], a[3] * b[3]}, vector_mt)
else
return setmetatable({a[1] * b, a[2] * b, a[3] * b}, vector_mt)
end
elseif (tb == "table") then
return setmetatable({a * b[1], a * b[2], a * b[3]}, vector_mt)
end
end
vector_mt.__div = function(a,b)
-- a/b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] / b[1], a[2] / b[2], a[3] / b[3]}, vector_mt)
else
-- minor optimization
local r = 1 / b
return setmetatable({a[1] * r, a[2] * r, a[3] * r}, vector_mt)
end
elseif (tb == "table") then
return setmetatable({a / b[1], a / b[2], a / b[3]}, vector_mt)
end
end
vector_mt.__mod = function(a,b)
-- a % b == a - math.floor(a/b)*b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] % b[1], a[2] % b[2], a[3] % b[3]}, vector_mt)
else
-- minor optimization
local r = 1 / b
return setmetatable({a[1] - math.floor(a[1] * r) * b,
a[2] - math.floor(a[2] * r) * b,
a[3] - math.floor(a[3] * r) * b}, vector_mt)
end
elseif (tb == "table") then
return setmetatable({a % b[1], a % b[2], a % b[3]}, vector_mt)
end
end
vector_mt.__unm = function(a)
-- -a
return setmetatable({-a[1], -a[2], -a[3]}, vector_mt)
end
vector_mt.__len = function(a)
-- #a
-- we could return length of vector, but # operator is often used in loops, so...
return 3 -- or #a, but length 3 is assumed
end
vector_mt.__pow = function(a,b)
-- a^b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return setmetatable({a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]}, vector_mt)
else
return setmetatable({a[1] ^ b, a[2] ^ b, a[3] ^ b}, vector_mt)
end
elseif (tb == "table") then
return setmetatable({a ^ b[1], a ^ b[2], a ^ b[3]}, vector_mt)
end
end
vector_mt.__eq = function (a,b)
-- a = b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return (a[1] == b[1]) and (a[2] == b[2]) and (a[3] == b[3])
else
return (a[1] == b) and (a[2] == b) and (a[3] == b)
end
elseif (tb == "table") then
return (a == b[1]) and (a == b[2]) and (a == b[3])
end
return false
end
vector_mt.__le = function (a,b)
-- a <= b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return (a[1] <= b[1]) and (a[2] <= b[2]) and (a[3] <= b[3])
else
return (a[1] <= b) and (a[2] <= b) and (a[3] <= b)
end
elseif (tb == "table") then
return (a <= b[1]) and (a <= b[2]) and (a <= b[3])
end
return false
end
vector_mt.__lt = function (a,b)
-- a < b
local ta,tb = type(a), type(b)
if (ta == "table") then
if (tb == "table") then
return (a[1] < b[1]) and (a[2] < b[2]) and (a[3] < b[3])
else
return (a[1] < b) and (a[2] < b) and (a[3] < b)
end
elseif (tb == "table") then
return (a < b[1]) and (a < b[2]) and (a < b[3])
end
return false
end
vector_mt.__tostring = function (t)
return "x,y,z: ".. t[1]..", ".. t[2]..", ".. t[3]
end
-- aux. meta methods -----------
vector_mt.methods = {
x = function(t) return t[1] end,
y = function(t) return t[2] end,
z = function(t) return t[3] end,
r = function(t) return t[1] end,
g = function(t) return t[2] end,
b = function(t) return t[3] end,
length = function(t)
local x,y,z = t[1], t[2], t[3]
return math.sqrt(x*x + y*y + z*z)
end,
inverse_length = function(t)
-- 1 / length
local x,y,z = t[1], t[2], t[3]
return (x*x + y*y + z*z) ^ -0.5
end,
sum = function(t)
return t[1] + t[2] + t[3]
end,
average = function(t)
return (t[1] + t[2] + t[3]) * (1/3)
end,
max = function(t)
return math.max(t[1], t[2], t[3])
end,
min = function(t)
return math.min(t[1], t[2], t[3])
end,
median = function(t)
return (t.min + t.max) * 0.5
end,
normalized = function(t)
-- minor optimization: 1 / sqrt(x) = x^-0.5
local x,y,z = t[1], t[2], t[3]
local l = (x*x + y*y + z*z) ^ -0.5
return setmetatable({x * l, y * l, z * l}, vector_mt)
end,
inverse = function(t)
return setmetatable({1/t[1], 1/t[2], 1/t[3]}, vector_mt)
end,
abs = function(t)
return setmetatable({math.abs(t[1]), math.abs(t[2]), math.abs(t[3])}, vector_mt)
end,
copy = function(t)
return setmetatable({t[1], t[2], t[3]}, vector_mt)
end
}
vector_mt.__index = function (t, k)
return vector_mt.methods[k](t)
end
[edit]
Color Class
[edit]
Documentation
[edit]
Code
...
[edit]
Further reading
[edit]
External Lua scripting resources
[edit]
Filter Forge Help
[edit]
