mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-30 02:43:00 +00:00
93 lines
3 KiB
Lua
93 lines
3 KiB
Lua
local wea = worldeditadditions
|
|
|
|
|
|
-- ███████ █████ ██████ ███████
|
|
-- ██ ██ ██ ██ ██
|
|
-- █████ ███████ ██ █████
|
|
-- ██ ██ ██ ██ ██
|
|
-- ██ ██ ██ ██████ ███████
|
|
|
|
--- A single face of a Mesh.
|
|
-- @class
|
|
local Face = {}
|
|
Face.__index = Face
|
|
|
|
--- Creates a new face from a list of vertices.
|
|
-- The list of vertices should be anti-clockwise.
|
|
-- @param vertices Vector3[] A list of Vector3 vertices that define the face.
|
|
function Face.new(vertices)
|
|
local result = { vertices = vertices }
|
|
setmetatable(result, Face)
|
|
return result
|
|
end
|
|
|
|
--- Determines whether this face is equal to another face or not.
|
|
-- @param a Face The first face to compare.
|
|
-- @param b Face The second face to compare.
|
|
-- @returns bool Whether the 2 faces are equal or not.
|
|
function Face.equal(a, b)
|
|
if #a.vertices ~= #b.vertices then return false end
|
|
for i,vertex in ipairs(a) do
|
|
if vertex ~= b.vertices[i] then return false end
|
|
end
|
|
return true
|
|
end
|
|
function Face.__eq(a, b) return Face.equal(a, b) end
|
|
|
|
|
|
-- ███ ███ ███████ ███████ ██ ██
|
|
-- ████ ████ ██ ██ ██ ██
|
|
-- ██ ████ ██ █████ ███████ ███████
|
|
-- ██ ██ ██ ██ ██ ██ ██
|
|
-- ██ ██ ███████ ███████ ██ ██
|
|
|
|
--- A mesh of faces.
|
|
-- @class
|
|
local Mesh = {}
|
|
Mesh.__index = Mesh
|
|
|
|
--- Creates a new empty mesh object container.
|
|
-- @returns Mesh
|
|
function Mesh.new()
|
|
local result = { faces = {} }
|
|
setmetatable(result, Mesh)
|
|
end
|
|
|
|
--- Adds a face to this mesh.
|
|
-- @param self Mesh The mesh instance to operate on.
|
|
-- @param face Face The face to add.
|
|
-- @returns void
|
|
function Mesh.add_face(self, face)
|
|
table.insert(self.faces, face)
|
|
end
|
|
|
|
--- Deduplicate the list of faces in this Mesh.
|
|
-- Removes all faces that are exactly equal to one another. This reduces the
|
|
-- filesize.
|
|
-- @returns number The number of faces removed.
|
|
function Mesh.dedupe(self)
|
|
-- Find the faces to remove
|
|
local toremove = {}
|
|
for i,face_check in ipairs(self.faces) do
|
|
for j,face_next in ipairs(self.faces) do
|
|
if i ~= j -- If we're not comparing a face to itself...
|
|
and face_check == face_next -- ....and the 2 faces are equal....
|
|
and not wea.table.contains(toremove, j) then -- ...and we haven't already marked it for removal...
|
|
-- Mark it for removal
|
|
table.insert(toremove, j)
|
|
end
|
|
end
|
|
end
|
|
-- Sort the list of indexes marked for removal from largest to smallest
|
|
-- This way, removing smaller items doesn't alter the index of larger ones
|
|
table.sort(toremove, function(a, b) return a > b end)
|
|
|
|
-- Remove the faces marked for removal
|
|
for i, remove_index in ipairs(toremove) do
|
|
table.remove(self.faces, remove_index)
|
|
end
|
|
return #toremove
|
|
end
|
|
|
|
|
|
return Mesh, Face
|