mirror of
https://github.com/Reuh/wirefame.git
synced 2026-01-18 02:23:04 +00:00
170 lines
3.8 KiB
Lua
170 lines
3.8 KiB
Lua
local wirefame = require((...):match("^(.*)%.wirefame%.group$"))
|
|
local model_mt = require((...):match("^(.*)group$").."model")
|
|
local m4, v3, bb3, bs3 = wirefame.m4, wirefame.v3, wirefame.bb3, wirefame.bs3
|
|
local unpack = table.unpack or unpack
|
|
|
|
--- Group methods.
|
|
local group_mt = {
|
|
--- Add a model to the node.
|
|
add = function(self, ...)
|
|
assert(not self.filtered, "can't add to a filtered group")
|
|
for _, m in ipairs({...}) do
|
|
self.n = self.n + 1
|
|
table.insert(self, m)
|
|
if m.parent == nil then
|
|
m.parent = self
|
|
if self.scene then
|
|
m:onAddToScene(self.scene)
|
|
end
|
|
m:setTransform(0, self:updateFinalTransform())
|
|
end
|
|
end
|
|
return self
|
|
end,
|
|
|
|
--- Remove a model from the node.
|
|
remove = function(self, ...)
|
|
assert(not self.filtered, "can't remove from a filtered group")
|
|
for _, m in ipairs({...}) do
|
|
for i=1, self.n do
|
|
if self[i] == m then
|
|
self.n = self.n - 1
|
|
table.remove(self, i)
|
|
m.parent = nil
|
|
if m.scene then
|
|
m:onRemoveFromScene(m.scene)
|
|
end
|
|
return self
|
|
end
|
|
end
|
|
end
|
|
error("can't find model to remove")
|
|
end,
|
|
|
|
--- All these methods and properties of model are present, but operate on the whole group.
|
|
|
|
-- Overwrite some model methods:
|
|
onAddToScene = function(self, scene)
|
|
self.scene = scene
|
|
for i=1, self.n do
|
|
self[i]:onAddToScene(scene)
|
|
end
|
|
end,
|
|
onRemoveFromScene = function(self, scene)
|
|
self.scene = nil
|
|
for i=1, self.n do
|
|
self[i]:onRemoveFromScene(scene)
|
|
end
|
|
end,
|
|
get = function(self, ...)
|
|
local l = {}
|
|
for i=1, self.n do
|
|
local il = self[i]:get(...)
|
|
if #il > 0 then
|
|
table.insert(l, il)
|
|
end
|
|
end
|
|
l.n = #l
|
|
l.filtered = true
|
|
return setmetatable(l, {__index = self, __tostring = self.__tostring})
|
|
end,
|
|
boundingBox = function(self)
|
|
if #self > 0 then
|
|
self:updateFinalTransform()
|
|
local r = self[1]:boundingBox()
|
|
for i=2, self.n do
|
|
r:include(self[i]:boundingBox())
|
|
end
|
|
return r
|
|
else
|
|
return bb3(v3(0,0,0), v3(0,0,0))
|
|
end
|
|
end,
|
|
boundingSphere = function(self)
|
|
if #self > 0 then
|
|
self:updateFinalTransform()
|
|
local r = self[1]:boundingSphere()
|
|
for i=2, self.n do
|
|
r:include(self[i]:boundingSphere())
|
|
end
|
|
return r
|
|
else
|
|
return bs3(v3(0,0,0), 0)
|
|
end
|
|
end,
|
|
initShader = function(self, shader)
|
|
for i=1, self.n do
|
|
self[i]:initShader(shader)
|
|
end
|
|
end,
|
|
sendFinalTransform = function(self, tr)
|
|
if self.filtered then self = getmetatable(self).__index end
|
|
for i=1, self.n do
|
|
self[i]:setTransform(0, tr)
|
|
end
|
|
end,
|
|
setColor = function(self, r, g, b, a) -- apply color to all children
|
|
self.color[1], self.color[2], self.color[3], self.color[4] = r, g, b, a or 1
|
|
for i=1, self.n do
|
|
self[i]:setColor(r, g, b, a)
|
|
end
|
|
return self
|
|
end,
|
|
draw = function(self, shader, transp)
|
|
-- Transparency sort
|
|
if transp then
|
|
if self.color[4] >= 1 then return end
|
|
else
|
|
if self.color[4] < 1 then return end
|
|
end
|
|
|
|
-- Transformation matrix
|
|
self:updateFinalTransform()
|
|
|
|
-- Draw
|
|
for i=1, self.n do
|
|
self[i]:draw(shader, transp)
|
|
end
|
|
end,
|
|
|
|
__tostring = function(self)
|
|
local mt = getmetatable(self)
|
|
setmetatable(self, nil)
|
|
local str = "group: "..(tostring(self):gsub("^table: ", ""))
|
|
setmetatable(self, mt)
|
|
return str
|
|
end
|
|
}
|
|
for k, v in pairs(model_mt) do
|
|
if group_mt[k] == nil then
|
|
group_mt[k] = v
|
|
end
|
|
end
|
|
group_mt.__index = group_mt
|
|
|
|
--- Create a group of models.
|
|
function wirefame.group(t)
|
|
local group = {
|
|
-- Size
|
|
n = 0,
|
|
|
|
-- Tags
|
|
tags = {},
|
|
|
|
-- Group transformation matrices
|
|
transformStack = { n = 1, changed = true, names = {}, [0] = m4.identity(), m4.identity() },
|
|
finalTransform = nil,
|
|
|
|
-- Group color
|
|
color = { wirefame.defaultColor[1], wirefame.defaultColor[2], wirefame.defaultColor[3], wirefame.defaultColor[4] },
|
|
|
|
-- Hierarchy
|
|
parent = nil,
|
|
scene = nil
|
|
}
|
|
|
|
-- Create & return object
|
|
return setmetatable(group, group_mt):add(unpack(t))
|
|
end
|
|
|
|
return group_mt
|