From 492cd3027c8e0601a9a46530d4fda51341b32bb8 Mon Sep 17 00:00:00 2001 From: Nikita Kruglickiy Date: Sat, 20 Mar 2021 00:14:24 +0600 Subject: [PATCH] Mesh loader refactor --- koptilnya/libs/table.txt | 19 +++ koptilnya/mesh_loader/builder.txt | 158 +--------------------- koptilnya/mesh_loader/cl_builder.txt | 51 +++++++ koptilnya/mesh_loader/obj_parser.txt | 38 ++++++ koptilnya/mesh_loader/parser.txt | 40 ------ koptilnya/mesh_loader/sv_builder.txt | 76 +++++++++++ koptilnya/mesh_loader_rework/builder2.txt | 109 --------------- koptilnya/mesh_loader_rework/cl_mesh.txt | 3 - koptilnya/mesh_loader_rework/mesh.txt | 17 --- koptilnya/mesh_loader_rework/sv_mesh.txt | 97 ------------- 10 files changed, 190 insertions(+), 418 deletions(-) create mode 100644 koptilnya/libs/table.txt create mode 100644 koptilnya/mesh_loader/cl_builder.txt create mode 100644 koptilnya/mesh_loader/obj_parser.txt delete mode 100644 koptilnya/mesh_loader/parser.txt create mode 100644 koptilnya/mesh_loader/sv_builder.txt delete mode 100644 koptilnya/mesh_loader_rework/builder2.txt delete mode 100644 koptilnya/mesh_loader_rework/cl_mesh.txt delete mode 100644 koptilnya/mesh_loader_rework/mesh.txt delete mode 100644 koptilnya/mesh_loader_rework/sv_mesh.txt diff --git a/koptilnya/libs/table.txt b/koptilnya/libs/table.txt new file mode 100644 index 0000000..6d41495 --- /dev/null +++ b/koptilnya/libs/table.txt @@ -0,0 +1,19 @@ +function table.chunk(tbl, size) + size = size or 1 + size = size > 0 and size or 1 + + local result = {} + local tblKeys = table.getKeys(tbl) + + for k, v in pairs(tblKeys) do + local chunkId = math.ceil(k / size) + + if not result[chunkId] then + result[chunkId] = {} + end + + result[chunkId][v] = tbl[v] + end + + return result +end diff --git a/koptilnya/mesh_loader/builder.txt b/koptilnya/mesh_loader/builder.txt index ebc68af..d4951a2 100644 --- a/koptilnya/mesh_loader/builder.txt +++ b/koptilnya/mesh_loader/builder.txt @@ -1,153 +1,7 @@ -MeshBuilder = class("MeshBuilder") - -function MeshBuilder:initialize(modelPlaceholder, bundleSize, sendDelay) - self.modelPlaceholder = modelPlaceholder or "models/holograms/cube.mdl" - self.bundleSize = bundleSize or 10 - self.sendDelay = sendDelay or 0.5 - - self._objects = {} - self._setups = {} - - if CLIENT then - self._setups = {} - self._meshData = {} - - net.receive("holograms", function(len) - local hasNext = net.readBit() - - while hasNext == 1 do - local key = net.readString() - - net.readEntity(function(ent) - if not self._objects[key] then - local holo = ent:toHologram() - - if self._meshData[key] then - holo:setMesh(self._meshData[key]) - holo:setRenderBounds(Vector(-200), Vector(200)) - end - - self._objects[key] = holo - end - end) - - hasNext = net.readBit() - end - end) - else - net.receive("setups", function(len, ply) - local hasNext = net.readBit() - - while hasNext == 1 do - local key = net.readString() - local pos = net.readVector() - local ang = net.readAngle() - local scale = net.readVector() - local color = net.readColor() - local mat = net.readString() - local parent = net.readEntity() - local relativeTo = net.readEntity() - - if not self._objects[key] then - if isValid(relativeTo) then - pos = relativeTo:localToWorld(pos) - ang = relativeTo:localToWorldAngles(ang) - end - - local holo = holograms.create(pos, ang, self.modelPlaceholder, scale) - holo:setColor(color) - holo:setMaterial(mat) - holo:setParent(parent) - - self._objects[key] = holo - end - - if not self._setups[key] then - self._setups[key] = self._objects[key] - end - - hasNext = net.readBit() - end - - net.start("holograms") - for k, v in pairs(self._setups) do - net.writeBit(1) - net.writeString(k) - net.writeEntity(v) - end - net.writeBit(0) - net.send(ply) - - table.empty(self._setups) - end) - end +-- @include sv_builder.txt +-- @include cl_builder.txt +if SERVER then + require("sv_builder.txt") +else + require("cl_builder.txt") end - -if CLIENT then - function MeshBuilder:setMeshData(meshData) - self._meshData = meshData - end - - function MeshBuilder:setup(key, pos, ang, scale, color, mat, parent, relativeTo) - if not self._objects[key] and not self._setups[key] and self._meshData[key] then - self._setups[key] = { - pos = pos, - ang = ang, - scale = scale, - color = color, - mat = mat, - parent = isValid(parent) and parent or chip(), - relativeTo = isValid(relativeTo) and relativeTo or chip() - } - end - end - - function MeshBuilder:setupAll(pos, ang, scale, color, mat, parent, relativeTo) - for _, v in pairs(table.getKeys(self._meshData)) do - self:setup(v, pos, ang, scale, color, mat, parent) - end - end - - function MeshBuilder:build() - local function sendSetups(setups) - net.start("setups") - for k, v in pairs(setups) do - net.writeBit(1) - net.writeString(k) - net.writeVector(v.pos) - net.writeAngle(v.ang) - net.writeVector(v.scale) - net.writeColor(v.color) - net.writeString(v.mat) - net.writeEntity(v.parent) - net.writeEntity(v.relativeTo) - end - net.writeBit(0) - net.send() - end - - local bundleKeys = table.getKeys(self._setups) - if #bundleKeys > self.bundleSize then - local i = 1 - - timer.create("sendSetups", self.sendDelay, math.ceil(#bundleKeys / self.bundleSize), function() - local from = (i - 1) * self.bundleSize + 1 - local setups = {} - - for _, v in pairs({ unpack(bundleKeys, from, from + self.bundleSize - 1) }) do - setups[v] = self._setups[v] - end - - sendSetups(setups) - - if i < math.ceil(#bundleKeys / self.bundleSize) then - i = i + 1 - else - table.empty(self._setups) - end - end) - else - sendSetups(self._setups) - end - end -end \ No newline at end of file diff --git a/koptilnya/mesh_loader/cl_builder.txt b/koptilnya/mesh_loader/cl_builder.txt new file mode 100644 index 0000000..08fcd35 --- /dev/null +++ b/koptilnya/mesh_loader/cl_builder.txt @@ -0,0 +1,51 @@ +-- @client +-- @include /koptilnya/libs/table.txt +-- @include obj_parser.txt +require("/koptilnya/libs/table.txt") +require("obj_parser.txt") + +MeshBuilder = class("MeshBuilder") + +function MeshBuilder:initialize(link) + self.link = link + self.meshData = {} + + self._objects = {} + self._parser = ObjParser:new(link) + self._parser.onLoaded = function(parser, objData, meshData, usedTriangles) + self.meshData = meshData + + self:_applyMeshes() + end + + net.receive("holograms", function() + local hasNext = net.readBit() + + while hasNext == 1 do + local name = net.readString() + + net.readEntity(function(ent) + local holo = ent:toHologram() + + table.insert(self._objects, {name = name, holo = holo}) + end) + + hasNext = net.readBit() + end + + self:onHologramsReceived(self._objects) + self:_applyMeshes() + end) +end + +function MeshBuilder:_applyMeshes() + for _, v in pairs(self._objects) do + if self.meshData[v.name] ~= nil then + v.holo:setMesh(self.meshData[v.name]) + v.holo:setRenderBounds(Vector(-200), Vector(200)) + end + end +end + +function MeshBuilder:onHologramsReceived(objects) +end diff --git a/koptilnya/mesh_loader/obj_parser.txt b/koptilnya/mesh_loader/obj_parser.txt new file mode 100644 index 0000000..0f66f90 --- /dev/null +++ b/koptilnya/mesh_loader/obj_parser.txt @@ -0,0 +1,38 @@ +-- @client +ObjParser = class("ObjParser") + +local initialChipName = chip():getChipName() +local function setStatus(status) + setName(string.format("%s (%s)", initialChipName, status)) +end + +function ObjParser:initialize(link, maxQuota) + self.maxQuota = maxQuota or 0.75 + + local triangles = mesh.trianglesLeft() + + setStatus("Getting file...") + http.get(link, function(objData) + local loadMesh = coroutine.wrap(function() + self.meshData = mesh.createFromObj(objData, true, true) + + return true + end) + + setStatus("File received, start parsing...") + hook.add("think", "loadingMesh", function() + while quotaAverage() < quotaMax() * self.maxQuota do + if loadMesh() then + setName(initialChipName) + self:onLoaded(objData, self.meshData, triangles - mesh.trianglesLeft()) + hook.remove("think", "loadingMesh") + + return + end + end + end) + end) +end + +function ObjParser:onLoaded(objData, meshData, usedTriangles) +end diff --git a/koptilnya/mesh_loader/parser.txt b/koptilnya/mesh_loader/parser.txt deleted file mode 100644 index 8aa0209..0000000 --- a/koptilnya/mesh_loader/parser.txt +++ /dev/null @@ -1,40 +0,0 @@ -Parser = class("Parser") - -local initialChipName = chip():getChipName() -local function setStatus(status) - setName(string.format("%s (%s)", initialChipName, status)) -end - -function Parser:initialize(link, maxQuota) - if CLIENT then - local triangles = mesh.trianglesLeft() - local createFromObjCoroutine = coroutine.create(function(objData) - self:OnLoaded(objData, mesh.createFromObj(objData, true)) - end) - - setStatus("Getting file...") - http.get(link, function(objData) - local loadMesh = coroutine.wrap(function() - self.meshData = mesh.createFromObj(objData, true) - - return true - end) - - setStatus("File received, start parsing...") - hook.add("think", "loadingMesh", function() - while quotaAverage() < quotaMax() * (maxQuota or 0.75) do - if loadMesh() then - setName(initialChipName) - self:onLoaded(objData, self.meshData, triangles - mesh.trianglesLeft()) - hook.remove("think", "loadingMesh") - - return - end - end - end) - end) - end -end - -function Parser:onLoaded(objData, meshData, usedTriangles) -end \ No newline at end of file diff --git a/koptilnya/mesh_loader/sv_builder.txt b/koptilnya/mesh_loader/sv_builder.txt new file mode 100644 index 0000000..9f6f6ba --- /dev/null +++ b/koptilnya/mesh_loader/sv_builder.txt @@ -0,0 +1,76 @@ +-- @server +MeshBuilder = class("MeshBuilder") + +function MeshBuilder:initialize(link, modelPlaceholder) + self.link = link + self.modelPlaceholder = modelPlaceholder or "models/holograms/cube.mdl" + self.isReady = false + + self._objectsNames = {} + self._objects = {} + + http.get(link, function(response) + for object in string.gmatch(response, "^?\n?o%s([%w_%.%-]+)") do + table.insert(self._objectsNames, object) + end + + self.isReady = true + self:onReady(self._objectsNames) + self:_sendHolograms() + end) + + hook.add("ClientInitialized", "MeshBuilder_ClientInitialized", function(ply) + if self.isReady then + self:_sendHolograms(ply) + end + end) +end + +function MeshBuilder:_sendHolograms(ply) + if #self._objects == 0 then + return + end + + net.start("holograms") + for _, v in pairs(self._objects) do + net.writeBit(1) + net.writeString(v.name) + net.writeEntity(v.holo) + end + net.writeBit(0) + net.send(ply) +end + +function MeshBuilder:onReady(objectsNames) +end + +function MeshBuilder:build(name, pos, ang, scale, color, mat, parent, relativeTo) + if not self.isReady then + throw("Call build methods when builder is ready!") + end + + if isValid(relativeTo) then + pos = relativeTo:localToWorld(pos) + ang = relativeTo:localToWorldAngles(ang) + end + + local holo = holograms.create(pos, ang, self.modelPlaceholder, scale) + holo:setColor(color) + holo:setMaterial(mat) + + if isValid(parent) then + holo:setParent(parent) + end + + table.insert(self._objects, {name = name, holo = holo}) +end + +function MeshBuilder:buildAll(pos, ang, scale, color, mat, parent, relativeTo) + if not self.isReady then + throw("Call build methods when builder is ready!") + end + + for _, v in pairs(self._objectsNames) do + self:build(v, pos, ang, scale, color, mat, parent, relativeTo) + end +end diff --git a/koptilnya/mesh_loader_rework/builder2.txt b/koptilnya/mesh_loader_rework/builder2.txt deleted file mode 100644 index 26f0f37..0000000 --- a/koptilnya/mesh_loader_rework/builder2.txt +++ /dev/null @@ -1,109 +0,0 @@ -local MODEL_PLACEHOLDER = "models/holograms/cube.mdl" - -MeshBuilder = class("MeshBuilder") - -function MeshBuilder:initialize() - self._holograms = {} - - if SERVER then - self._meshObjects = {} - self._setupAllArgs = nil - - net.receive("meshDataSet", function(_, ply) - self._meshObjects = net.readTable() - - if self._setupAllArgs ~= nil then - self:setupAll(unpack(self._setupAllArgs)) - - self._setupAllArgs = nil - end - - net.start("holograms") - for k, v in pairs(self._holograms) do - net.writeBit(1) - net.writeString(k) - net.writeEntity(v) - end - - net.writeBit(0) - net.send(ply) - end) - else - self._meshData = {} - self._hologramsReceived = false - - net.receive("holograms", function() - local hasNext = net.readBit() - - while hasNext == 1 do - local key = net.readString() - - net.readEntity(function(ent) - if not isValid(ent) then return end - - if self._meshData[key] and not self._holograms[key] then - self._holograms[key] = ent:toHologram() - end - end) - - hasNext = net.readBit() - end - - self._hologramsReceived = true - - self:applyMeshes() - end) - end -end - -if SERVER then - function MeshBuilder:setup(key, pos, ang, scale, color, mat, parent, relativeTo) - if isValid(self._holograms[key]) then return end - - if isValid(relativeTo) then - pos = relativeTo:localToWorld(pos) - ang = relativeTo:localToWorldAngles(ang) - end - - local holo = holograms.create(pos, ang, MODEL_PLACEHOLDER, scale) - holo:setColor(color) - holo:setMaterial(mat) - holo:setParent(parent) - - self._meshes[key] = Mesh:new() - self._holograms[key] = holo - - return holo - end - - function MeshBuilder:setupAll(pos, ang, scale, color, mat, parent, relativeTo) - if #self._meshObjects > 0 then - for _, v in pairs(self._meshObjects) do - self:setup(v, pos, ang, scale, color, mat, parent, relativeTo) - end - else - self._setupAllArgs = {pos, ang, scale, color, mat, parent, relativeTo} - end - end -else - function MeshBuilder:setMeshData(meshData) - self._meshData = meshData - - if self._hologramsReceived then - self:applyMeshes() - else - net.start("meshDataSet") - net.writeTable(table.getKeys(meshData)) - net.send() - end - end - - function MeshBuilder:applyMeshes() - for k, v in pairs(self._holograms) do - if isValid(v) then - v:setMesh(self._meshData[k]) - v:setRenderBounds(Vector(-200), Vector(200)) - end - end - end -end \ No newline at end of file diff --git a/koptilnya/mesh_loader_rework/cl_mesh.txt b/koptilnya/mesh_loader_rework/cl_mesh.txt deleted file mode 100644 index 1a409c3..0000000 --- a/koptilnya/mesh_loader_rework/cl_mesh.txt +++ /dev/null @@ -1,3 +0,0 @@ ---@include /koptilnya/libs/utils.txt - -require("/koptilnya/libs/utils.txt") \ No newline at end of file diff --git a/koptilnya/mesh_loader_rework/mesh.txt b/koptilnya/mesh_loader_rework/mesh.txt deleted file mode 100644 index 035c6e6..0000000 --- a/koptilnya/mesh_loader_rework/mesh.txt +++ /dev/null @@ -1,17 +0,0 @@ ---@include /koptilnya/libs/utils.txt ---@include /koptilnya/mesh_loader/sv_mesh.txt - -require("/koptilnya/libs/utils.txt") - -Mesh = class("Mesh") - -accessorFunc(Mesh, "_hologram", "Hologram", nil) - -if SERVER then - require("/koptilnya/mesh_loader/sv_mesh.txt") -else - function Mesh:setData(data) - self:getEntity():setMesh(data) - self:getEntity():setRenderBounds(Vector(-200), Vector(200)) - end -end \ No newline at end of file diff --git a/koptilnya/mesh_loader_rework/sv_mesh.txt b/koptilnya/mesh_loader_rework/sv_mesh.txt deleted file mode 100644 index 09164fc..0000000 --- a/koptilnya/mesh_loader_rework/sv_mesh.txt +++ /dev/null @@ -1,97 +0,0 @@ ---@include /koptilnya/libs/utils.txt - -require("/koptilnya/libs/utils.txt") - -accessorFunc(Mesh, "_relativeTo", "RelativeTo", nil) - -function Mesh:initialize(pos, ang, scale, color, mat, parent, relativeTo) - --create holo - - self:setPos(pos) - self:setAng(ang) - self:setScale(scale) - self:setColor(color) - self:setMaterial(mat) - self:setParent(parent) - self:setRelativeTo(relativeTo) -end - -function Mesh:getPos() - return self:getEntity():getPos() -end - -function Mesh:setPos(pos) - self:getEntity():setPos(pos) -end - -function Mesh:getRelativePos() - if isValid(self:getRelativeTo()) then - return self:getRelativeTo():worldToLocal(self:getPos()) - else - return self:getPos() - end -end - -function Mesh:setRelativePos(pos) - if isValid(self:getRelativeTo()) then - self:setPos(self:getRelativeTo():localToWorld(pos)) - else - self:setPos(pos) - end -end - -function Mesh:getAng() - return self:getEntity():getAng() -end - -function Mesh:setAng(pos) - self:getEntity():setAng(pos) -end - -function Mesh:getRelativeAng() - if isValid(self:getRelativeTo()) then - return self:getRelativeTo():worldToLocalAngles(self:getAng()) - else - return self:getAng() - end -end - -function Mesh:setRelativeAng(ang) - if isValid(self:getRelativeTo()) then - self:setAng(self:getRelativeTo():localToWorldAngles(ang)) - else - self:setAng(ang) - end -end - -function Mesh:getScale() - return self:getEntity():getScale() -end - -function Mesh:setScale(scale) - self:getEntity():setScale(scale) -end - -function Mesh:getColor() - return self:getEntity():getColor() -end - -function Mesh:setColor(color) - self:getEntity():setColor(color) -end - -function Mesh:getMaterial() - return self:getEntity():getMaterial() -end - -function Mesh:setMaterial(material) - self:getEntity():setMaterial(material) -end - -function Mesh:getParent() - return self:getEntity():getParent() -end - -function Mesh:setParent(parent) - self:getEntity():setParent(parent) -end \ No newline at end of file