Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local fs = require("filesystem")
- local png = require("PNGImage")
- local converts = {}
- function grab_byte(v)
- return math.floor(v / 256), string.char(math.floor(v) % 256)
- end
- converts.float2str = function(x)
- local sign = 0
- if x < 0 then
- sign = 1
- x = -x
- end
- local mantissa, exponent = math.frexp(x)
- if x == 0 then
- mantissa = 0
- exponent = 0
- else
- mantissa = (mantissa * 2 - 1) * 8388608
- exponent = exponent + 126
- end
- local v, byte = ""
- x, byte = grab_byte(mantissa); v = v..byte
- x, byte = grab_byte(x); v = v..byte
- x, byte = grab_byte(exponent * 128 + x); v = v..byte
- x, byte = grab_byte(sign * 128 + x); v = v..byte
- return v
- end
- converts.str2float = function(x)
- local sign = 1
- local mantissa = string.byte(x, 3) % 128
- for i = 2, 1, -1 do mantissa = mantissa * 256 + string.byte(x, i) end
- if string.byte(x, 4) > 127 then sign = -1 end
- local exponent = (string.byte(x, 4) % 128) * 2 + math.floor(string.byte(x, 3) / 128)
- if exponent == 0 then return 0 end
- mantissa = (math.ldexp(mantissa, -23) + 1) * sign
- return math.ldexp(mantissa, exponent - 127)
- end
- converts.int2str = function(n)
- n = (n < 0) and (4294967296 + n) or n
- return string.char((math.modf(n/16777216))%256, (math.modf(n/65536))%256, (math.modf(n/256))%256, n%256)
- end
- converts.str2int = function(x)
- b1, b2, b3, b4 = string.byte(x, 1, 4)
- local n = b1*16777216 + b2*65536 + b3*256 + b4
- n = (n > 2147483647) and (n - 4294967296) or n
- return n
- end
- print("Select a model type:\n0 - Standart 3D\n1 - Vertex animated 3D\n2 - Color animated 3D\n3 - Vertex and color animated 3D\n4 - Standart 2D\n5 - Vertex animated 2D\n6 - Color animated 2D\n7 - Vertex and color animated 2D")
- local inType = io.read()
- local type = tonumber(inType)
- if type == nil then type = 0 end
- print("Enter model name:")
- local inModelName = io.read()
- if inModelName == "" then inModelName = "model" end
- inModelName = inModelName..".pam"
- ::gotoInBaseModel::
- print("\nEnter base model path *.obj:")
- local inBaseModel = io.read()
- if inBaseModel == "exit" then goto gotoExit
- else
- if (inBaseModel:len() > 4) and (inBaseModel:find(".obj", inBaseModel:len()-4) ~= nil) then
- if not fs.exists(inBaseModel) then
- print("File does not exists")
- goto gotoInBaseModel
- end
- else
- print("Bad file path")
- goto gotoInBaseModel
- end
- end
- ::gotoInBasePalette::
- print("\nEnter base palette path *.png:")
- local inBasePalette = io.read()
- if inBasePalette == "exit" then goto gotoExit
- else
- if (inBasePalette:len() > 4) and (inBasePalette:find(".png", inBasePalette:len()-4) ~= nil) then
- if not fs.exists(inBasePalette) then
- print("File does not exists")
- goto gotoInBasePalette
- end
- else
- print("Bad file path, can you pick file?(y/n):")
- local yn = io.read()
- if yn ~= nil and ((yn == "y") or (yn == "yes")) then goto gotoInBasePalette end
- inBasePalette = ""
- end
- end
- local function getVT(data)
- local v, t = data:match("(-?%d+)/(-?%d+)")
- return tonumber(v), tonumber(t) or nil
- end
- local function getUVColor(img, u, v)
- if img == nil then return string.char(255,255,255,255) end
- local w,h = img:getSize()
- local r,g,b,a = img:getPixel(math.floor(u*w), math.floor((1-v)*h))
- if r == nil then r=255 g=255 b=255 a=255 end
- return string.char(r,g,b,a)
- end
- local function inBounds(u, v)
- if u > 1 then
- local a, b = math.modf(u)
- u = b
- elseif u < 0 then
- local a, b = math.modf(u)
- u = 1+b
- end
- if v > 1 then
- local a, b = math.modf(v)
- v = b
- elseif v < 0 then
- local a, b = math.modf(v)
- v = 1+b
- end
- return u, v
- end
- local function loadModel(fileName)
- local file = io.open(fileName, "r")
- if file ~= nil then
- local vertexes = {}
- local triangles = {}
- local textureCoords = {}
- local retTextureCoords = {}
- for line in file:lines() do
- if line ~= nil and line ~= '' then
- local key, a, b, c, d = line:match("(%S+)%s+(%S+)%s+(%S+)%s+(%S+)%s*(%S*)")
- if key == 'v' then
- local x, y, z = tonumber(a), tonumber(b), tonumber(c)
- table.insert(vertexes, {x,y,z})
- elseif key == "vt" then
- local u, v = tonumber(a), tonumber(b)
- table.insert(textureCoords, table.pack(inBounds(u, v)))
- elseif key == 'f' then
- local v1, t1 = getVT(a)
- local v2 = getVT(b)
- local v3 = getVT(c)
- if v1 < 0 then
- local len = #vertexes + 1
- v1, v2, v3 = len + v1, len + v2, len + v3
- end
- local p = 0
- if (t1 ~= nil) and (textureCoords[t1] ~= nil) then
- table.insert(retTextureCoords, textureCoords[t1])
- p = #retTextureCoords
- end
- table.insert(triangles, {v1,v2,v3, p})
- end
- end
- end
- file:close()
- return vertexes, triangles, retTextureCoords
- else return nil end
- end
- local function loadModel2D(fileName)
- local vertexes = {}
- local triangles = {}
- local textureCoords = {}
- local retTextureCoords = {}
- local file = io.open(fileName, "r")
- if file ~= nil then
- for line in file:lines() do
- if line ~= nil and line ~= '' then
- local key, a, b, c, d = line:match("(%S+)%s+(%S+)%s+(%S+)%s+(%S+)%s*(%S*)")
- if key == 'v' then
- local x, y = tonumber(a), tonumber(b)
- table.insert(vertexes, {x,y})
- elseif key == "vt" then
- local u, v = tonumber(a), tonumber(b)
- table.insert(textureCoords, table.pack(inBounds(u, v)))
- elseif key == 'f' then
- local v1, t1 = getVT(a)
- local v2 = getVT(b)
- local v3 = getVT(c)
- if v1 < 0 then
- local len = #vertexes + 1
- v1, v2, v3 = len + v1, len + v2, len + v3
- end
- local p = 0
- if (t1 ~= nil) and (textureCoords[t1] ~= nil) then
- table.insert(retTextureCoords, textureCoords[t1])
- p = #retTextureCoords
- end
- table.insert(triangles, {v1,v2,v3,p})
- end
- end
- end
- file:close()
- return vertexes, triangles, retTextureCoords
- else return nil end
- end
- if type < 4 then
- local verts, tris, texts = loadModel(inBaseModel)
- if verts == nil then
- print("Bad model")
- goto gotoExit
- end
- local image = nil
- if inBasePalette ~= "" then
- image = png.newFromFile(inBasePalette)
- end
- local data = "PAM"..string.char(type)..converts.int2str(#verts)..converts.int2str(#tris)
- for n, vert in pairs(verts) do
- local x,y,z = table.unpack(vert)
- data = data..converts.float2str(x)..converts.float2str(y)..converts.float2str(z)
- end
- for n, tri in pairs(tris) do
- local a,b,c,d = table.unpack(tri)
- local color = ""
- if (image == nil) or (d == 0) or (d > #texts) then color = string.char(255,255,255,255)
- else
- local u,v = table.unpack(texts[d])
- color = getUVColor(image,u,v)
- end
- data = data..converts.int2str(a)..converts.int2str(b)..converts.int2str(c)..color
- end
- local vcount = #verts
- local fcount = 0
- local pcount = 0
- local fdata = ""
- local pdata = ""
- if (type == 2) or (type == 3) then
- local palettePaths = {}
- ::gotoInFramePalette::
- print("\nEnter frame palette path *.png:")
- local inFramePalette = io.read()
- if inFramePalette == "exit" then goto gotoExit
- else
- if (inFramePalette:len() > 4) and (inFramePalette:find(".png", inFramePalette:len()-4) ~= nil) then
- if fs.exists(inFramePalette) then
- table.insert(palettePaths, inFramePalette)
- goto gotoInFramePalette
- else
- print("File does not exists")
- goto gotoInFramePalette
- end
- elseif inFramePalette == "" then
- print("End palette frames")
- else
- print("Bad file path")
- goto gotoInFramePalette
- end
- end
- for n, pal in pairs(palettePaths) do
- image = png.newFromFile(pal)
- if image ~= nil then
- for n, tri in pairs(tris) do
- local a,b,c,d = table.unpack(tri)
- local u,v = table.unpack(texts[d])
- local color = getUVColor(image,u,v)
- pdata = pdata..color
- end
- pcount = pcount+1
- else print("Bad palette frame "..pal.."\nSkipping")
- end
- end
- pdata = converts.int2str(pcount)..pdata
- end
- if (type == 1) or (type == 3) then
- local framePaths = {}
- ::gotoInFrameModel::
- print("\nEnter frame model path *.obj:")
- local inFrameModel = io.read()
- if inFrameModel == "exit" then goto gotoExit
- else
- if (inFrameModel:len() > 4) and (inFrameModel:find(".obj", inFrameModel:len()-4) ~= nil) then
- if fs.exists(inFrameModel) then
- table.insert(framePaths, inFrameModel)
- goto gotoInFrameModel
- else
- print("File does not exists")
- goto gotoInFrameModel
- end
- elseif inFrameModel == "" then
- print("End vertex frames")
- else
- print("Bad file path")
- goto gotoInFrameModel
- end
- end
- for n, fp in pairs(framePaths) do
- verts = loadModel(fp)
- if (verts == nil) or (#verts ~= vcount) then
- print("Different number of vertexes in "..fp.."\nSkipping")
- else
- for n, vert in pairs(verts) do
- local x,y,z = table.unpack(vert)
- fdata = fdata..converts.float2str(x)..converts.float2str(y)..converts.float2str(z)
- end
- fcount = fcount+1
- end
- end
- fdata = converts.int2str(fcount)..fdata
- end
- data = data..fdata..pdata
- local file = fs.open(inModelName, "wb")
- file:write(data)
- file:close()
- if type == 0 then print("Model succeful packed to "..inModelName)
- elseif type == 1 then print("Model succeful packed to "..inModelName.." vertex frames count: "..fcount)
- elseif type == 2 then print("Model succeful packed to "..inModelName.." palette frames count: "..pcount)
- else print("Model succeful packed to "..inModelName.." vertex frames count: "..fcount.." palette frames count: "..pcount)
- end
- elseif type < 8 then
- local verts, tris, texts = loadModel2D(inBaseModel)
- if verts == nil then
- print("Bad model")
- goto gotoExit
- end
- local image = nil
- if inBasePalette ~= "" then
- image = png.newFromFile(inBasePalette)
- end
- local data = "PAM"..string.char(type)..converts.int2str(#verts)..converts.int2str(#tris)
- for n, vert in pairs(verts) do
- local x,y = table.unpack(vert)
- data = data..converts.float2str(x)..converts.float2str(y)
- end
- for n, tri in pairs(tris) do
- local a,b,c,d = table.unpack(tri)
- local color = ""
- if (image == nil) or (d == 0) or (d > #texts) then color = string.char(255,255,255,255)
- else
- local u,v = table.unpack(texts[d])
- color = getUVColor(image,u,v)
- end
- data = data..converts.int2str(a)..converts.int2str(b)..converts.int2str(c)..color
- end
- local vcount = #verts
- local fcount = 0
- local pcount = 0
- local fdata = ""
- local pdata = ""
- if (type == 6) or (type == 7) then
- local palettePaths = {}
- ::gotoInFramePalette::
- print("\nEnter frame palette path *.png:")
- local inFramePalette = io.read()
- if inFramePalette == "exit" then goto gotoExit
- else
- if (inFramePalette:len() > 4) and (inFramePalette:find(".png", inFramePalette:len()-4) ~= nil) then
- if fs.exists(inFramePalette) then
- table.insert(palettePaths, inFramePalette)
- goto gotoInFramePalette
- else
- print("File does not exists")
- goto gotoInFramePalette
- end
- elseif inFramePalette == "" then
- print("End palette frames")
- else
- print("Bad file path")
- goto gotoInFramePalette
- end
- end
- for n, pal in pairs(palettePaths) do
- image = png.newFromFile(pal)
- if image ~= nil then
- for n, tri in pairs(tris) do
- local a,b,c,d = table.unpack(tri)
- local u,v = table.unpack(texts[d])
- local color = getUVColor(image,u,v)
- pdata = pdata..color
- end
- pcount = pcount+1
- else print("Bad palette frame "..pal.."\nSkipping")
- end
- end
- pdata = converts.int2str(pcount)..pdata
- end
- if (type == 5) or (type == 7) then
- local framePaths = {}
- ::gotoInFrameModel::
- print("\nEnter frame model path *.obj:")
- local inFrameModel = io.read()
- if inFrameModel == "exit" then goto gotoExit
- else
- if (inFrameModel:len() > 4) and (inFrameModel:find(".obj", inFrameModel:len()-4) ~= nil) then
- if fs.exists(inFrameModel) then
- table.insert(framePaths, inFrameModel)
- goto gotoInFrameModel
- else
- print("File does not exists")
- goto gotoInFrameModel
- end
- elseif inFrameModel == "" then
- print("End vertex frames")
- else
- print("Bad file path")
- goto gotoInFrameModel
- end
- end
- for n, fp in pairs(framePaths) do
- verts = loadModel2D(fp)
- if (verts == nil) or (#verts ~= vcount) then
- print("Different number of vertexes in "..fp.."\nSkipping")
- else
- for n, vert in pairs(verts) do
- local x,y = table.unpack(vert)
- fdata = fdata..converts.float2str(x)..converts.float2str(y)
- end
- fcount = fcount+1
- end
- end
- fdata = converts.int2str(fcount)..fdata
- end
- data = data..fdata..pdata
- local file = fs.open(inModelName, "wb")
- file:write(data)
- file:close()
- if type == 4 then print("Model succeful packed to "..inModelName)
- elseif type == 5 then print("Model succeful packed to "..inModelName.." vertex frames count: "..fcount)
- elseif type == 6 then print("Model succeful packed to "..inModelName.." palette frames count: "..pcount)
- else print("Model succeful packed to "..inModelName.." vertex frames count: "..fcount.." palette frames count: "..pcount)
- end
- end
- ::gotoExit::
Advertisement
Add Comment
Please, Sign In to add comment