ring/src/models/contempra.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