Compare commits

...

4 Commits

Author SHA1 Message Date
db4809d385
add obj loader 2025-02-21 02:03:50 +03:00
82da17287e
fix vector3 fields in server 2025-02-21 02:03:08 +03:00
71c045c797
add music 2025-02-20 23:40:42 +03:00
b7e027cdc6
some type stuff 2025-02-16 00:19:54 +03:00
7 changed files with 182 additions and 10 deletions

BIN
data/images/measure002a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

38
data/models/unit_cube.obj Normal file
View File

@ -0,0 +1,38 @@
# Blender 4.0.2
# www.blender.org
o Cube
v -0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v 0.500000 0.500000 0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 0.500000 -0.500000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/3/2 8/5/2 7/6/2
f 7/6/3 8/5/3 6/7/3 5/8/3
f 5/8/4 6/7/4 2/9/4 1/10/4
f 3/11/5 7/6/5 5/8/5 1/12/5
f 8/5/6 4/13/6 2/14/6 6/7/6

BIN
data/music/bg1.xm Normal file

Binary file not shown.

View File

@ -0,0 +1,125 @@
---@class Obj
---@field model string
---@field texture string
---@field texture_size integer
---@field position Vector3
---@field triangles table
local Obj = {}
local Vector3 = require "types.vector3"
Obj.__index = Obj
local function string_split(str, delimiter)
local res = {}
local i = 0
local f
local match = '(.-)' .. delimiter .. '()'
if string.find(str, delimiter) == nil then
return {str}
end
for sub, j in string.gmatch(str, match) do
i = i + 1
res[i] = sub
f = j
end
if i ~= 0 then
res[i+1] = string.sub(str, f)
end
return res
end
---parses the obj file and triangulates it for drawing
---@param model string path to obj model
---@param texture {file: string, size: number}
---@param position Vector3?
---@return Obj
function Obj.create(model, texture, position)
local pos
if position ~= nil then
pos = position
else
pos = Vector3()
end
local obj = {
model = model,
texture = texture.file,
texture_size = texture.size,
position = pos:copy(),
triangles = {}
}
obj.position = obj.position:copy()
setmetatable(obj, Obj)
-- adapted from https://github.com/karai17/lua-obj/blob/master/obj_loader.lua
-- Copyright (c) 2014 Landon Manning - LManning17@gmail.com - LandonManning.com
-- MIT
local file = file_read{file = obj.model}
local lines = string_split(file, "\r?\n")
local obj_data = {
v = {},
vt = {},
f = {},
}
for _, line in ipairs(lines) do
local l = string_split(line, "%s+")
if l[1] == "v" then
local v = {
x = tonumber(l[2]),
y = tonumber(l[3]),
z = tonumber(l[4]),
}
table.insert(obj_data.v, v)
elseif l[1] == "vt" then
local vt = {
x = tonumber(l[2]) * obj.texture_size,
y = tonumber(l[3]) * obj.texture_size,
}
table.insert(obj_data.vt, vt)
elseif l[1] == "f" then
local f = {}
for i = 2, #l do
local split = string_split(l[i], "/")
local v = {}
v.v = tonumber(split[1])
if split[2] ~= "" then v.vt = tonumber(split[2]) end
-- v.vn = tonumber(split[3])
table.insert(f, v)
end
table.insert(obj_data.f, f)
end
end
for _, face in ipairs(obj_data.f) do
for i = 2, #face - 1 do
local triangle = {
v0 = obj_data.v[face[1].v],
v1 = obj_data.v[face[i].v],
v2 = obj_data.v[face[i + 1].v],
uv0 = obj_data.vt[face[1].vt],
uv1 = obj_data.vt[face[i].vt],
uv2 = obj_data.vt[face[i + 1].vt],
texture = obj.texture
}
table.insert(obj.triangles, triangle)
end
end
return obj
end
function Obj:draw()
for _, triangle in ipairs(self.triangles) do
local newt = util.shallow_copy(triangle)
newt.v0 = Vector3(triangle.v0) + self.position
newt.v1 = Vector3(triangle.v1) + self.position
newt.v2 = Vector3(triangle.v2) + self.position
draw_triangle(newt)
end
end
return Obj

View File

@ -3,10 +3,16 @@ local player = require "classes.player"
local Vector3 = require "types.vector3"
local List = require "types.list"
local Obj = require "classes.obj"
local cube = Obj.create("models/unit_cube.obj", {file = "images/measure002a.png", size = 512}, Vector3(0, 1, 0))
local Feed = require "classes.feed"
---@type List
local feed = List()
local Duck = require "classes.duck"
---@type List
local ducks = List()
local function create_feed(position, direction)
@ -38,10 +44,7 @@ end
function game_tick()
-- ctx.initialization_needed is true first frame and every time dynamic reload is performed
if ctx.initialization_needed then
-- ctx.udata persists on reload
ctx.udata = {
capture = false,
}
audio_play{audio = "music/bg1.xm", loops = true, channel = "music"}
player.ThrowPressed:connect(create_feed)
-- spawn some ducks
@ -52,7 +55,13 @@ function game_tick()
duck.SeekFeed:connect(duck_seek_feed)
duck.index = i
end
end
-- ctx.udata persists on reload
if ctx.udata == nil then
ctx.udata = {
capture = false,
}
end
ctx.mouse_capture = ctx.udata.capture
@ -77,4 +86,7 @@ function game_tick()
texture_region = { x = 0, y = 0, w = 512, h = 512 },
}
draw_quad(util.merge(q, params))
cube.position.x = math.sin(ctx.frame_number * 0.01)
cube.position.z = math.cos(ctx.frame_number * 0.01)
cube:draw()
end

View File

@ -154,7 +154,7 @@ function List:shuffled()
end
---Returns a sorted copy of this list.
---@param f? fun(a: any, b: any)
---@param f? fun(a: any, b: any): boolean
---@return List
function List:sorted(f)
local list = self:copy()

View File

@ -1,8 +1,5 @@
--- @class Vector3
--- @field x number
--- @field y number
--- @field z number
--- @alias vectorlike number[] | Vector3
--- @class Vector3
local Vector3 = {
x = 0,
y = 0,