summaryrefslogtreecommitdiff
path: root/main.lua
diff options
context:
space:
mode:
Diffstat (limited to 'main.lua')
-rw-r--r--main.lua213
1 files changed, 35 insertions, 178 deletions
diff --git a/main.lua b/main.lua
index 2463bdd..098a65b 100644
--- a/main.lua
+++ b/main.lua
@@ -1,28 +1,4 @@
require 'honey.std'
-local paused = true
-local balls = {}
-
-local function formatize(f)
- return function(fmt, ...)
- f(string.format(fmt, ...))
- end
-end
-local printf = formatize(print)
-local log = honey.log
-log.fatal = formatize(log.fatal)
-log.error = formatize(log.error)
-log.warn = formatize(log.warn)
-log.info = formatize(log.info)
-log.debug = formatize(log.debug)
-log.trace = formatize(log.trace)
-
-log.info(
- "honey v%d.%d.%d -- %s",
- honey.version.major,
- honey.version.minor,
- honey.version.patch,
- honey.version.string
-)
local glfw = honey.glfw
local gl = honey.gl
@@ -43,80 +19,14 @@ local vg = nvg.CreateContext()
local november = nvg.CreateFont(vg, "November", "assets/november.regular.ttf")
local vw, vh = 640, 480
+
-- create camera matrices
local camera = {
view=Mat4():identity():translate(Vec3{0, 0, -30}),
projection=Mat4():perspective(math.rad(45), 640/480, 0.1, 100),
}
--- setup ecs
-local level = ecs.Level()
-level:addSystem(systems.transformCascade)
-level:addSystem(systems.renderCam(camera))
-level:addSystem(systems.update)
-
--- physics system
-local world = ode.WorldCreate()
-local space = ode.HashSpaceCreate(ode.Space0)
-level:addSystem{
- setup=function(self)
- self.time = 0
- self.world=world
- self.space=space
- ode.WorldSetGravity(self.world, 0, -100, 0)
- ode.WorldSetCFM(self.world, 1e-5)
- self.contactgroup = ode.JointGroupCreate(200)
- self.__gc = honey.util.gc_canary(function()
- ode.WorldDestroy(self.world)
- ode.SpaceDestroy(self.space)
- end)
- end,
- filter = ecs.Filter.AND{"transform", "collisionShape", "physicsBody"},
- preUpdate = function(self)
- self.dt = nil
- if self.time > 0.01 then
- self.time = self.time - 0.01
- ode.SpaceCollide(self.space, function(o1, o2)
- local b1 = ode.GeomGetBody(o1)
- local b2 = ode.GeomGetBody(o2)
- local contact = ode.CreateContact{
- surface = {
- mode = ode.ContactBounce + ode.ContactSoftCFM,
- mu = ode.Infinity,
- bounce = 0.90,
- bounce_vel = 0.1,
- soft_cfm = 0.001,
- },
- }
- local collisions = ode.Collide(o1, o2, 1)
- if #collisions > 0 then
- local e1 = ode.GeomGetData(o1)
- local e2 = ode.GeomGetData(o2)
- ode.ContactSetGeom(contact, collisions[1])
- local joint = ode.JointCreateContact(self.world, self.contactgroup, contact)
- ode.JointAttach(joint, b1, b2)
- end
- end)
- ode.WorldQuickStep(self.world, 0.01)
- ode.JointGroupEmpty(self.contactgroup)
- end
- end,
- update = function(self, entity, dt)
- if not self.dt then
- self.dt = dt
- self.time = self.time + dt
- end
- local x, y, z = ode.BodyGetPosition(entity.physicsBody)
- local d, a, b, c = ode.BodyGetQuaternion(entity.physicsBody)
- entity.transform:identity():translate(Vec3{x, y, z}):mul(Quaternion{a, b, c, d}:toMat4())
- end,
- onRemoveEntity = function(self, id, entity)
- print("remove", id)
- ode.GeomDestroy(entity.collisionShape)
- ode.BodyDestroy(entity.physicsBody)
- end,
-}
-- create shader
local shader = honey.Shader{
@@ -132,97 +42,12 @@ local octa = honey.mesh.loadFile("assets/octahedron.obj")[1]
local dodeca = honey.mesh.loadFile("assets/dodecahedron.obj")[1]
local icosa = honey.mesh.loadFile("assets/icosahedron.obj")[1]
--- update function for each entity
-function updateTransform(self, dt)
- self.transform:rotateY(0.3 * math.pi * dt)
- self.transform:rotateX(0.1 * math.pi * dt)
-end
-
--- create entities
-function growLine(prev, depth)
- if depth == 0 then return prev end
-
- local entity = {
- transform=Mat4():identity():translate(Vec3{2, 0, 0}),
- parent=false,
- mesh=octa,
- shader=shader,
- update=updateTransform,
- }
- prev.parent = entity
- level:addEntity(prev)
- return growLine(entity, depth-1)
-end
-
-local leaf = {
- transform=Mat4():identity():translate(Vec3{2, 0, 0}),
- parent=false,
- mesh=tetra,
- shader=shader,
-}
-local root = growLine(leaf, 24)
-root.update = function(self, dt)
- self.transform:rotateY(0.2 * math.pi * dt)
-end
-level:addEntity(root)
-
-local groundPlane = {
- transform=Mat4():identity():translate(Vec3{0, -2, 0}):scale(Vec3{10, 10, 10}),
- parent=false,
- mesh=plane,
- shader=shader,
-}
-level:addEntity(groundPlane)
-
-
-local function createNewBall()
- local ball = {
- transform=Mat4():identity(),
- parent=false,
- mesh=icosa,
- shader=shader,
- collisionShape=ode.CreateSphere(space, 1.0),
- physicsBody=ode.BodyCreate(world),
- }
-
- local id = level:addEntity(ball)
- ball.id = id
- table.insert(balls, id)
- if #balls > 200 then
- level:removeEntity(table.remove(balls, 1))
- end
-
- local mass = ode.MassCreate()
- ode.MassSetSphere(mass, 1, 0.5)
- ode.BodySetMass(ball.physicsBody, mass)
- local function tiny() return (6 * math.random()) - 3 end
- local x, y, z = tiny(), tiny(), tiny()
- ode.GeomSetBody(ball.collisionShape, ball.physicsBody)
- ode.BodySetPosition(ball.physicsBody, x, y, z)
- ode.BodySetLinearVel(ball.physicsBody, x, y, z)
- ode.GeomSetData(ball.collisionShape, ball)
-end
-createNewBall()
-
-ode.CreatePlane(space, 0, 1, 0, -2)
-- close window on ESCAPE key
window:setKeyCallback(function(_, key, scancode, action)
if action == glfw.PRESS then
if key == glfw.KEY_ESCAPE then
window:setShouldClose(true)
- elseif key == glfw.KEY_SPACE then
- paused = not paused
- elseif
- key == glfw.KEY_Z or
- key == glfw.KEY_X or
- key == glfw.KEY_C or
- key == glfw.KEY_V or
- key == glfw.KEY_B or
- key == glfw.KEY_N or
- key == glfw.KEY_M
- then
- createNewBall()
end
end
end)
@@ -248,15 +73,47 @@ function averager(memory)
end
local fpsAverage = averager(200)
+
+-- setup ecs
+local edb = ecs.EntityDb()
+local sdb = ecs.SystemDb()
+
+sdb:addSystem{
+ update = function(self, dt)
+ local entities = self.db:queryComponent("renderMesh")
+ for entity, tbl in pairs(entities) do
+ tbl.shader:use()
+ tbl.shader:configure{matrix={
+ view=camera.view,
+ projection=camera.projection,
+ model=Mat4():identity(),
+ }}
+ local mesh = honey.mesh.loadMesh(tbl.mesh.filename, tbl.mesh.index)
+ mesh:drawElements()
+ end
+ end,
+ db = edb,
+ priority = 99,
+}
+
+
+local id = edb:createEntity()
+edb:addComponent(id, "renderMesh", {
+ shader = shader,
+ mesh = { filename="assets/icosahedron.obj", index=1 },
+})
+
+
+
-- main loop
honey.loop(window, function(dt)
gl.ClearColor(0.2, 0.4, 1.0, 1.0)
gl.Clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT + gl.STENCIL_BUFFER_BIT)
- gl.UseProgram(0)
gl.Enable(gl.DEPTH_TEST)
+ gl.Disable(gl.CULL_FACE)
- level:update(dt, paused)
+ sdb:update(dt)
nvg.BeginFrame(vg, vw, vh, 1.0)
nvg.StrokeColor(vg, nvg.RGBf(1, 1, 1))
nvg.FontFace(vg, "November")