Initial commit.

This commit is contained in:
Signal 2026-02-14 12:36:36 -05:00
commit b5c753ff4d
129 changed files with 4472 additions and 0 deletions

View file

@ -0,0 +1,404 @@
local ns = firefly
local game_makers = {}
minetest.register_entity(":firefly:map_preview", {
initial_properties = {
visual = "mesh",
textures = {"[fill:1x1:0,0:#39f2"},
use_texture_alpha = true,
static_save = false
},
on_activate = function(e)
e.object:set_armor_groups{immortal = 1}
e._name = ""..math.random()
end,
on_punch = function(e, p)
e.master:set_map(e.map)
end,
dismiss = function(e)
e.object:remove()
end
})
minetest.register_entity(":firefly:game_maker_display", {
initial_properties = {
visual = "sprite",
textures = {"blank.png"},
selectionbox = {
-2.5, -0.5, 0.5,
2.5, 2.5, 6/16
}
-- pointable = false,
},
on_activate = function(e, data)
local pos = e.object:get_pos():round()
local node = minetest.get_node(pos)
if not data or not node.name:find "game_maker_" then return end
e.object:set_armor_groups{immortal = 1}
e.mode = data
e.rot = ns.facedir_to_rotation(node.param2)
e.object:set_properties {
selectionbox = ns.rotate_selectionbox({
-2.5, -0.5, 0.5,
2.5, 2.5, 6/16
}, e.rot)
}
e.label = minetest.add_entity(pos +vector.new(0, 1, 0.3):rotate(e.rot), "display")
e.label:set_rotation(e.rot)
e.players = {}
e.players_list = {}
game_makers[pos:to_string()] = e
e.pos = pos
e:show_status()
end,
on_step = function(e, dtime)
if e.state == "choose_world" then
elseif e.state == "starting" and e.timer then
e.timer = e.timer -dtime
if e.timer_display then
local tx, w = ns.texture_from_number(math.round(e.timer))
e.timer_display:set_properties {
textures = {tx},
visual_size = vector.new(w /16,1,1) *0.5
}
else
e.timer = nil
return
end
local timer = math.round(e.timer)
if timer ~= e._timer then
for _, name in pairs(e.players_list) do
ns.change_hud_bar(ns.players[name], "start_timer", {
value = math.max(timer, 0),
title = timer == 0 and "Starting..." or "Starting in "..timer.."..."
})
end
end
e._timer = timer
if e.timer <= 0 then
e:start_game()
-- e.timer = nil
-- e.timer_display:remove()
-- e.timer_display = nil
-- e.label:set_pos(e.label:get_pos():offset(0, -0.25, 0))
-- e.label:set_properties {
-- visual = "upright_sprite",
-- textures = {"[combine:102x102:0,46=firefly_punch_to_start.png", "[combine:102x102:0,46=firefly_punch_to_start.png"},
-- }
--
-- ns.start_game(e.mode, e.players_list)
--
-- for name, obj in pairs(e.players) do
-- obj:remove()
-- ns.remove_hud_bar(ns.players[name], "start_timer")
-- end
-- e.players = {}
-- e.players_list = {}
end
end
end,
add_player = function(e, name)
table.insert(e.players_list, name)
ns.add_hud_bar(ns.players[name], "start_timer", {
max = 10,
value = 0,
title = "Waiting for players..."
})
if e.state == "awaiting_players" then
local pos = e.object:get_pos() +vector.new(-#e.players_list /2 +0.5, 1, 0.3):rotate(e.rot)
local obj = minetest.add_entity(pos, "display")
obj:set_properties {
visual = "mesh",
mesh = "firefly_head.gltf",
visual_size = vector.new(1, 1, 1) *0.5,
textures = {"firefly_character.png"}
}
obj:set_rotation(e.rot:offset(0, -math.pi, 0))
e.players[name] = obj
for i, name in pairs(e.players_list) do
e.players[name]:set_pos(pos +vector.new(0.5 *(i -1), 0, 0):rotate(e.rot))
end
elseif e.state == "starting" then
end
end,
remove_player = function(e, name)
ns.remove_hud_bar(ns.players[name], "start_timer")
table.remove(e.players_list, table.indexof(e.players_list, name))
if e.state == "choose_map" then
e:dismiss_map_selector()
e.state = nil
e:show_status()
elseif #e.players_list < 1 then
if e.state == "awaiting_players" then
e:dismiss_players()
elseif e.state == "starting" then
e:dismiss_countdown()
end
e.state = nil
for i, name in pairs(e.players_list) do
e.players[name]:set_pos(pos +vector.new(0.5 *(i -1), 0, 0):rotate(e.rot))
end
e:show_status()
else
local pos = e.object:get_pos() +vector.new(-#e.players_list /2 +0.5, 1, 0):rotate(e.rot)
end
end,
show_status = function(e)
if e.map_image then
e.map_image.object:remove()
e.map_image = nil
end
e.label:set_pos(e.pos +vector.new(0, 1, 0.3):rotate(e.rot))
e.label:set_properties {
visual = "upright_sprite",
textures = {"[combine:102x102:0,46=firefly_punch_to_start.png", "[combine:102x102:0,46=firefly_punch_to_start.png"},
visual_size = vector.new(1, 1, 1) *3
}
end,
dismiss_status = function(e)
end,
show_map_selector = function(e)
e.map = nil
e.label:set_pos(e.pos +vector.new(0, 2, 0.3):rotate(e.rot))
e.label:set_properties {
visual = "upright_sprite",
textures = {"[combine:85x85:0,37.5=firefly_choose_map.png", "[combine:85x85:0,37.5=firefly_choose_map.png"},
visual_size = vector.new(1, 1, 1) *1
}
e.map_previews = {}
local pos = e.object:get_pos()
for name, x in pairs(ns.modes[e.mode].maps) do
local obj = minetest.add_entity(pos, "firefly:map_preview")
obj:set_properties {
mesh = x.preview
}
local le = obj:get_luaentity()
le.master = e
le.map = name
e.map_previews[name] = le
end
end,
set_map = function(e, map)
if not e.map then
e.confirm_map = minetest.add_entity(e.object:get_pos() +vector.new(2, 1, 0.3):rotate(e.rot), "display")
e.confirm_map:set_properties {
visual = "upright_sprite",
textures = {"[combine:85x85:0,37.5=firefly_choose_map.png", "[combine:85x85:0,37.5=firefly_choose_map.png"},
visual_size = vector.new(1, 1, 1) *1,
pointable = true
}
e.confirm_map = e.confirm_map:get_luaentity()
e.confirm_map.on_punch = function()
e:dismiss_map_selector()
e.state = "awaiting_players"
e:show_players()
end
end
e.map_image = minetest.add_entity(e.object:get_pos() +vector.new(0, 1, 0.35):rotate(e.rot), "display")
e.map_image:set_properties {
visual = "upright_sprite",
textures = {"firefly_battle_map_test.png"},
visual_size = vector.new(4.5, 2.5, 5) *0.98,
pointable = true
}
e.map_image = e.map_image:get_luaentity()
e.map = map
end,
dismiss_map_selector = function(e)
for _, x in pairs(e.map_previews) do
x:dismiss()
end
e.map_previews = nil
if e.confirm_map then
e.confirm_map.object:remove()
e.confirm_map = nil
end
end,
show_players = function(e)
e.label:set_pos(e.pos +vector.new(0, 2, 0.3):rotate(e.rot))
e.label:set_properties {
visual = "upright_sprite",
textures = {"[combine:94x94:0,42=firefly_punch_to_join.png", "[combine:94x94:0,42=firefly_punch_to_join.png"},
visual_size = vector.new(1, 1, 1) *2
}
local pos = e.object:get_pos() +vector.new(-#e.players_list /2 +0.5, 1, 0.3):rotate(e.rot)
for i = 1, #e.players_list do
local name = e.players_list[i]
local obj = minetest.add_entity(pos +vector.new(0.5 *(i -1), 0, 0):rotate(e.rot), "display")
obj:set_properties {
visual = "mesh",
mesh = "firefly_head.gltf",
visual_size = vector.new(1, 1, 1) *0.5,
textures = {"firefly_character.png"}
}
obj:set_rotation(e.rot:offset(0, -math.pi, 0))
e.players[name] = obj
end
e.begin_countdown = minetest.add_entity(pos +vector.new(2, 1, 0):rotate(e.rot), "display")
e.begin_countdown:set_properties {
visual = "upright_sprite",
textures = {"[combine:85x85:0,37.5=firefly_choose_map.png", "[combine:85x85:0,37.5=firefly_choose_map.png"},
visual_size = vector.new(1, 1, 1) *1,
pointable = true
}
e.begin_countdown = e.begin_countdown:get_luaentity()
e.begin_countdown.on_punch = function()
e:dismiss_players()
e.state = "starting"
e.timer = 10
e:show_countdown()
end
end,
dismiss_players = function(e)
for _, x in pairs(e.players) do
x:remove()
end
e.begin_countdown.object:remove()
e.begin_countdown = nil
end,
show_countdown = function(e)
local pos = e.object:get_pos()
e.timer_display = minetest.add_entity(pos +vector.new(0, 1, 0.3):rotate(e.rot), "display")
e.timer_display:set_properties {
visual = "upright_sprite",
}
e.timer_display:set_rotation(e.rot)
end,
dismiss_countdown = function(e)
e.timer_display:remove()
e.timer_display = nil
end,
start_game = function(e)
e.timer = nil
e.state = nil
e:dismiss_countdown()
for i = 1, #e.players_list do
ns.remove_hud_bar(ns.players[e.players_list[i]], "start_timer")
end
ns.start_game(e.mode, e.map, e.players_list)
e.players_list = {}
e:show_status()
end,
on_punch = function(e, p)
local name = p:get_player_name()
local m = ns.players[name]
if not e.state then
m.hosting = e
e:add_player(name)
e.state = "choose_map"
e:show_map_selector()
elseif e.state == "awaiting_players" or e.state == "starting" then
if e.players[name] then
e:remove_player(name)
else
e:add_player(name)
end
end
-- if e.players[name] then
-- e.players[name]:remove()
-- e.players[name] = nil
-- table.remove(e.players_list, table.indexof(e.players_list, name))
-- ns.remove_hud_bar(ns.players[name], "start_timer")
-- if not next(e.players_list) then
-- e.label:set_pos(e.label:get_pos():offset(0, -0.25, 0))
-- e.label:set_properties {
-- visual = "upright_sprite",
-- textures = {"[combine:102x102:0,46=firefly_punch_to_start.png", "[combine:102x102:0,46=firefly_punch_to_start.png"},
-- }
-- e.timer_display:remove()
-- e.timer_display = nil
-- end
-- else
-- if not next(e.players_list) then
-- e.label:set_pos(e.label:get_pos():offset(0, 0.25, 0))
-- e.label:set_properties {
-- visual = "upright_sprite",
-- textures = {"[combine:94x94:0,42=firefly_punch_to_join.png", "[combine:94x94:0,42=firefly_punch_to_join.png"},
-- }
-- e.timer_display = minetest.add_entity(e.object:get_pos():offset(0, 0.85, 0), "display")
-- e.timer_display:set_properties {
-- visual = "upright_sprite",
-- }
-- e.timer_display:set_rotation(e.rot)
-- end
-- local display = minetest.add_entity(e.object:get_pos():offset(0, 0, 0), "display")
-- display:set_properties {
-- visual = "mesh",
-- mesh = "firefly_head.gltf",
-- textures = ns.players[name].object:get_properties().textures,
-- visual_size = vector.new(1,1,1) *0.5
-- }
-- display:set_rotation(e.rot)
-- e.players[name] = display
-- table.insert(e.players_list, name)
-- e.timer = math.max(5, 11 -(#e.players_list)^2)
-- e._timer = e.timer
-- ns.add_hud_bar(ns.players[name], "start_timer", {
-- max = e.timer,
-- value = e.timer,
-- title = "Starting in "..e._timer.."..."
-- })
-- end
end,
get_staticdata = function(e)
return e.mode
end,
on_deactivate = function(e)
local pos = e.object:get_pos():round()
game_makers[pos:to_string()] = nil
e.label:remove()
if e.timer_display then
e.timer_display:remove()
end
end
})
Player:listen("deinit", function(m)
if m.hosting then
m.hosting:remove_player(m.name)
elseif m.joining then
m.joining:remove_player(m.name)
end
end)
function ns.register_game_maker(name, def)
local function onload(pos)
minetest.add_entity(pos, "firefly:game_maker_display", def.mode)
end
ns.register_node("game_maker_"..name, {
drawtype = "mesh",
mesh = "firefly_screen.gltf",
tiles = {"firefly_screen.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = false,
groups = {call_on_load = 1},
on_construct = onload,
on_load = onload,
on_destruct = function(pos)
game_makers[pos:to_string()].object:remove()
end,
})
end

View file

@ -0,0 +1,20 @@
local ns = firefly
ns.register_player_state {
name = "lobby_main",
on_enter = function(m)
end,
on_leave = function(m)
end
}
Player:listen('init', function(m)
ns.set_player_state(m, "lobby_main")
end)
include "game_maker.lua"
minetest.register_mapgen_script(minetest.get_modpath(minetest.get_current_modname()).."/mapgen.lua")

View file

@ -0,0 +1,73 @@
local REALM_START = vector.new(-500, -500, -500)
local REALM_END = vector.new(500, 500, 500)
local function intersection(min, max, b, c)
return min.x < c.x and max.x > b.x and
min.y < c.y and max.y > b.y and
min.z < c.z and max.z > b.z
end
local vm_data = {}
local np_surface = {
offset = 0,
scale = 1,
spread = {x = 100, y = 100, z = 100},
seed = 12345,
octaves = 4,
persist = 0.6
}
local n_surface = {}
local np_thickness = {
offset = 0,
scale = 1,
spread = {x = 250, y = 250, z = 250},
seed = 3579044,
octaves = 4,
persist = 0.6
}
local n_thickness = {}
local c_chest = minetest.get_content_id("chest_with_everything:chest")
local c_air = minetest.get_content_id("air")
local c_stone = minetest.get_content_id("stone")
minetest.register_on_generated(function(vm, min, max)
-- AABB intersection, to determine whether this block should be considered for this mapgen.
if not intersection(min, max, REALM_START, REALM_END) then return end
local va = VoxelArea(vm:get_emerged_area())
local sides2d = {x = max.x - min.x + 1, y = max.z - min.z + 1}
local surface = minetest.get_perlin_map(np_surface, sides2d)
surface:get_2d_map_flat({x = min.x, y = min.z}, n_surface)
local thickness = minetest.get_perlin_map(np_thickness, sides2d)
thickness:get_2d_map_flat({x = min.x, y = min.z}, n_thickness)
vm:get_data(vm_data)
local ni = 1
for z = min.z, max.z do
for x = min.x, max.x do
local r = math.sqrt(x *x + z *z)
local bottom = -(3 +n_thickness[ni] *5 +((1 -(r /100))^0.5 *50))
local top = (n_surface[ni] +1) *8 *(1 -(math.max(0, r -90) /10))^0.5
for y = min.y, max.y do
if y > bottom and y < top then
local vi = va:index(x, y, z)
vm_data[vi] = c_stone
end
if x == 0 and z == 0 and y == math.round(top) then
local vi = va:index(x, y, z)
vm_data[vi] = c_chest
end
end
ni = ni +1
end
end
vm:set_data(vm_data)
end)

View file

@ -0,0 +1,2 @@
name = firefly_lobby
depends = firefly_state

View file

@ -0,0 +1 @@
{"asset":{"version":"2.0","generator":"Blockbench 4.12.5 glTF exporter"},"scenes":[{"nodes":[2],"name":"blockbench_export"}],"scene":0,"nodes":[{"translation":[0,0,-1.25],"name":"cube","mesh":0},{"translation":[0,-5,-1.25],"name":"cube","mesh":1},{"children":[0,1]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":288,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":576,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":768,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":840,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1128,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1416,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":1608,"byteLength":72,"target":34963}],"buffers":[{"byteLength":1680,"uri":"data:application/octet-stream;base64,AACgQAAAjEAAACA/AACgQAAAjEAAACC/AACgQAAAcMAAACA/AACgQAAAcMAAACC/AACgwAAAjEAAACC/AACgwAAAjEAAACA/AACgwAAAcMAAACC/AACgwAAAcMAAACA/AACgwAAAjEAAACC/AACgQAAAjEAAACC/AACgwAAAjEAAACA/AACgQAAAjEAAACA/AACgwAAAcMAAACA/AACgQAAAcMAAACA/AACgwAAAcMAAACC/AACgQAAAcMAAACC/AACgwAAAjEAAACA/AACgQAAAjEAAACA/AACgwAAAcMAAACA/AACgQAAAcMAAACA/AACgQAAAjEAAACC/AACgwAAAjEAAACC/AACgQAAAcMAAACC/AACgwAAAcMAAACC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAPwAAAD8AABA/AAAAPwAAAD8AAGg/AAAQPwAAaD8AABA/AAAAPwAAID8AAAA/AAAQPwAAaD8AACA/AABoPwAAgD8AAKA+AAAAPwAAoD4AAIA/AACAPgAAAD8AAIA+AACAPwAAoD4AAAA/AACgPgAAgD8AAMA+AAAAPwAAwD4AAAAAAADQPgAAAD8AANA+AAAAAAAAUD8AAAA/AABQPwAAAAAAAAAAAAAAPwAAAAAAAAAAAADQPgAAAD8AANA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAACgQAAAoD8AAKA/AACgQAAAoD8AAKC/AACgQAAAAAAAAKA/AACgQAAAAAAAAKC/AACgwAAAoD8AAKC/AACgwAAAoD8AAKA/AACgwAAAAAAAAKC/AACgwAAAAAAAAKA/AACgwAAAoD8AAKC/AACgQAAAoD8AAKC/AACgwAAAoD8AAKA/AACgQAAAoD8AAKA/AACgwAAAAAAAAKA/AACgQAAAAAAAAKA/AACgwAAAAAAAAKC/AACgQAAAAAAAAKC/AACgwAAAoD8AAKA/AACgQAAAoD8AAKA/AACgwAAAAAAAAKA/AACgQAAAAAAAAKA/AACgQAAAoD8AAKC/AACgwAAAoD8AAKC/AACgQAAAAAAAAKC/AACgwAAAAAAAAKC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAgPwAAAD8AAEA/AAAAPwAAID8AABA/AABAPwAAED8AACA/AAAQPwAAQD8AABA/AAAgPwAAID8AAEA/AAAgPwAAgD8AAAA+AAAAPwAAAD4AAIA/AAAAAAAAAD8AAAAAAACAPwAAAD4AAAA/AAAAPgAAgD8AAIA+AAAAPwAAgD4AAAA/AADgPgAAgD8AAOA+AAAAPwAAAD8AAIA/AAAAPwAAAD8AAMA+AACAPwAAwD4AAAA/AADgPgAAgD8AAOA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUA"}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[5,4.375,0.625],"min":[-5,-3.75,-0.625],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"max":[1,0.90625],"min":[0,0],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":4,"componentType":5126,"count":24,"max":[5,1.25,1.25],"min":[-5,0,-1.25],"type":"VEC3"},{"bufferView":5,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":6,"componentType":5126,"count":24,"max":[1,0.625],"min":[0.5,0],"type":"VEC2"},{"bufferView":7,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"}],"materials":[{"pbrMetallicRoughness":{"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0}},"alphaMode":"MASK","alphaCutoff":0.05,"doubleSided":true}],"textures":[{"sampler":0,"source":0,"name":"texture"}],"samplers":[{"magFilter":9728,"minFilter":9728,"wrapS":33071,"wrapT":33071}],"images":[{"mimeType":"image/png","name":"texture","uri":"texture.png"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":4,"NORMAL":5,"TEXCOORD_0":6},"indices":7,"material":0}]}]}

View file

@ -0,0 +1 @@
{"asset":{"version":"2.0","generator":"Blockbench 4.12.5 glTF exporter"},"scenes":[{"nodes":[1],"name":"blockbench_export"}],"scene":0,"nodes":[{"translation":[0,-5,-4.375],"name":"cube","mesh":0},{"children":[0]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":288,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":576,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":768,"byteLength":72,"target":34963}],"buffers":[{"byteLength":840,"uri":"data:application/octet-stream;base64,AADIQQAA8EEAACA/AADIQQAA8EEAACC/AADIQQAAAAAAACA/AADIQQAAAAAAACC/AADIwQAA8EEAACC/AADIwQAA8EEAACA/AADIwQAAAAAAACC/AADIwQAAAAAAACA/AADIwQAA8EEAACC/AADIQQAA8EEAACC/AADIwQAA8EEAACA/AADIQQAA8EEAACA/AADIwQAAAAAAACA/AADIQQAAAAAAACA/AADIwQAAAAAAACC/AADIQQAAAAAAACC/AADIwQAA8EEAACA/AADIQQAA8EEAACA/AADIwQAAAAAAACA/AADIQQAAAAAAACA/AADIQQAA8EEAACC/AADIwQAA8EEAACC/AADIQQAAAAAAACC/AADIwQAAAAAAACC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACgPgAAgDwAAKQ+AACAPAAAoD4AAFA+AACkPgAAUD4AAKA+AABQPgAApD4AAFA+AACgPgAAyD4AAKQ+AADIPgAAID8AAAA8AACgPgAAADwAACA/AAAAAAAAoD4AAAAAAAAgPwAAADwAAKA+AAAAPAAAID8AAIA8AACgPgAAgDwAAAAAAABAPgAAoD4AAEA+AAAAAAAAwD4AAKA+AADAPgAAAAAAAAAAAACgPgAAAAAAAAAAAABAPgAAoD4AAEA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUA"}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[25,30,0.625],"min":[-25,0,-0.625],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"max":[0.625,0.390625],"min":[0,0],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"}],"materials":[{"pbrMetallicRoughness":{"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0}},"alphaMode":"MASK","alphaCutoff":0.05,"doubleSided":true}],"textures":[{"sampler":0,"source":0,"name":"texture"}],"samplers":[{"magFilter":9728,"minFilter":9728,"wrapS":33071,"wrapT":33071}],"images":[{"mimeType":"image/png","name":"firefly_screen.png","uri":"firefly_screen.png"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B