A
This commit is contained in:
@@ -1,8 +1,21 @@
|
||||
-- @name koptilnya/mesh_loader/builder
|
||||
-- @include sv_builder.txt
|
||||
-- @include cl_builder.txt
|
||||
-- @include /koptilnya/libs/perma.txt
|
||||
|
||||
require("/koptilnya/libs/perma.txt")
|
||||
|
||||
if SERVER then
|
||||
require("sv_builder.txt")
|
||||
else
|
||||
PERMA.addTable({
|
||||
"http.get",
|
||||
"hologram.create",
|
||||
"material.create",
|
||||
"material.load",
|
||||
"material.urlcreate",
|
||||
"mesh"
|
||||
})
|
||||
|
||||
require("cl_builder.txt")
|
||||
end
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
-- @include /koptilnya/libs/table.txt
|
||||
-- @include obj_parser.txt
|
||||
-- @include /koptilnya/libs/utils.txt
|
||||
-- @include /koptilnya/libs/constants.txt
|
||||
require("/koptilnya/libs/table.txt")
|
||||
require("obj_parser.txt")
|
||||
require("/koptilnya/libs/utils.txt")
|
||||
require("/koptilnya/libs/constants.txt")
|
||||
|
||||
MeshBuilder = class("MeshBuilder")
|
||||
|
||||
@@ -14,27 +16,21 @@ function MeshBuilder:initialize(link)
|
||||
self.meshData = {}
|
||||
|
||||
self._objects = {}
|
||||
self._cachedMaterials = {}
|
||||
self._parser = ObjParser:new(link)
|
||||
self._parser.onLoaded = function(parser, objData)
|
||||
self:onObjLoaded(objData)
|
||||
self:_onObjLoaded(objData)
|
||||
end
|
||||
self._parser.onParsed = function(parser, meshData, usedTriangles)
|
||||
net.start("obj_parsed")
|
||||
net.send()
|
||||
|
||||
self:onObjParsed(meshData, usedTriangles)
|
||||
|
||||
self.meshData = meshData
|
||||
|
||||
self:_applyMeshes()
|
||||
self:_onObjParsed(meshData, usedTriangles)
|
||||
end
|
||||
self._cachedMaterials = {}
|
||||
self._parser:parse()
|
||||
|
||||
if player() == owner() then
|
||||
if IS_ME then
|
||||
net.receive("initialized", function()
|
||||
net.readEntity(function(ply)
|
||||
notification.addProgress(tostring(ply:getUserID()), string.format("%s is loading mesh", ply:getName()))
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
net.receive("obj_parsed", function()
|
||||
@@ -42,54 +38,91 @@ function MeshBuilder:initialize(link)
|
||||
notification.kill(tostring(ply:getUserID()))
|
||||
end)
|
||||
end)
|
||||
|
||||
net.receive("player_disconnect", function()
|
||||
notification.kill(net.readString())
|
||||
end)
|
||||
|
||||
net.receive("starfall_error", function()
|
||||
net.readEntity(function(ply)
|
||||
notification.kill(tostring(ply:getUserID()))
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
net.start("initialized")
|
||||
net.send()
|
||||
hook.add("starfallerror", "_starfallerror", function(ent, ply, err)
|
||||
if ent ~= chip() then return end
|
||||
|
||||
net.start("starfall_error")
|
||||
net.writeEntity(ply)
|
||||
net.send()
|
||||
end)
|
||||
|
||||
net.receive("objects", function()
|
||||
self._objects = {}
|
||||
self:_onReceiveObjects()
|
||||
end)
|
||||
end
|
||||
|
||||
local hasNext = net.readBit()
|
||||
function MeshBuilder:_onObjLoaded(objData)
|
||||
self:onObjLoaded(objData)
|
||||
end
|
||||
|
||||
while hasNext == 1 do
|
||||
local name = net.readString()
|
||||
local mat = net.readTable()
|
||||
function MeshBuilder:_onObjParsed(meshData, usedTriangles)
|
||||
net.start("obj_parsed")
|
||||
net.send()
|
||||
|
||||
net.readEntity(function(ent)
|
||||
local holo = ent:toHologram()
|
||||
self:onObjParsed(meshData, usedTriangles)
|
||||
|
||||
if (isURL(mat.basetexture)) then
|
||||
mat = self:_createMaterial(mat.shader, mat.basetexture, mat.bumpmap, mat.options)
|
||||
else
|
||||
hasErr, mat = pcall(material.load, mat.basetexture)
|
||||
self.meshData = meshData
|
||||
|
||||
if not hasErr then
|
||||
mat = material.load("models/debug/debugwhite")
|
||||
end
|
||||
self:_applyMeshes()
|
||||
end
|
||||
|
||||
function MeshBuilder:_onReceiveObjects()
|
||||
self._objects = {}
|
||||
|
||||
local hasNext = net.readBit()
|
||||
|
||||
while hasNext == 1 do
|
||||
local name = net.readString()
|
||||
local mat = net.readTable()
|
||||
|
||||
net.readEntity(function(ent)
|
||||
local holo = ent:toHologram()
|
||||
|
||||
if (isURL(mat.basetexture)) then
|
||||
mat = self:_createMaterial(mat.shader, mat.basetexture, mat.bumpmap, mat.options)
|
||||
else
|
||||
hasErr, mat = pcall(material.load, mat.basetexture)
|
||||
|
||||
if not hasErr then
|
||||
mat = material.load("models/debug/debugwhite")
|
||||
end
|
||||
end
|
||||
|
||||
local object = {name = name, mat = mat, holo = holo}
|
||||
local object = {name = name, mat = mat, holo = holo}
|
||||
|
||||
table.insert(self._objects, object)
|
||||
end)
|
||||
|
||||
hasNext = net.readBit()
|
||||
end
|
||||
|
||||
timer.simple(0.5, function()
|
||||
self:onHologramsReceived(self._objects)
|
||||
self:_applyMeshes()
|
||||
table.insert(self._objects, object)
|
||||
end)
|
||||
|
||||
hasNext = net.readBit()
|
||||
end
|
||||
|
||||
timer.simple(0.5, function()
|
||||
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
|
||||
local color = v.holo:getColor()
|
||||
|
||||
v.holo:setRenderBounds(Vector(-200), Vector(200))
|
||||
v.holo:setMesh(self.meshData[v.name])
|
||||
v.holo:setMeshMaterial(v.mat)
|
||||
v.holo:setRenderBounds(Vector(-200), Vector(200))
|
||||
|
||||
v.meshApplied = true
|
||||
end
|
||||
end
|
||||
@@ -105,6 +138,8 @@ function MeshBuilder:_setTexture(mat, name, texture, layoutOptions)
|
||||
layoutOptions = layoutOptions or {}
|
||||
|
||||
mat:setTextureURL(name, texture, function(_, _, _, _, layout)
|
||||
if not layout then return end
|
||||
|
||||
local x = layoutOptions.x or 0
|
||||
local y = layoutOptions.y or 0
|
||||
local w = layoutOptions.w or 1024
|
||||
|
||||
@@ -11,6 +11,12 @@ local function setStatus(status)
|
||||
end
|
||||
|
||||
function ObjParser:initialize(link)
|
||||
self.link = link
|
||||
self.rawData = nil
|
||||
self.objData = {}
|
||||
end
|
||||
|
||||
function ObjParser:parse()
|
||||
addWorker(coroutine.wrap(function()
|
||||
setStatus("Getting file...")
|
||||
|
||||
@@ -18,24 +24,25 @@ function ObjParser:initialize(link)
|
||||
coroutine.yield(1)
|
||||
end
|
||||
|
||||
local objData
|
||||
http.get(link, function(response)
|
||||
objData = response
|
||||
local rawObj
|
||||
http.get(self.link, function(response)
|
||||
rawObj = response
|
||||
end)
|
||||
|
||||
while not objData do
|
||||
while not rawObj do
|
||||
coroutine.yield(1)
|
||||
end
|
||||
|
||||
self:onLoaded(objData)
|
||||
|
||||
local triangles = mesh.trianglesLeft()
|
||||
self.rawObj = rawObj
|
||||
self:onLoaded(rawObj)
|
||||
|
||||
setStatus("File received, start parsing...")
|
||||
|
||||
self.meshData = mesh.createFromObj(objData, true)
|
||||
local triangles = mesh.trianglesLeft()
|
||||
|
||||
self:onParsed(self.meshData, triangles - mesh.trianglesLeft())
|
||||
self.objData = mesh.createFromObj(self.rawObj, true)
|
||||
|
||||
self:onParsed(self.objData, triangles - mesh.trianglesLeft())
|
||||
|
||||
setName(initialChipName)
|
||||
|
||||
|
||||
@@ -3,18 +3,29 @@
|
||||
-- @include /koptilnya/libs/workers.txt
|
||||
require("/koptilnya/libs/workers.txt")
|
||||
|
||||
local TIMEOUT = 3
|
||||
|
||||
MeshBuilder = class("MeshBuilder")
|
||||
|
||||
function MeshBuilder:initialize(link, modelPlaceholder)
|
||||
self.link = link
|
||||
self.modelPlaceholder = modelPlaceholder or "models/holograms/cube.mdl"
|
||||
|
||||
self._objectsNames = {}
|
||||
self._objects = {}
|
||||
self._objectsToSend = {}
|
||||
self._playersWithAccess = {}
|
||||
self._firstTimePlayers = find.allPlayers()
|
||||
self._firstTimeSended = false
|
||||
self._players = {}
|
||||
self._timeoutPassed = false
|
||||
|
||||
PERMA.onPermissionsGained = function(_, ply)
|
||||
table.insert(self._players, ply)
|
||||
|
||||
net.start("initialized")
|
||||
net.writeEntity(ply)
|
||||
net.send(owner())
|
||||
|
||||
if self._timeoutPassed then
|
||||
self:_sendObjects(ply)
|
||||
end
|
||||
end
|
||||
|
||||
net.receive("obj_parsed", function(len, ply)
|
||||
net.start("obj_parsed")
|
||||
@@ -24,69 +35,31 @@ function MeshBuilder:initialize(link, modelPlaceholder)
|
||||
self:onPlayerParsedObj(ply)
|
||||
end)
|
||||
|
||||
net.receive("initialized", function(len, ply)
|
||||
net.start("initialized")
|
||||
net.writeEntity(ply)
|
||||
net.send(owner())
|
||||
|
||||
table.insert(self._playersWithAccess, ply)
|
||||
|
||||
if self._firstTimeSended then
|
||||
self:_sendObjects(ply)
|
||||
end
|
||||
end)
|
||||
|
||||
hook.add("ClientInitialized", "MeshBuilder_ClientInitialized", function(ply)
|
||||
if #self._firstTimePlayers > 0 then
|
||||
table.removeByValue(self._firstTimePlayers, ply)
|
||||
|
||||
if #self._firstTimePlayers == 0 then
|
||||
self:_sendObjects(self._playersWithAccess)
|
||||
|
||||
self._firstTimeSended = true
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.add("PlayerConnected", "MeshBuilder_PlayerConnected", function(ply)
|
||||
if not self._firstTimeSended then
|
||||
table.insert(self._firstTimePlayers, ply)
|
||||
end
|
||||
end)
|
||||
|
||||
hook.add("PlayerDisconnected", "MeshBuilder_PlayerDisconnected", function(ply)
|
||||
table.removeByValue(self._firstTimePlayers, ply)
|
||||
table.removeByValue(self._players, ply)
|
||||
|
||||
net.start("player_disconnect")
|
||||
net.writeString(tostring(ply:getUserID()))
|
||||
net.writeString(ply:getName())
|
||||
net.send(owner())
|
||||
end)
|
||||
|
||||
addWorker(coroutine.wrap(function()
|
||||
while not http.canRequest() do
|
||||
coroutine.yield(1)
|
||||
end
|
||||
net.receive("starfall_error", function()
|
||||
print("starfall_error")
|
||||
|
||||
local objData
|
||||
http.get(link, function(response)
|
||||
objData = response
|
||||
net.readEntity(function(ply)
|
||||
net.start("starfall_error")
|
||||
net.writeEntity(ply)
|
||||
net.send(owner())
|
||||
end)
|
||||
|
||||
while not objData do
|
||||
coroutine.yield(1)
|
||||
end
|
||||
|
||||
self:onObjectLoaded(objData)
|
||||
|
||||
self:onObjectParsed(self._objectsNames)
|
||||
|
||||
return 2
|
||||
end))
|
||||
end)
|
||||
end
|
||||
|
||||
function MeshBuilder:_sendObjects(target)
|
||||
if #self._objectsToSend == 0 then
|
||||
return
|
||||
end
|
||||
if #self._objects == 0 then return end
|
||||
|
||||
net.start("objects")
|
||||
for _, v in pairs(self._objectsToSend) do
|
||||
for _, v in pairs(self._objects) do
|
||||
net.writeBit(1)
|
||||
net.writeString(v.name)
|
||||
net.writeTable(type(v.mat) == "table" and v.mat or { basetexture = tostring(v.mat) })
|
||||
@@ -102,7 +75,6 @@ function MeshBuilder:reset()
|
||||
end
|
||||
|
||||
self._objects = {}
|
||||
self._objectsToSend = {}
|
||||
end
|
||||
|
||||
function MeshBuilder:build(name, pos, ang, scale, color, mat, parent, relativeTo)
|
||||
@@ -113,6 +85,7 @@ function MeshBuilder:build(name, pos, ang, scale, color, mat, parent, relativeTo
|
||||
|
||||
local holo = holograms.create(pos, ang, self.modelPlaceholder, scale)
|
||||
holo:setColor(color)
|
||||
holo:setRenderMode(color.a == 255 and RENDERMODE.NORMAL or RENDERMODE.TRANSCOLOR)
|
||||
|
||||
if isValid(parent) then
|
||||
holo:setParent(parent)
|
||||
@@ -124,22 +97,20 @@ function MeshBuilder:build(name, pos, ang, scale, color, mat, parent, relativeTo
|
||||
end
|
||||
|
||||
function MeshBuilder:getResult()
|
||||
table.copyFromTo(self._objects, self._objectsToSend)
|
||||
|
||||
if self._firstTimeSended then
|
||||
self:_sendObjects(self._playersWithAccess)
|
||||
if self._timeoutPassed then
|
||||
self:_sendObjects(self._players)
|
||||
else
|
||||
timer.simple(TIMEOUT, function()
|
||||
self._timeoutPassed = true
|
||||
|
||||
self:_sendObjects(self._players)
|
||||
end)
|
||||
end
|
||||
|
||||
return self._objectsToSend
|
||||
return self._objects
|
||||
end
|
||||
|
||||
-- STUB
|
||||
|
||||
function MeshBuilder:onObjectLoaded(objData)
|
||||
end
|
||||
|
||||
function MeshBuilder:onObjectParsed(objectsNames)
|
||||
end
|
||||
|
||||
function MeshBuilder:onPlayerParsedObj(ply)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user