replaced bells, diffuse lighitng everywhere, started terrain, test puzzle swap
|
@ -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. 🔔🔔🔔🔔🔔🔔🔔",
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
After Width: | Height: | Size: 652 KiB |
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -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
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
--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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
local sfx = {}
|
||||
|
||||
function sfx.playFootstep()
|
||||
print( "step" )
|
||||
--print( "step" )
|
||||
end
|
||||
return sfx
|
|
@ -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
|
||||
]]
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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
|
||||
]]
|
After Width: | Height: | Size: 652 KiB |
Before Width: | Height: | Size: 2.3 MiB |
Before Width: | Height: | Size: 5.5 MiB |
BIN
src/tex/bell.png
Before Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 55 KiB |