diff --git a/src/i18n/en.lua b/src/i18n/en.lua index 9a52957..57e5413 100644 --- a/src/i18n/en.lua +++ b/src/i18n/en.lua @@ -26,5 +26,9 @@ ENTER TO KEEP]], win = [[ZIMINIAR HAS ARRIVED. THE WORLD WILL NEVER BE THE SAME. RICHES TO THE CONJUROR! -]] +]], + phoneRing = "THE PHONE RINGS IMPATIENTLY", + phonePickup = "[%s]: PICK UP", + phoneRedial = "[%s]: *69", + phoneClue = "THE TIME IS %dP.M. 🔔🔔🔔🔔🔔🔔🔔", } \ No newline at end of file diff --git a/src/level/light.lua b/src/level/light.lua new file mode 100644 index 0000000..c8bee05 --- /dev/null +++ b/src/level/light.lua @@ -0,0 +1,20 @@ +local function normal( a, b, c ) + local norm = a*a+b*b+c*c + if norm < 0.0001 then return p end + norm = 1.0 / math.sqrt( norm ) + return norm *a, norm *b, norm *c +end + +local light = {} +light[1], light[2], light[3] = normal( 1.0, 1.0, 0.0 ) --direction TO the light btw +light.target = 1 + +local c, s, p = math.cos, math.sin, 2*math.pi +function light.setTarget( i ) + light.target = light.target + 1 + i = i - 1 + light[1], light[2], light[3] = normal( c(i*p/7), 1, s(i*p/7) ) +end + + +return light \ No newline at end of file diff --git a/src/level/terrain.lua b/src/level/terrain.lua deleted file mode 100644 index 94f483c..0000000 --- a/src/level/terrain.lua +++ /dev/null @@ -1,25 +0,0 @@ -local lg = assert( love.graphics ) -local mesh = lg.newMesh( - {--attributes - {"VertexPosition", "float", 2}, - {"VertexTexCoord", "float", 2}, - }, - {--vertices - { 1, 0, -a, - 1, 1, 1, - 1, 0 }, - { -1, 0, -a, - 1, 0, 0, - 0, 0 }, - { 0, 1, a, - 0, 1, 0, - 1, 1, }, - { 0, -1, a, - 0, 0, 1, - 0, 1, }, - }, - "strip", - "static" -) -mesh:setVertexMap{ 1,2,3,4,1,2 } -return mesh \ No newline at end of file diff --git a/src/level/world.lua b/src/level/world.lua index 4cb8632..56efaf5 100644 --- a/src/level/world.lua +++ b/src/level/world.lua @@ -11,6 +11,8 @@ local debugTF = love.math.newTransform() local sky local bell local contempra +local terrain +local light = require( "level.light" ) function t.start() canvas = { @@ -18,10 +20,11 @@ function t.start() stencil = false, depth = true, } - + sky = require( "models.sky" ) bell = require( "models.bell" ) contempra = require( "models.contempra" ) + terrain = require( "models.terrain" ) end function t.debug() @@ -52,9 +55,10 @@ function t.draw( view, proj ) love.graphics.replaceTransform( tf ) love.graphics.setMeshCullMode( "back" ) - sky.draw( view, proj ) - bell.draw( view, proj ) - contempra.draw( view, proj ) + sky.draw( view, proj, light ) + terrain.draw( view, proj ) + bell.draw( view, proj, light ) + contempra.draw( view, proj, light ) love.graphics.pop() @@ -67,14 +71,20 @@ function t.draw( view, proj ) end end -function t.update( mesh, modelMatrix ) - meshes[mesh] = modelMatrix +function t.update( player ) + end -function t.add( mesh, shaderName ) - shaderName = shaderName or "matte" - meshes[mesh] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, {0, 0, 1, 0}, {0, 0, 0, 1} } - drawLists[shaderName][mesh] = true +function t.transposeBells( i, j ) + return bell.transpose( i, j ) +end + +function t.targetLight( i ) + return light.setTarget( i ) +end + +function t.pickupPhone() + return contempra.pickup() end return t \ No newline at end of file diff --git a/src/mat4.lua b/src/mat4.lua index bca1e3f..59a39ad 100644 --- a/src/mat4.lua +++ b/src/mat4.lua @@ -16,6 +16,11 @@ function t.TRS( x, y, z, a, b, g, dx, dy, dz ) {dx, dy, dz, 1}} end +--gltf properties to matrix +function t.gltfTRS( scale, rotation, translation ) + +end + --position of camera x y z --yaw a --pitch b diff --git a/src/models/bell-height.jpg b/src/models/bell-height.jpg new file mode 100644 index 0000000..7c16c66 Binary files /dev/null and b/src/models/bell-height.jpg differ diff --git a/src/models/bell.bin b/src/models/bell.bin new file mode 100644 index 0000000..c1abf1b Binary files /dev/null and b/src/models/bell.bin differ diff --git a/src/models/bell.gltf b/src/models/bell.gltf new file mode 100644 index 0000000..0c7c64f --- /dev/null +++ b/src/models/bell.gltf @@ -0,0 +1,137 @@ +{ + "asset":{ + "generator":"Khronos glTF Blender I/O v4.2.70", + "version":"2.0" + }, + "scene":0, + "scenes":[ + { + "name":"Scene", + "nodes":[ + 0 + ] + } + ], + "nodes":[ + { + "mesh":0, + "name":"Plane" + } + ], + "materials":[ + { + "doubleSided":true, + "name":"Material.001", + "pbrMetallicRoughness":{ + "baseColorTexture":{ + "index":0 + }, + "metallicFactor":0, + "roughnessFactor":0.5 + } + } + ], + "meshes":[ + { + "name":"Plane", + "primitives":[ + { + "attributes":{ + "POSITION":0, + "NORMAL":1, + "TEXCOORD_0":2 + }, + "indices":3, + "material":0 + } + ] + } + ], + "textures":[ + { + "sampler":0, + "source":0 + } + ], + "images":[ + { + "mimeType":"image/jpeg", + "name":"bell-height", + "uri":"bell-height.jpg" + } + ], + "accessors":[ + { + "bufferView":0, + "componentType":5126, + "count":3775, + "max":[ + 0.9985347986221313, + 1.7237859964370728, + 0.9926199316978455 + ], + "min":[ + -0.9985349774360657, + 0.0007939338684082031, + -1.0005090236663818 + ], + "type":"VEC3" + }, + { + "bufferView":1, + "componentType":5126, + "count":3775, + "type":"VEC3" + }, + { + "bufferView":2, + "componentType":5126, + "count":3775, + "type":"VEC2" + }, + { + "bufferView":3, + "componentType":5123, + "count":5625, + "type":"SCALAR" + } + ], + "bufferViews":[ + { + "buffer":0, + "byteLength":45300, + "byteOffset":0, + "target":34962 + }, + { + "buffer":0, + "byteLength":45300, + "byteOffset":45300, + "target":34962 + }, + { + "buffer":0, + "byteLength":30200, + "byteOffset":90600, + "target":34962 + }, + { + "buffer":0, + "byteLength":11250, + "byteOffset":120800, + "target":34963 + } + ], + "samplers":[ + { + "magFilter":9729, + "minFilter":9987 + } + ], + "buffers":[ + { + "byteLength":132052, + "uri":"bell.bin" + } + ] +} diff --git a/src/models/bell.lua b/src/models/bell.lua index 00ea170..327f6cf 100644 --- a/src/models/bell.lua +++ b/src/models/bell.lua @@ -1,106 +1,148 @@ +local dkjson = require( "lib.dkjson" ) +local love = assert( love ) local lg = assert( love.graphics ) local math = math local mat = require( "mat4" ) -local DETAIL = 15 -local CURVE = 45 -local vertices = {} +local attributeNames = { + POSITION = "VertexPosition", + NORMAL = "VertexNormal", + TEXCOORD_0 = "VertexTexCoord", +} -local function dr( y ) - return -math.pow( 1-y, -2/3 ) * 0.6/3 -end +local types = { + ["SCALAR"] = 1, + ["VEC3"] = 3, + ["VEC2"] = 2, +} -local function radius( y ) - return math.pow( math.max( 0, - 0.6 * math.pow( (1-y), 1/3 ) + - 0.1 * math.exp( -5*y )), - 0.8) -end +local componentTypes = { + [5121] = "byte", + [5123] = "unorm16", + [5126] = "float", +} -local loops = {} -for i = 1, CURVE do loops[i] = {} end +local elementComponentTypes = { + [5123] = "uint16", + [5126] = "uint32", +} +local filterTypes = { + [9729] = "linear", + [9987] = "linear", +} + +local asset +local buffer do - local c, s = math.cos( 2*math.pi / DETAIL ), -math.sin( 2*math.pi / DETAIL ) - local n = 1 - local y = 0 - for i, loop in ipairs( loops ) do - local x, z = 1, 0 - y = y + 1 / #loops - local r = radius( y ) - local dy = dr( y ) - for j = 1, DETAIL + 1 do - --need the extra vertex so the texture wraps correctly - local u = 5 * ( j - 1 ) / DETAIL - local v = 3 * (1.0 - y) - 1.0 - vertices[ n ] = { r * x, y, r * z, u, v, x, 0, z } - loop[j] = n - n = n + 1 - x, z = c*x+s*z, c*z-s*x - end - end + local fd = assert( love.filesystem.newFileData( "models/bell.gltf" ) ) + asset = dkjson.decode( fd:getString() ) + buffer = love.filesystem.newFileData( "models/bell.bin" ) end -local function constructVertexMap() - local map = {} - local k = 1 - for i, loop in ipairs( loops ) do - local nextLoop = loops[i+1] - if not nextLoop then return map end - for j, n in ipairs( loop ) do - map[k] = n - map[k+1] = nextLoop[j] - k=k+2 +--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 { + assert(attributeNames[attributeName]), + assert(componentTypes[accessor.componentType]), + assert(types[accessor.type]) } +end + +local function lgTexture( matIdx ) + local tex = asset.textures[1+matIdx] + local img = asset.images[1+tex.source] + local smpl = asset.samplers[1+tex.sampler] + img = love.graphics.newImage( "tex/"..img.uri, { mipmaps = true } ) + img:setWrap( "repeat", "repeat" ) + img:setFilter( filterTypes[smpl.minFilter], filterTypes[smpl.magFilter] ) + img:setMipmapFilter( filterTypes[smpl.minFilter] ) + return img +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 + + if primitive.material then finalMesh:setTexture( lgTexture( primitive.material ) ) end + return finalMesh end -local bellMesh = lg.newMesh( - {--attributes - {"VertexPosition", "float", 3}, - {"VertexTexCoord", "float", 2}, - {"VertexNormal", "float", 3}, - }, - vertices, - "strip", - "static" -) - -local bellPositions = {} +local bellMesh = lgMesh( asset.meshes[1].primitives[1] ) +--each bell has the following positional data: +-- scale, x, z, colorparam +local bells = {} +local bellInstanceMesh do local c, s = math.cos( 2*math.pi / 7 ), -math.sin( 2*math.pi / 7 ) local x, z = 1, 0 local r = 15 for i = 1, 7 do - bellPositions[i] = { i / 2, r * x, r * z, (i-1)/6 } + bells[i] = { i / 2, r * x, r * z, (i-1)/6 } x, z = c*x+s*z, c*z-s*x end - bellMesh:attachAttribute( "bellInstance", - lg.newMesh({{"bellInstance","float",4}}, bellPositions, nil, "static" ), + bellInstanceMesh = lg.newMesh({{"bellInstance","float",4}}, bells, nil, "static" ) + bellMesh:attachAttribute( "bellInstance", bellInstanceMesh, "perinstance" ) end -bellMesh:setVertexMap( constructVertexMap() ) -do - local bellTexture = lg.newImage( "tex/bell-height.png", {mipmaps = true} ) - bellTexture:setWrap( "repeat", "clampzero" ) - bellMesh:setTexture( bellTexture ) -end - local t = {} t.shader = require( "shaders.bell" ) t.mesh = bellMesh -function t.draw( view, proj ) +function t.draw( view, proj, light ) local s = t.shader s:send( "view", "column", view ) s:send( "proj", "column", proj ) + s:send("light", light ) lg.setShader(s) lg.drawInstanced( t.mesh, 7 ) end +function t.transpose( i, j ) + print( "transposing:", i, j ) + io.flush() + bells[i][2], bells[i][3], bells[j][2], bells[j][3] = + bells[j][2], bells[j][3], bells[i][2], bells[i][3] + bellInstanceMesh:setVertices( bells ) + bellMesh:attachAttribute( "bellInstance", bellInstanceMesh, + "perinstance" ) +end + return t \ No newline at end of file diff --git a/src/models/contempra.bin b/src/models/contempra.bin index 274355e..059a6d9 100644 Binary files a/src/models/contempra.bin and b/src/models/contempra.bin differ diff --git a/src/models/contempra.gltf b/src/models/contempra.gltf index 7dfa428..26b60ab 100644 --- a/src/models/contempra.gltf +++ b/src/models/contempra.gltf @@ -10,23 +10,60 @@ "name":"Scene", "nodes":[ 0, - 1 + 1, + 2 ] } ], "nodes":[ { "mesh":0, - "name":"Phone" + "name":"Table" }, { "mesh":1, - "name":"Handset" + "name":"Handset", + "rotation":[ + 0, + 0.9925320744514465, + 0, + 0.12198396772146225 + ], + "scale":[ + 0.2577824592590332, + 0.2577824592590332, + 0.2577824592590332 + ], + "translation":[ + -0.5825188159942627, + 1, + 0 + ] + }, + { + "mesh":2, + "name":"Phone", + "rotation":[ + 0, + 0.9925320744514465, + 0, + 0.12198396772146225 + ], + "scale":[ + 0.2577824592590332, + 0.2577824592590332, + 0.2577824592590332 + ], + "translation":[ + -0.5825188159942627, + 1, + 0 + ] } ], "meshes":[ { - "name":"Phone", + "name":"Table", "primitives":[ { "attributes":{ @@ -48,12 +85,80 @@ "indices":5 } ] + }, + { + "name":"Phone", + "primitives":[ + { + "attributes":{ + "POSITION":6, + "NORMAL":7 + }, + "indices":8 + } + ] } ], "accessors":[ { "bufferView":0, "componentType":5126, + "count":1838, + "max":[ + 1.100633144378662, + 0.9967015981674194, + 1.100633144378662 + ], + "min":[ + -1.100633144378662, + 0.0033593475818634033, + -1.100633144378662 + ], + "type":"VEC3" + }, + { + "bufferView":1, + "componentType":5126, + "count":1838, + "type":"VEC3" + }, + { + "bufferView":2, + "componentType":5123, + "count":2868, + "type":"SCALAR" + }, + { + "bufferView":3, + "componentType":5126, + "count":396, + "max":[ + 1.3204938173294067, + 0.7231597304344177, + -0.10927927494049072 + ], + "min":[ + -1.4686684608459473, + 0.10958258807659149, + -0.8433066010475159 + ], + "type":"VEC3" + }, + { + "bufferView":4, + "componentType":5126, + "count":396, + "type":"VEC3" + }, + { + "bufferView":5, + "componentType":5123, + "count":600, + "type":"SCALAR" + }, + { + "bufferView":6, + "componentType":5126, "count":260, "max":[ 1.3268864154815674, @@ -68,87 +173,77 @@ "type":"VEC3" }, { - "bufferView":1, + "bufferView":7, "componentType":5126, "count":260, "type":"VEC3" }, { - "bufferView":2, + "bufferView":8, "componentType":5123, "count":546, "type":"SCALAR" - }, - { - "bufferView":3, - "componentType":5126, - "count":76, - "max":[ - 1.3234574794769287, - 0.728451132774353, - -0.10927927494049072 - ], - "min":[ - -1.482479214668274, - 0.10958258807659149, - -0.8433066010475159 - ], - "type":"VEC3" - }, - { - "bufferView":4, - "componentType":5126, - "count":76, - "type":"VEC3" - }, - { - "bufferView":5, - "componentType":5123, - "count":120, - "type":"SCALAR" } ], "bufferViews":[ { "buffer":0, - "byteLength":3120, + "byteLength":22056, "byteOffset":0, "target":34962 }, + { + "buffer":0, + "byteLength":22056, + "byteOffset":22056, + "target":34962 + }, + { + "buffer":0, + "byteLength":5736, + "byteOffset":44112, + "target":34963 + }, + { + "buffer":0, + "byteLength":4752, + "byteOffset":49848, + "target":34962 + }, + { + "buffer":0, + "byteLength":4752, + "byteOffset":54600, + "target":34962 + }, + { + "buffer":0, + "byteLength":1200, + "byteOffset":59352, + "target":34963 + }, { "buffer":0, "byteLength":3120, - "byteOffset":3120, + "byteOffset":60552, + "target":34962 + }, + { + "buffer":0, + "byteLength":3120, + "byteOffset":63672, "target":34962 }, { "buffer":0, "byteLength":1092, - "byteOffset":6240, - "target":34963 - }, - { - "buffer":0, - "byteLength":912, - "byteOffset":7332, - "target":34962 - }, - { - "buffer":0, - "byteLength":912, - "byteOffset":8244, - "target":34962 - }, - { - "buffer":0, - "byteLength":240, - "byteOffset":9156, + "byteOffset":66792, "target":34963 } ], "buffers":[ { - "byteLength":9396, + "byteLength":67884, "uri":"contempra.bin" } ] diff --git a/src/models/contempra.lua b/src/models/contempra.lua index a48b558..4c55fac 100644 --- a/src/models/contempra.lua +++ b/src/models/contempra.lua @@ -48,26 +48,26 @@ local function lgMesh( primitive ) 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] @@ -76,8 +76,23 @@ local function lgMesh( primitive ) return finalMesh end -local phone = lgMesh( asset.meshes[1].primitives[1] ) -local handset = lgMesh( asset.meshes[2].primitives[1] ) +--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 = { @@ -89,34 +104,37 @@ local obj = { size = 0.1, } -local phoneTF = mat.TRS( - obj.size,obj.size,obj.size, - 0,0.12,0, - obj.x, obj.y, obj.z) -local lx, lz = 1, 0 -local c, s = math.cos( 0.01 ), math.sin( 0.01 ) -function obj.draw( view, proj ) +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 } } +) - love.graphics.setColor( 1,0.2,0.2,1 ) - love.graphics.setMeshCullMode( "none" ) --debug - shader:send( "view", "column", view ) - shader:send( "proj", "column", proj ) - - lx, lz = c*lx+s*lz,c*lz-s*lx - shader:send( "light", {0, 1, 0} ) - love.graphics.setShader( shader ) - shader:send( "mdl", "column", phoneTF ) - love.graphics.draw( phone ) - love.graphics.draw( handset ) +function obj.draw( view, proj, light ) + love.graphics.setMeshCullMode( "none" ) --debug + 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.ring() - +function obj.update( player ) + end -function obj.answer() - +function obj.pickup( ) + obj.pickedUp = true end return obj \ No newline at end of file diff --git a/src/models/sky.lua b/src/models/sky.lua index eb9e2bc..fedfce0 100644 --- a/src/models/sky.lua +++ b/src/models/sky.lua @@ -27,25 +27,15 @@ mesh:setVertexMap{ 5, 1, 7, 1, 7, 3, } -local cubemap = lg.newCubeImage( - { - "tex/cubemap_5.png", - "tex/cubemap_4.png", - "tex/cubemap_2.png", - "tex/cubemap_3.png", - "tex/cubemap_0.png", - "tex/cubemap_1.png", - }, - {mipmaps = true} ) local shader = require( "shaders.sky" ) -shader:send( "cube", cubemap ) -local function draw( view, proj ) +local function draw( view, proj, light ) lg.push( "all" ) lg.setDepthMode( "always", false ) lg.setMeshCullMode( "none" ) --get view matrix without translation + shader:send( "light", light ) shader:send( "proj", "column", proj ) shader:send( "view", "column", {view[1], view[2], view[3], {0, 0, 0, 1}} ) lg.setShader( shader ) diff --git a/src/models/spike.lua b/src/models/spike.lua index 9ec176b..c845a2a 100644 --- a/src/models/spike.lua +++ b/src/models/spike.lua @@ -1,23 +1,112 @@ -local lg = assert( love.graphics ) +local love = assert( love ) local math = math +local mat = require( "mat4" ) +local dkjson = require( "lib.dkjson" ) +local shader = require( "shaders.spike" ) -local vertices = {{0, 1, 0, 1/2, 3}} +local attributeNames = { + POSITION = "VertexPosition", + NORMAL = "VertexNormal", + TEXCOORD_0 = "VertexTexCoord", +} -local c, s = math.cos( math.pi / 8 ), math.sin( math.pi / 8 ) -local x, z = 1, 0 -for i = 1, 17 do - local u, v = i / 17, 1 - i / 17 - vertices[ i + 1 ] = { x, 0, z, u, 0} - x, z = c*x+s*z, c*z-s*x +local types = { + ["SCALAR"] = 1, + ["VEC3"] = 3, + ["VEC2"] = 2, +} + +local componentTypes = { + [5121] = "byte", + [5123] = "unorm16", + [5126] = "float", +} + +local elementComponentTypes = { + [5123] = "uint16", + [5126] = "uint32", +} + +local filterTypes = { + [9729] = "linear", + [9987] = "linear", +} + +local asset +local buffer +do + local fd = assert( love.filesystem.newFileData( "models/bell.gltf" ) ) + asset = dkjson.decode( fd:getString() ) + buffer = love.filesystem.newFileData( "models/bell.bin" ) end -local mesh = lg.newMesh( - {--attributes - {"VertexPosition", "float", 3}, - {"VertexTexCoord", "float", 2}, - }, - vertices, - "fan", - "static" -) -return mesh \ No newline at end of file +--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 { + assert(attributeNames[attributeName]), + assert(componentTypes[accessor.componentType]), + assert(types[accessor.type]) } +end + +local function lgTexture( matIdx ) + local tex = asset.textures[1+matIdx] + local img = asset.images[1+tex.source] + local smpl = asset.samplers[1+tex.sampler] + img = love.graphics.newImage( "tex/"..img.uri, { mipmaps = true } ) + img:setWrap( "repeat", "repeat" ) + img:setFilter( filterTypes[smpl.minFilter], filterTypes[smpl.magFilter] ) + img:setMipmapFilter( filterTypes[smpl.minFilter] ) + return img +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 + + if primitive.material then finalMesh:setTexture( lgTexture( primitive.material ) ) end + return finalMesh +end + +local spike = lgMesh( asset.meshes[1].primitives[1] ) +local spikeInstanceMesh = {} + +local spikes = {} + +function spikes.draw( view, proj, light ) + +end + +return spikes \ No newline at end of file diff --git a/src/models/terrain.lua b/src/models/terrain.lua new file mode 100644 index 0000000..139d268 --- /dev/null +++ b/src/models/terrain.lua @@ -0,0 +1,71 @@ +local love = assert( love ) +local ffi = require( "ffi" ) +local sideLength = 256 +local vertexCount = sideLength * sideLength +local vertices = love.data.newByteData( 4 * vertexCount ) +local vertexMap = love.data.newByteData( 2 * vertexCount ) + +local height = love.graphics.newImage( "tex/terrain.png" ) + +local mesh = love.graphics.newMesh( + {{"VertexPosition", "float", 1 }}, + vertexCount, + "strip", + "static" +) +mesh:setTexture( height ) + +do + local p = vertexMap:getFFIPointer() + local ptr = ffi.cast( "uint16_t *", p) + for i = 0, vertexCount - 1 do + ptr[i] = i + end + mesh:setVertexMap( vertexMap, "uint16" ) + do local _ = p end --keep alive? +end + +local shader = love.graphics.newShader[[ + #pragma glsl3 + #define fog vec4( 0.85, 0.85, 1.0, 1.0 ) + #define fogHigh vec4( 1.0, 1.0, 0.9, 1.0 ) + varying float depth; +//varying vec3 normal; + varying vec4 world; +#ifdef VERTEX + uniform mat4 view; + uniform mat4 proj; +// attribute vec3 VertexNormal; + vec4 position( mat4 _, vec4 pos ){ +//normal = VertexNormal; + world = pos; + vec4 eye = view * world; + depth = -eye.z; + return proj*eye; + } +#endif +#ifdef PIXEL +//uniform vec3 light; + vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) { +// vec3 norm = normalize( normal ); +// vec3 toLight = normalize( light - world.xyz ); +// float diff = max( dot( norm, light ), 0.5 ); +// vec4 mainColor = vec4( diff * color.rgb, color.a ); + + return mix( mix( color * Texel( tex, texuv ), fog, + clamp( depth / 80.0, 0.0, 1.0)), fogHigh, + clamp( world.y / 20.0, 0.0, 1.0)) ; + } +#endif +]] + +local obj = { height = height } + +function obj.draw( view, proj ) + shader:send( "view", "column", view ) + shader:send( "proj", "column", proj ) + love.graphics.setShader( shader ) + love.graphics.draw( mesh ) +end + +return obj \ No newline at end of file diff --git a/src/player.lua b/src/player.lua index 28f494f..2cabec5 100644 --- a/src/player.lua +++ b/src/player.lua @@ -14,7 +14,7 @@ local player = { rate = 0.01, --tick rate speed = 2, --movement speed m/s x = 0, - y = 0.5, + y = 1.5, z = 3, vx = 0, vz = 0, @@ -75,7 +75,8 @@ end local function collide( ix, iz, fx, fz, circles, lines ) local x, z = ix, iz for _, circle in pairs( circles ) do - if distanceToSegment( ix, iz, fx, fz ) then + if distanceToSegment( ix, iz, fx, fz, circle.x, circle.z ) < + circle.r * circle.r then end end diff --git a/src/scenes/main.lua b/src/scenes/main.lua index 0f4433e..f391ccb 100644 --- a/src/scenes/main.lua +++ b/src/scenes/main.lua @@ -58,6 +58,7 @@ function t.update( dt ) player:update() end + world.update( player ) end function t.mousepressed( x, y, button, isTouch, presses ) @@ -73,11 +74,20 @@ function t.keypressed( key, code, isrepeat ) if code == settings.keyUse.val then end - if code == "q" then + if code == "2" then local strings = require( "i18n" ) local slideshow = require( "scenes.slideshow" ) return slideshow.play( strings.win, love.event.quit, "tex/win.jpg" ) end + if code == "3" then + return world.targetLight( math.random( 1, 7 ) ) + end + if code == "4" then + return world.pickupPhone() + end + if code == "1" then + return world.transposeBells( 2, 7 ) + end end function t.keyreleased( key, code ) diff --git a/src/scenes/settings.lua b/src/scenes/settings.lua index eb5dd3e..2e30a02 100644 --- a/src/scenes/settings.lua +++ b/src/scenes/settings.lua @@ -45,7 +45,7 @@ function t.keypressed( key, code, isRepeat ) if code == "return" then local slideshow = require( "scenes.slideshow" ) local main = require( "scenes.main" ) - return slideshow.play( strings.intro, main.play, "tex/jared.jpg" ) + return slideshow.play( strings.intro, main.play ) end end diff --git a/src/sfx.lua b/src/sfx.lua index 131ddb7..2004c27 100644 --- a/src/sfx.lua +++ b/src/sfx.lua @@ -1,6 +1,6 @@ local sfx = {} function sfx.playFootstep() - print( "step" ) + --print( "step" ) end return sfx \ No newline at end of file diff --git a/src/shaders/bell.lua b/src/shaders/bell.lua index 2b0b648..39431e0 100644 --- a/src/shaders/bell.lua +++ b/src/shaders/bell.lua @@ -3,32 +3,48 @@ return love.graphics.newShader[[ #define fogHigh vec4( 1.0, 1.0, 0.85, 1.0 ) #define sunDir 0.1 * vec3( 0.9, 0.2, 0.5 ) varying float depth; - varying float height; + varying vec3 normal; + varying vec4 world; varying float instanceColor; #ifdef VERTEX //per instance: (uniform) scale and xz position attribute vec4 bellInstance; - attribute vec3 vertexNormal; + attribute vec3 VertexNormal; uniform mat4 view; uniform mat4 proj; vec4 position( mat4 _, vec4 pos ){ + normal = (view*vec4(VertexNormal,1.0)).rgb; instanceColor = bellInstance.a; pos.xyz *= bellInstance.r; pos.xz += bellInstance.gb; - height = pos.y; + world = pos; + vec4 eye = view * pos; depth = -eye.z; return proj*eye; } #endif #ifdef PIXEL + uniform vec3 light; vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) { vec4 icolor = mix( vec4(1.0,1.0,1.0,1.0), vec4(0.5,0.0,0.0,1.0), instanceColor ); vec4 texel = Texel( tex, texuv ); - vec4 bellColor = icolor * (texel + (1.0 - texel.a)); - return color * mix( mix( bellColor, - fog, clamp( depth / 80.0, 0.0, 1.0)), - fogHigh, clamp( height / 20.0, 0.0, 1.0)); + float y = texuv.y; + y = max( 0.1, + 1.4 * pow( 0.9*y*(1.0-0.9*y) , 0.25)); + texel.rgb *= y; + texel.gb *= 0.5 * instanceColor + 0.75; + + + //diffuse light + vec3 norm = normalize( normal ); + vec3 toLight = normalize( light - world.xyz ); + float diff = max( dot( norm, light ), 0.1 ); + vec4 mainColor = vec4( diff * texel.rgb, texel.a ); + + return color * mix( mix( mainColor, + fog, clamp( depth / 80.0, 0.0, 1.0)), + fogHigh, clamp(world.y / 20.0, 0.0, 1.0)); } #endif ]] \ No newline at end of file diff --git a/src/shaders/flat.lua b/src/shaders/flat.lua index d307c32..50deebe 100644 --- a/src/shaders/flat.lua +++ b/src/shaders/flat.lua @@ -22,7 +22,7 @@ return love.graphics.newShader[[ vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) { vec3 norm = normalize( normal ); vec3 toLight = normalize( light - world.xyz ); - float diff = max( dot( norm, light ), 0.5 ); + float diff = max( dot( norm, light ), 0.1 ); vec4 mainColor = vec4( diff * color.rgb, color.a ); diff --git a/src/shaders/sky.lua b/src/shaders/sky.lua index 77bfce9..0a8d9b9 100644 --- a/src/shaders/sky.lua +++ b/src/shaders/sky.lua @@ -1,22 +1,23 @@ return love.graphics.newShader[[ #define fog vec4( 0.85, 0.85, 1.0, 1.0 ) + #define yellow vec4( 0.9, 0.9, 0.7, 1.0 ) + #define blue vec4( 0.6, 0.6, 0.7, 1.0 ) varying vec3 viewDir; #ifdef VERTEX uniform mat4 view; uniform mat4 proj; vec4 position( mat4 _, vec4 pos ){ viewDir = pos.xyz; - viewDir.y -= 0.5; return proj*view*pos; } #endif #ifdef PIXEL - uniform samplerCube cube; + uniform vec3 light; vec4 effect( vec4 color, Image _, vec2 __, vec2 ___) { - return color * Texel( cube, viewDir ) + 0.5 * dot( viewDir, vec3( 0.0, 1.0, 0.0 )); - //mix( fog, - //Texel( cube, viewDir ), - //dot(viewDir, vec3(0.0, 0.0, 1.0 )));; + float d = dot( normalize( viewDir ), light ); + d = 0.5+0.5*d; + d = pow(d, 45); + return mix( blue, mix( yellow, color, d * 2 ) , d ); } #endif ]] \ No newline at end of file diff --git a/src/shaders/spike.lua b/src/shaders/spike.lua new file mode 100644 index 0000000..e69de29 diff --git a/src/tex/bell-height.jpg b/src/tex/bell-height.jpg new file mode 100644 index 0000000..7c16c66 Binary files /dev/null and b/src/tex/bell-height.jpg differ diff --git a/src/tex/bell-height.png b/src/tex/bell-height.png deleted file mode 100644 index 7266d48..0000000 Binary files a/src/tex/bell-height.png and /dev/null differ diff --git a/src/tex/bell-normal.png b/src/tex/bell-normal.png deleted file mode 100644 index 7f5f2e2..0000000 Binary files a/src/tex/bell-normal.png and /dev/null differ diff --git a/src/tex/bell.png b/src/tex/bell.png deleted file mode 100644 index 452257d..0000000 Binary files a/src/tex/bell.png and /dev/null differ diff --git a/src/tex/terrain.png b/src/tex/terrain.png index d88c5ee..ffb6262 100644 Binary files a/src/tex/terrain.png and b/src/tex/terrain.png differ