139 lines
3.1 KiB
Lua
139 lines
3.1 KiB
Lua
local dkjson = require( "lib.dkjson" )
|
|
local love = assert( love )
|
|
local shader = require( "shaders.flat" )
|
|
local mat = require( "mat4" )
|
|
|
|
local attributeNames = {
|
|
POSITION = "VertexPosition",
|
|
NORMAL = "VertexNormal",
|
|
}
|
|
|
|
local types = {
|
|
["SCALAR"] = 1,
|
|
["VEC3"] = 3,
|
|
}
|
|
|
|
local componentTypes = {
|
|
[5121] = "byte",
|
|
[5123] = "unorm16",
|
|
[5126] = "float",
|
|
}
|
|
|
|
local elementComponentTypes = {
|
|
[5123] = "uint16",
|
|
[5126] = "uint32",
|
|
}
|
|
|
|
local asset
|
|
local buffer
|
|
do
|
|
local fd = assert( love.filesystem.newFileData( "models/contempra.gltf" ) )
|
|
asset = dkjson.decode( fd:getString() )
|
|
buffer = love.filesystem.newFileData( "models/contempra.bin" )
|
|
end
|
|
|
|
--load all the bufferViews
|
|
local bufferViews = {}
|
|
for i, view in pairs( asset.bufferViews ) do
|
|
bufferViews[i] = love.data.newByteData( buffer, view.byteOffset, view.byteLength )
|
|
end
|
|
|
|
local function attributeFormat( attributeName, accessor )
|
|
return {attributeNames[attributeName], componentTypes[accessor.componentType], types[accessor.type] }
|
|
end
|
|
|
|
local function lgMesh( primitive )
|
|
assert( not( primitive.mode ) ) --triangles only
|
|
|
|
local finalMesh
|
|
for name, accIdx in pairs( primitive.attributes ) do
|
|
local acc = asset.accessors[accIdx+1]
|
|
|
|
local mesh = love.graphics.newMesh(
|
|
{attributeFormat(name, acc)}, --vertexformat
|
|
acc.count,
|
|
"triangles",
|
|
"static"
|
|
)
|
|
|
|
local bfv = bufferViews[1+acc.bufferView]
|
|
mesh:setVertices( bfv )
|
|
|
|
if finalMesh then
|
|
finalMesh:attachAttribute( attributeNames[name], mesh )
|
|
else
|
|
finalMesh = mesh
|
|
end
|
|
|
|
end
|
|
|
|
|
|
do
|
|
local acc = asset.accessors[1+primitive.indices]
|
|
local bfv = bufferViews[1+acc.bufferView]
|
|
finalMesh:setVertexMap(bfv, elementComponentTypes[acc.componentType] )
|
|
end
|
|
return finalMesh
|
|
end
|
|
|
|
--flat hierarchy only, ignores rotation. quaternions, man :(
|
|
local function getNodeTransform( node )
|
|
if not node.scale then return end
|
|
return mat.TRS(
|
|
node.scale[1], node.scale[2], node.scale[3],
|
|
0, 0, 0,
|
|
node.translation[1], node.translation[2], node.translation[3] )
|
|
end
|
|
|
|
local meshes = {}
|
|
local transforms = { mat.id() }
|
|
for _, nodeIdx in pairs( asset.scenes[1].nodes ) do
|
|
local node = asset.nodes[1+nodeIdx]
|
|
local mesh = asset.meshes[1+node.mesh]
|
|
meshes[mesh.name] = lgMesh( mesh.primitives[1] )
|
|
transforms[mesh.name] = getNodeTransform( node ) or transforms[1]
|
|
end
|
|
|
|
|
|
local obj = {
|
|
isRinging = false,
|
|
isTalking = false,
|
|
x = 2,
|
|
y = 0.25,
|
|
z = -2,
|
|
size = 0.1,
|
|
}
|
|
|
|
|
|
local colors = setmetatable(
|
|
{
|
|
Handset = {0.9, 0.1, 0.1 },
|
|
Phone = {0.85, 0.1, 0.1 },
|
|
Table = {0.30, 0.1, 0.1 },
|
|
},
|
|
{__index = { 0, 0, 0 } }
|
|
)
|
|
|
|
function obj.draw( view, proj, light )
|
|
shader:send( "view", "column", view )
|
|
shader:send( "proj", "column", proj )
|
|
shader:send( "light", light )
|
|
love.graphics.setShader( shader )
|
|
for name, mesh in pairs( meshes ) do
|
|
if ( name ~= "Handset" or not obj.pickedUp ) then
|
|
love.graphics.setColor( colors[name] )
|
|
shader:send( "mdl", "column", transforms[name] )
|
|
love.graphics.draw( mesh )
|
|
end
|
|
end
|
|
end
|
|
|
|
function obj.update( player )
|
|
|
|
end
|
|
|
|
function obj.pickup( )
|
|
obj.pickedUp = true
|
|
end
|
|
|
|
return obj |