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