Created
September 14, 2017 18:39
-
-
Save Bambofy/31a465ceb8a4edc72850c95724081964 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local path = ... .. "." | |
local loader = {} | |
loader.version = "0.0.2" | |
function loader.load(path, filename) | |
loader.object = { | |
v = {}, -- List of vertices - x, y, z, [w]=1.0 | |
vt = {}, -- Texture coordinates - u, v, [w]=0 | |
vn = {}, -- Normals - x, y, z | |
vp = {}, -- Parameter space vertices - u, [v], [w] | |
f = {}, -- Faces | |
materials = {} | |
} | |
assert(file_exists(path .. "/" .. filename), "File not found: " .. path .. "/" .. filename) | |
local get_lines | |
if love then | |
get_lines = love.filesystem.lines | |
else | |
get_lines = io.lines | |
end | |
local lines = {} | |
for line in get_lines(path .. "/" .. filename) do | |
table.insert(lines, line) | |
end | |
loader.parse(path, filename, lines) | |
return loader.object | |
end | |
function loader.parse(path, filename, lines) | |
for _, line in ipairs(lines) do | |
local l = string_split(line, "%s+") | |
if l[1] == "mtllib" then | |
local mtllibfilename = l[2] | |
loader.parseMaterial(path, mtllibfilename) | |
elseif l[1] == "v" then | |
local v = { | |
x = tonumber(l[2]), | |
y = tonumber(l[3]), | |
z = tonumber(l[4]), | |
w = tonumber(l[5]) or 1.0 | |
} | |
table.insert(loader.object.v, v) | |
elseif l[1] == "vt" then | |
local vt = { | |
u = tonumber(l[2]), | |
v = tonumber(l[3]), | |
w = tonumber(l[4]) or 0 | |
} | |
table.insert(loader.object.vt, vt) | |
elseif l[1] == "vn" then | |
local vn = { | |
x = tonumber(l[2]), | |
y = tonumber(l[3]), | |
z = tonumber(l[4]), | |
} | |
table.insert(loader.object.vn, vn) | |
elseif l[1] == "vp" then | |
local vp = { | |
u = tonumber(l[2]), | |
v = tonumber(l[3]), | |
w = tonumber(l[4]), | |
} | |
table.insert(loader.object.vp, vp) | |
elseif l[1] == "f" then | |
local f = {} | |
for i=2, #l do | |
local line = string.gsub(l[i], "//", "/") | |
local split = string_split(line, "/") | |
local v = {} | |
if #split == 1 then | |
v.v = tonumber(split[1]) | |
elseif #split == 2 then | |
v.v = tonumber(split[1]) | |
v.vn = tonumber(split[2]) | |
elseif #split == 3 then | |
v.v = tonumber(split[1]) | |
v.vt = tonumber(split[2]) | |
v.vn = tonumber(split[3]) | |
end | |
table.insert(f, v) | |
end | |
table.insert(loader.object.f, f) | |
end | |
end | |
end | |
function loader.parseMaterial(path, mtllibfilename) | |
assert(file_exists(path .. "/" .. mtllibfilename), "File not found: " .. path .. "/" .. mtllibfilename) | |
local lines = {} | |
for line in love.filesystem.lines(path .. "/" .. mtllibfilename) do | |
table.insert(lines, line) | |
end | |
local materials = {} | |
local currentMaterialIndex = 0 | |
for k,v in pairs(lines) do | |
local parts = string_split(v, "%s+") | |
if parts[1] == "newmtl" then | |
currentMaterialIndex = currentMaterialIndex + 1 | |
materials[currentMaterialIndex] = { | |
Name = parts[2] | |
} | |
elseif parts[1] == "Ka" then | |
materials[currentMaterialIndex].Ambient = { | |
R = tonumber(parts[2]), | |
G = tonumber(parts[3]), | |
B = tonumber(parts[4]) | |
} | |
elseif parts[1] == "Kd" then | |
materials[currentMaterialIndex].Diffuse = { | |
R = tonumber(parts[2]), | |
G = tonumber(parts[3]), | |
B = tonumber(parts[4]) | |
} | |
elseif parts[1] == "Ks" then | |
materials[currentMaterialIndex].Specular = { | |
R = tonumber(parts[2]), | |
G = tonumber(parts[3]), | |
B = tonumber(parts[4]) | |
} | |
elseif parts[1] == "Ns" then | |
materials[currentMaterialIndex].Shininess = tonumber(parts[2]) | |
elseif parts[1] == "map_Kd" then | |
materials[currentMaterialIndex].DiffuseTexture = path .. "/" .. parts[2] | |
end | |
end | |
loader.object.materials = materials | |
end | |
function file_exists(file) | |
if love then return love.filesystem.exists(file) end | |
local f = io.open(file, "r") | |
if f then f:close() end | |
return f ~= nil | |
end | |
-- http://wiki.interfaceware.com/534.html | |
function string_split(s, d) | |
local t = {} | |
local i = 0 | |
local f | |
local match = '(.-)' .. d .. '()' | |
if string.find(s, d) == nil then | |
return {s} | |
end | |
for sub, j in string.gmatch(s, match) do | |
i = i + 1 | |
t[i] = sub | |
f = j | |
end | |
if i ~= 0 then | |
t[i+1] = string.sub(s, f) | |
end | |
return t | |
end | |
return loader |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment