diff options
author | sanine-a <sanine.not@pm.me> | 2023-04-14 15:44:38 -0500 |
---|---|---|
committer | sanine-a <sanine.not@pm.me> | 2023-04-14 15:44:38 -0500 |
commit | 01a8b2a3d98f816b8b712a974f3d1e98f05152f5 (patch) | |
tree | 742c9375bd533c45f8ebd01278c336177ae614ab /honey | |
parent | 64194866e9a1d6991efc9f44a0e3075905ab6470 (diff) |
implement loading/saving entity db
Diffstat (limited to 'honey')
-rw-r--r-- | honey/ecs-systems.lua | 103 | ||||
-rw-r--r-- | honey/ecs.lua | 67 | ||||
-rw-r--r-- | honey/glm.lua | 12 |
3 files changed, 132 insertions, 50 deletions
diff --git a/honey/ecs-systems.lua b/honey/ecs-systems.lua index cfd5675..969b6fe 100644 --- a/honey/ecs-systems.lua +++ b/honey/ecs-systems.lua @@ -85,51 +85,52 @@ function renderCamera(params) db = params.db, priority = params.priority or 99, update = function(self, dt) - local cameraParams = self.db:getComponent(self.camera, "camera") - local cameraTransform = self.db:getComponent(self.camera, "transform") - local view - if cameraTransform then - view = cameraTransform._matrix - else - view = Mat4():identity() - end - - local entities = self.db:queryComponent("renderMesh") - for entity, tbl in pairs(entities) do - -- get shader - local shader = honey.shader.loadShader(tbl.shader.vertex, tbl.shader.fragment) - shader:use() - - -- bind textures - local texOffset = 0 - for name, texTbl in pairs(tbl.textures or {}) do - local texture = honey.image.loadImage(texTbl.filename, texTbl.params) - gl.BindTexture(gl.TEXTURE_2D + texOffset, texture.texture) - shader:setInt(name, texOffset) - texOffset = texOffset + 1 + for id, camera in pairs(self.db:queryComponent("camera")) do + local cameraTransform = self.db:getComponent(id, "transform") + local view + if cameraTransform then + view = cameraTransform._matrix + else + view = Mat4():identity() end - - -- configure default uniforms - local query = self.db:getComponent(entity, "transform") - local model = (query and query._matrix) or Mat4():identity() - shader:configure{ - float={ - time=glfw.GetTime(), - }, - matrix={ - view=view, - projection=cameraParams.projection, - model=model, - }, - } - - -- draw mesh - local mesh = honey.mesh.loadMesh(tbl.mesh.filename, tbl.mesh.index) - mesh:drawElements() - - -- unbind textures - for i=0,texOffset-1 do - gl.BindTexture(gl.TEXTURE_2D + i, 0) + + local entities = self.db:queryComponent("renderMesh") + for entity, tbl in pairs(entities) do + -- get shader + local shader = honey.shader.loadShader(tbl.shader.vertex, tbl.shader.fragment) + shader:use() + + -- bind textures + local texOffset = 0 + for name, texTbl in pairs(tbl.textures or {}) do + local texture = honey.image.loadImage(texTbl.filename, texTbl.params) + gl.BindTexture(gl.TEXTURE_2D + texOffset, texture.texture) + shader:setInt(name, texOffset) + texOffset = texOffset + 1 + end + + -- configure default uniforms + local query = self.db:getComponent(entity, "transform") + local model = (query and query._matrix) or Mat4():identity() + shader:configure{ + float={ + time=glfw.GetTime(), + }, + matrix={ + view=view, + projection=camera.projection, + model=model, + }, + } + + -- draw mesh + local mesh = honey.mesh.loadMesh(tbl.mesh.filename, tbl.mesh.index) + mesh:drawElements() + + -- unbind textures + for i=0,texOffset-1 do + gl.BindTexture(gl.TEXTURE_2D + i, 0) + end end end end, @@ -171,7 +172,15 @@ physics = function(params) local query = self.db:queryComponent("physics") for id, physics in pairs(query) do if not physics._body then + print("creating physics body for "..id) + for k,v in pairs(physics) do + print(k, v) + end physics._body = ode.BodyCreate(self.world) + physics._gc = honey.util.gc_canary(function() + print("releasing physics body for " .. id) + ode.BodyDestroy(physics._body) + end) local mass = ode.MassCreate() local class = physics.mass.class if not class then @@ -183,24 +192,30 @@ physics = function(params) physics.mass.radius ) end + print('mass') ode.BodySetMass(physics._body, mass) local m = self.db:getComponent(id, "transform").matrix + print(m) + print('pos') ode.BodySetPosition( physics._body, m[1][4], m[2][4], m[3][4] ) + print('rot') ode.BodySetRotation( physics._body, m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3] ) + print('vel') ode.BodySetLinearVel( physics._body, physics.velocity[1], physics.velocity[2], physics.velocity[3] ) + print('lvel') ode.BodySetAngularVel( physics._body, physics.angularVelocity[1], diff --git a/honey/ecs.lua b/honey/ecs.lua index 39f1c77..d544a37 100644 --- a/honey/ecs.lua +++ b/honey/ecs.lua @@ -1,5 +1,7 @@ math.randomseed(os.time()) +local glm = require 'honey.glm' + local module = {} setmetatable(module, {__index=_G}) setfenv(1, module) @@ -28,6 +30,71 @@ end setmetatable(EntityDb, {__call=EntityDb.new}) +local function serialize(tbl) + local tostr = function(x, value) + if type(x) == "table" then + if x.__tostring then + return tostring(x) + else + return serialize(x) + end + elseif type(x) == "string" then + if value then + return string.format("\"%s\"", x) + else + return x + end + else + return tostring(x) + end + end + local str = "{" + for key, value in pairs(tbl) do + if type(key) == "string" and string.match(key, "^_") then + -- ignore keys starting with an underscore + else + str = str .. string.format("%s=%s,", tostr(key), tostr(value, true)) + end + end + str = string.sub(str, 1, -2) .. "}" + return str +end + + +-- save current database to file +function EntityDb.save(self, filename) + local file, err = io.open(filename, "w") + if not file then error(err) end + + for entity in pairs(self.entities) do + local components = self:queryEntity(entity) + file:write(string.format("Entity(\"%s\", %s)\n", entity, serialize(components))) + end + + file:close() +end + + +-- load database from file +function EntityDb.load(self, filename) + self.entities = {} + self.components = {} + local env = { + Entity = function(id, components) + print("add entity:", id) + self:createEntity(id) + self:addComponents(id, components) + end, + Vec3 = glm.Vec3, + Mat4 = glm.Mat4, + } + local f, err = loadfile(filename) + if not f then error(err) end + setfenv(f, env) + f() +end + + -- check if a given entity id is legitimate function EntityDb.checkIsValid(self, id) if not self.entities[id] then diff --git a/honey/glm.lua b/honey/glm.lua index dada37f..3357815 100644 --- a/honey/glm.lua +++ b/honey/glm.lua @@ -42,7 +42,7 @@ end function Vec3.__tostring(self) - return string.format("Vec3[%.4f, %.4f, %.4f]", self[1], self[2], self[3]) + return string.format("Vec3{%.4f, %.4f, %.4f}", self[1], self[2], self[3]) end @@ -196,7 +196,7 @@ end --===== Mat4 =====-- -function Mat4.new(_, self, values) +function Mat4.new(_, values) local self = {} self.type = "mat4" self.data = glm.mat4_create() @@ -238,10 +238,10 @@ end function Mat4.__tostring(self) return string.format( - "/ %0.4f, %0.4f, %0.4f, %0.4f \\\n" .. - "| %0.4f, %0.4f, %0.4f, %0.4f |\n" .. - "| %0.4f, %0.4f, %0.4f, %0.4f |\n" .. - "\\ %0.4f, %0.4f, %0.4f, %0.4f /", + "Mat4{%0.4f, %0.4f, %0.4f, %0.4f, " .. + "%0.4f, %0.4f, %0.4f, %0.4f, " .. + "%0.4f, %0.4f, %0.4f, %0.4f, " .. + "%0.4f, %0.4f, %0.4f, %0.4f}", self[1][1], self[1][2], self[1][3], self[1][4], self[2][1], self[2][2], self[2][3], self[2][4], self[3][1], self[3][2], self[3][3], self[3][4], |