mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-27 17:43:53 +01:00
f32d8588e0
Together, these classes provide a way to represent a mesh of faces generated from the Minetest world. This way, the generation of a mesh can be abstracted away from any potential output file writers, thereby allowing for multiple different output file formats to be supported.
100 lines
3.1 KiB
Lua
100 lines
3.1 KiB
Lua
local wea = worldeditadditions
|
|
|
|
|
|
-- ███████ █████ ██████ ███████
|
|
-- ██ ██ ██ ██ ██
|
|
-- █████ ███████ ██ █████
|
|
-- ██ ██ ██ ██ ██
|
|
-- ██ ██ ██ ██████ ███████
|
|
|
|
--- A single face of a Mesh.
|
|
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.
|
|
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
|
|
|
|
|
|
if worldeditadditions then
|
|
worldeditadditions.Face = Face
|
|
worldeditadditions.Mesh = Mesh
|
|
else
|
|
return {
|
|
Face = Face,
|
|
Mesh = Mesh
|
|
}
|
|
end
|