From ba458be334de1f2e58065f3a163c3e9b64593dc1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 23 Jun 2024 22:09:04 +0300 Subject: [PATCH 001/178] add test entities prototype --- src/graphics/render/WorldRenderer.cpp | 3 +- src/logic/LevelController.cpp | 2 + src/objects/Entities.cpp | 55 ++++++++++++++++++++++++++ src/objects/Entities.hpp | 57 +++++++++++++++++++++++++++ src/typedefs.hpp | 1 + src/world/Level.cpp | 2 + src/world/Level.hpp | 2 + 7 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/objects/Entities.cpp create mode 100644 src/objects/Entities.hpp diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index f94939de..e6e89b96 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -15,6 +15,7 @@ #include "../../maths/FrustumCulling.hpp" #include "../../maths/voxmaths.hpp" #include "../../objects/Player.hpp" +#include "../../objects/Entities.hpp" #include "../../settings.hpp" #include "../../voxels/Block.hpp" #include "../../voxels/Chunk.hpp" @@ -195,7 +196,7 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - // draw entities here + level->entities->render(assets, *modelBatch); modelBatch->render(); skybox->unbind(); diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index d8afbc57..551beb71 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -6,6 +6,7 @@ #include "../world/Level.hpp" #include "../world/World.hpp" #include "../physics/Hitbox.hpp" +#include "../objects/Entities.hpp" #include "scripting/scripting.hpp" #include "../interfaces/Object.hpp" @@ -47,6 +48,7 @@ void LevelController::update(float delta, bool input, bool pause) { } } blocks->update(delta); + level->entities->updatePhysics(delta); } } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp new file mode 100644 index 00000000..674ae1f1 --- /dev/null +++ b/src/objects/Entities.cpp @@ -0,0 +1,55 @@ +#include "Entities.hpp" + +#include "../assets/Assets.hpp" +#include "../world/Level.hpp" +#include "../physics/Hitbox.hpp" +#include "../physics/PhysicsSolver.hpp" +#include "../graphics/render/ModelBatch.hpp" +#include "../graphics/core/Model.hpp" + +#include + +void Transform::refresh() { + combined = glm::mat4(1.0f); + combined = glm::translate(combined, pos); +} + +Entities::Entities(Level* level) : level(level) { + auto entity = registry.create(); + glm::vec3 pos(0.5f, 170, 0.5f); + glm::vec3 size(1); + registry.emplace(entity, 1); + registry.emplace(entity, pos, size, glm::mat3(1.0f)); + registry.emplace(entity, pos, size/20.0f); +} + +void Entities::updatePhysics(float delta){ + auto view = registry.view(); + auto physics = level->physics.get(); + for (auto [entity, transform, hitbox] : view.each()) { + physics->step( + level->chunks.get(), + &hitbox, + delta, + 10, + false, + 1.0f, + true + ); + transform.pos = hitbox.position; + if (hitbox.grounded) { + hitbox.velocity.y = 10; + } + } +} + +void Entities::render(Assets* assets, ModelBatch& batch) { + auto view = registry.view(); + auto model = assets->get("dingus"); + for (auto [entity, transform] : view.each()) { + transform.refresh(); + batch.pushMatrix(transform.combined); + batch.draw(model); + batch.popMatrix(); + } +} diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp new file mode 100644 index 00000000..0c725f89 --- /dev/null +++ b/src/objects/Entities.hpp @@ -0,0 +1,57 @@ +#ifndef OBJECTS_ENTITIES_HPP_ +#define OBJECTS_ENTITIES_HPP_ + +#include "../typedefs.hpp" + +#include +#include +#include + +struct EntityId { + entityid_t uid; +}; + +struct Transform { + glm::vec3 pos; + glm::vec3 size; + glm::mat3 rot; + glm::mat4 combined; + + void refresh(); +}; + +class Level; +class Assets; +class ModelBatch; + +class Entity { + entt::registry& registry; + entt::entity entity; +public: + Entity(entt::registry& registry, entt::entity entity) + : registry(registry), entity(entity) {} + + bool isValid() const { + return registry.valid(entity); + } + + Transform& getTransform() const { + return registry.get(entity); + } + + entityid_t getUID() const { + return registry.get(entity).uid; + } +}; + +class Entities { + entt::registry registry; + Level* level; + std::unordered_map entities; +public: + Entities(Level* level); + void updatePhysics(float delta); + void render(Assets* assets, ModelBatch& batch); +}; + +#endif // OBJECTS_ENTITIES_HPP_ diff --git a/src/typedefs.hpp b/src/typedefs.hpp index 7b065aa3..0d8b9b6e 100644 --- a/src/typedefs.hpp +++ b/src/typedefs.hpp @@ -21,6 +21,7 @@ using ubyte = uint8_t; using itemid_t = uint32_t; using blockid_t = uint16_t; +using entityid_t = uint64_t; using itemcount_t = uint32_t; using blockstate_t = uint16_t; using light_t = uint16_t; diff --git a/src/world/Level.cpp b/src/world/Level.cpp index 1df81c74..84b10742 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -10,6 +10,7 @@ #include "../physics/Hitbox.hpp" #include "../physics/PhysicsSolver.hpp" #include "../objects/Player.hpp" +#include "../objects/Entities.hpp" #include "../items/Inventory.hpp" #include "../items/Inventories.hpp" @@ -22,6 +23,7 @@ Level::Level( chunksStorage(std::make_unique(this)), physics(std::make_unique(glm::vec3(0, -22.6f, 0))), events(std::make_unique()), + entities(std::make_unique(this)), settings(settings) { auto inv = std::make_shared( diff --git a/src/world/Level.hpp b/src/world/Level.hpp index 7b18f06f..3f57ac10 100644 --- a/src/world/Level.hpp +++ b/src/world/Level.hpp @@ -14,6 +14,7 @@ class Content; class World; class Player; class Chunks; +class Entities; class Inventory; class Inventories; class LevelEvents; @@ -35,6 +36,7 @@ public: std::unique_ptr physics; std::unique_ptr lighting; std::unique_ptr events; + std::unique_ptr entities; const EngineSettings& settings; From 69ddcb7595bac601cd89716f51ae855e0a185f8c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 24 Jun 2024 01:05:28 +0300 Subject: [PATCH 002/178] add test model --- res/content/base/models/cube.obj | 46 +++++++++++++++++++++++++++ res/content/base/preload.json | 3 ++ src/graphics/render/WorldRenderer.cpp | 2 +- src/maths/FrustumCulling.hpp | 18 ++++------- src/objects/Entities.cpp | 36 +++++++++++++-------- src/objects/Entities.hpp | 3 +- 6 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 res/content/base/models/cube.obj diff --git a/res/content/base/models/cube.obj b/res/content/base/models/cube.obj new file mode 100644 index 00000000..26a621ff --- /dev/null +++ b/res/content/base/models/cube.obj @@ -0,0 +1,46 @@ +# Blender v2.79 (sub 0) OBJ File: '' +# www.blender.org +mtllib cube.mtl +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 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +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 +usemtl blocks/stone +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/2 8/6/2 7/7/2 6/8/2 +f 1/1/3 5/9/3 6/10/3 2/11/3 +f 2/12/4 6/13/4 7/7/4 3/14/4 +f 3/15/5 7/16/5 8/17/5 4/4/5 +f 5/5/6 1/18/6 4/19/6 8/20/6 diff --git a/res/content/base/preload.json b/res/content/base/preload.json index 801938a6..238cab00 100644 --- a/res/content/base/preload.json +++ b/res/content/base/preload.json @@ -2,5 +2,8 @@ "sounds": [ "blocks/door_open", "blocks/door_close" + ], + "models": [ + "cube" ] } diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index e6e89b96..c7722fc9 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -196,7 +196,7 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - level->entities->render(assets, *modelBatch); + level->entities->render(assets, *modelBatch, *frustumCulling); modelBatch->render(); skybox->unbind(); diff --git a/src/maths/FrustumCulling.hpp b/src/maths/FrustumCulling.hpp index 309fc1ba..f8372c14 100644 --- a/src/maths/FrustumCulling.hpp +++ b/src/maths/FrustumCulling.hpp @@ -3,8 +3,7 @@ #include -class Frustum -{ +class Frustum { public: Frustum() {}; @@ -12,8 +11,7 @@ public: bool isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const; private: - enum Planes - { + enum Planes { Left = 0, Right, Bottom, @@ -25,8 +23,7 @@ private: }; template - struct ij2k - { + struct ij2k { enum { k = i * (9 - i) / 2 + j - 1 }; }; @@ -37,8 +34,7 @@ private: glm::vec3 m_points[8]; }; -inline void Frustum::update(glm::mat4 m) -{ +inline void Frustum::update(glm::mat4 m) { m = glm::transpose(m); m_planes[Left] = m[3] + m[0]; m_planes[Right] = m[3] - m[0]; @@ -78,8 +74,7 @@ inline void Frustum::update(glm::mat4 m) inline bool Frustum::isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const { // check box outside/inside of frustum - for (int i = 0; i < Count; i++) - { + for (int i = 0; i < Count; i++) { if ((glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, minp.z, 1.0f)) < 0.0) && (glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, minp.z, 1.0f)) < 0.0) && (glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, minp.z, 1.0f)) < 0.0) && @@ -106,8 +101,7 @@ inline bool Frustum::isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) } template -inline glm::vec3 Frustum::intersection(const glm::vec3* crosses) const -{ +inline glm::vec3 Frustum::intersection(const glm::vec3* crosses) const { float D = glm::dot(glm::vec3(m_planes[a]), crosses[ij2k::k]); glm::vec3 res = glm::mat3(crosses[ij2k::k], -crosses[ij2k::k], crosses[ij2k::k]) * glm::vec3(m_planes[a].w, m_planes[b].w, m_planes[c].w); diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 674ae1f1..bdc59ad6 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -6,21 +6,26 @@ #include "../physics/PhysicsSolver.hpp" #include "../graphics/render/ModelBatch.hpp" #include "../graphics/core/Model.hpp" +#include "../maths/FrustumCulling.hpp" #include void Transform::refresh() { combined = glm::mat4(1.0f); combined = glm::translate(combined, pos); + combined = glm::scale(combined, size); + combined = combined * glm::mat4(rot); } Entities::Entities(Level* level) : level(level) { - auto entity = registry.create(); - glm::vec3 pos(0.5f, 170, 0.5f); - glm::vec3 size(1); - registry.emplace(entity, 1); - registry.emplace(entity, pos, size, glm::mat3(1.0f)); - registry.emplace(entity, pos, size/20.0f); + for (int i = 0; i < 1000; i++) { + auto entity = registry.create(); + glm::vec3 pos(0.5f+rand()%50, 100+i, 0.5f+rand()%50); + glm::vec3 size(1); + registry.emplace(entity, 1); + registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); + registry.emplace(entity, pos, size/2.0f); + } } void Entities::updatePhysics(float delta){ @@ -37,19 +42,24 @@ void Entities::updatePhysics(float delta){ true ); transform.pos = hitbox.position; + transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); if (hitbox.grounded) { - hitbox.velocity.y = 10; + //hitbox.velocity.y = 10; } } } -void Entities::render(Assets* assets, ModelBatch& batch) { +void Entities::render(Assets* assets, ModelBatch& batch, Frustum& frustum) { auto view = registry.view(); - auto model = assets->get("dingus"); + auto model = assets->get("cube"); for (auto [entity, transform] : view.each()) { - transform.refresh(); - batch.pushMatrix(transform.combined); - batch.draw(model); - batch.popMatrix(); + const auto& pos = transform.pos; + const auto& size = transform.size; + if (frustum.isBoxVisible(pos-size, pos+size)) { + transform.refresh(); + batch.pushMatrix(transform.combined); + batch.draw(model); + batch.popMatrix(); + } } } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 0c725f89..b203cfa6 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -23,6 +23,7 @@ struct Transform { class Level; class Assets; class ModelBatch; +class Frustum; class Entity { entt::registry& registry; @@ -51,7 +52,7 @@ class Entities { public: Entities(Level* level); void updatePhysics(float delta); - void render(Assets* assets, ModelBatch& batch); + void render(Assets* assets, ModelBatch& batch, Frustum& frustum); }; #endif // OBJECTS_ENTITIES_HPP_ From 4b20487c58d97b32d871a162d5be263644dc75be Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 24 Jun 2024 15:39:40 +0300 Subject: [PATCH 003/178] add drop test --- res/config/bindings.toml | 1 + res/content/base/models/cube.obj | 2 +- src/graphics/render/ModelBatch.cpp | 2 +- src/logic/PlayerController.cpp | 4 ++++ src/objects/Entities.cpp | 20 ++++++++++++-------- src/objects/Entities.hpp | 2 ++ 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/res/config/bindings.toml b/res/config/bindings.toml index e13be068..2d373cb9 100644 --- a/res/config/bindings.toml +++ b/res/config/bindings.toml @@ -15,4 +15,5 @@ player.flight="key:f" player.attack="mouse:left" player.build="mouse:right" player.pick="mouse:middle" +player.drop="key:q" hud.inventory="key:tab" diff --git a/res/content/base/models/cube.obj b/res/content/base/models/cube.obj index 26a621ff..c0daf3e8 100644 --- a/res/content/base/models/cube.obj +++ b/res/content/base/models/cube.obj @@ -36,7 +36,7 @@ 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 -usemtl blocks/stone +usemtl blocks/leaves s off f 1/1/1 2/2/1 3/3/1 4/4/1 f 5/5/2 8/6/2 7/7/2 6/8/2 diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 67be92e5..2d7c1e9d 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -54,7 +54,7 @@ ModelBatch::~ModelBatch() { void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation) { glm::vec3 gpos = matrix * glm::vec4(glm::vec3(), 1.0f); - light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); + light_t light = chunks->getLight(floor(gpos.x), floor(gpos.y), floor(gpos.z)); glm::vec4 lights ( Lightmap::extract(light, 0) / 15.0f, Lightmap::extract(light, 1) / 15.0f, diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 583be194..5885b728 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -6,6 +6,7 @@ #include "scripting/scripting.hpp" #include "../objects/Player.hpp" +#include "../objects/Entities.hpp" #include "../physics/PhysicsSolver.hpp" #include "../physics/Hitbox.hpp" #include "../lighting/Lighting.hpp" @@ -246,6 +247,9 @@ void PlayerController::update(float delta, bool input, bool pause) { camControl.refresh(); if (input) { updateInteraction(); + if (Events::jactive("player.drop")) { + level->entities->drop(player->camera->position, player->camera->front*10.0f+player->hitbox->velocity); + } } else { player->selection.vox.id = BLOCK_VOID; player->selection.vox.state.rotation = 0; diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index bdc59ad6..0c450aa9 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -18,14 +18,17 @@ void Transform::refresh() { } Entities::Entities(Level* level) : level(level) { - for (int i = 0; i < 1000; i++) { - auto entity = registry.create(); - glm::vec3 pos(0.5f+rand()%50, 100+i, 0.5f+rand()%50); - glm::vec3 size(1); - registry.emplace(entity, 1); - registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); - registry.emplace(entity, pos, size/2.0f); - } +} + +void Entities::drop(glm::vec3 pos, glm::vec3 vel) { + auto entity = registry.create(); + glm::vec3 size(1); + registry.emplace(entity, 1); + registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); + registry.emplace(entity, pos, size/2.0f); + + auto& hitbox = registry.get(entity); + hitbox.velocity = vel; } void Entities::updatePhysics(float delta){ @@ -41,6 +44,7 @@ void Entities::updatePhysics(float delta){ 1.0f, true ); + hitbox.linear_damping = hitbox.grounded * 5; transform.pos = hitbox.position; transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); if (hitbox.grounded) { diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index b203cfa6..0a05bfba 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -53,6 +53,8 @@ public: Entities(Level* level); void updatePhysics(float delta); void render(Assets* assets, ModelBatch& batch, Frustum& frustum); + + void drop(glm::vec3 pos, glm::vec3 vel); }; #endif // OBJECTS_ENTITIES_HPP_ From c9fc4a85b8856becb498a2ba371b3fd5d2a66a67 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 24 Jun 2024 16:53:07 +0300 Subject: [PATCH 004/178] fix msvc build --- src/objects/Entities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 0c450aa9..56f52318 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -23,7 +23,7 @@ Entities::Entities(Level* level) : level(level) { void Entities::drop(glm::vec3 pos, glm::vec3 vel) { auto entity = registry.create(); glm::vec3 size(1); - registry.emplace(entity, 1); + registry.emplace(entity, static_cast(1)); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); registry.emplace(entity, pos, size/2.0f); From 5a01eca7807fe362bbcdfe5b73efcaa3ddcebad2 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 24 Jun 2024 20:57:19 +0300 Subject: [PATCH 005/178] add entity models rigging draft --- src/logic/PlayerController.cpp | 2 +- src/objects/Entities.cpp | 3 ++- src/objects/Entities.hpp | 1 + src/objects/rigging.hpp | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/objects/rigging.hpp diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 5885b728..f7b3b85b 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -248,7 +248,7 @@ void PlayerController::update(float delta, bool input, bool pause) { if (input) { updateInteraction(); if (Events::jactive("player.drop")) { - level->entities->drop(player->camera->position, player->camera->front*10.0f+player->hitbox->velocity); + level->entities->drop(player->camera->position, player->camera->front*8.0f+glm::vec3(0, 2, 0)+player->hitbox->velocity); } } else { player->selection.vox.id = BLOCK_VOID; diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 56f52318..fd4fe76c 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -25,7 +25,8 @@ void Entities::drop(glm::vec3 pos, glm::vec3 vel) { glm::vec3 size(1); registry.emplace(entity, static_cast(1)); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); - registry.emplace(entity, pos, size/2.0f); + registry.emplace(entity, pos, + glm::vec3(size.x*0.2f, size.y*0.5f, size.z*0.2f)); auto& hitbox = registry.get(entity); hitbox.velocity = vel; diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 0a05bfba..8efc7197 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -24,6 +24,7 @@ class Level; class Assets; class ModelBatch; class Frustum; +class Rig; class Entity { entt::registry& registry; diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp new file mode 100644 index 00000000..a509533b --- /dev/null +++ b/src/objects/rigging.hpp @@ -0,0 +1,34 @@ +#ifndef OBJECTS_SKELETON_HPP_ +#define OBJECTS_SKELETON_HPP_ + +#include "../typedefs.hpp" + +#include +#include +#include + +namespace rigging { + struct Rig; + + struct Pose { + std::vector matrices; + }; + + class RigNode { + uint index; + std::vector> subnodes; + public: + RigNode(uint index); + }; + + class RigConfig { + std::unique_ptr root; + }; + + struct Rig { + RigConfig* config; + Pose pose; + }; +}; + +#endif // OBJECTS_SKELETON_HPP_ From 4b3ac95d71c0a361f22b339d58ef117cb6471969 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 24 Jun 2024 21:39:44 +0300 Subject: [PATCH 006/178] optimize res/content/base/models/cube --- res/content/base/models/cube.obj | 73 +++++++++++++++----------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/res/content/base/models/cube.obj b/res/content/base/models/cube.obj index c0daf3e8..8beb020e 100644 --- a/res/content/base/models/cube.obj +++ b/res/content/base/models/cube.obj @@ -1,43 +1,38 @@ -# Blender v2.79 (sub 0) OBJ File: '' -# www.blender.org -mtllib cube.mtl -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 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 1.0000 0.0000 -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 +v 0.5 -0.5 -0.5 +v 0.5 -0.5 0.5 +v -0.5 -0.5 0.5 +v -0.5 -0.5 -0.5 +v 0.5 0.5 -0.5 +v 0.5 0.5 0.5 +v -0.5 0.5 0.5 +v -0.5 0.5 -0.5 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vn 0.0 -1.0 0.0 +vn 0.0 1.0 0.0 +vn 1.0 0.0 0.0 +vn -0.0 -0.0 1.0 +vn -1.0 -0.0 -0.0 +vn 0.0 0.0 -1.0 usemtl blocks/leaves -s off f 1/1/1 2/2/1 3/3/1 4/4/1 f 5/5/2 8/6/2 7/7/2 6/8/2 f 1/1/3 5/9/3 6/10/3 2/11/3 From eacbc1b9d030dc8d85acd3685126fa55b475c9a8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 24 Jun 2024 23:36:20 +0300 Subject: [PATCH 007/178] add entity.test(...) function --- res/content/base/scripts/hud.lua | 5 +++++ src/logic/PlayerController.cpp | 3 --- src/logic/scripting/lua/api_lua.hpp | 1 + src/logic/scripting/lua/libentity.cpp | 26 ++++++++++++++++++++++++++ src/logic/scripting/lua/lua_engine.cpp | 1 + 5 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 res/content/base/scripts/hud.lua create mode 100644 src/logic/scripting/lua/libentity.cpp diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua new file mode 100644 index 00000000..8e605bb8 --- /dev/null +++ b/res/content/base/scripts/hud.lua @@ -0,0 +1,5 @@ +function on_hud_open() + input.add_callback("player.drop", function () + entity.test() + end) +end diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index f7b3b85b..a37128b8 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -247,9 +247,6 @@ void PlayerController::update(float delta, bool input, bool pause) { camControl.refresh(); if (input) { updateInteraction(); - if (Events::jactive("player.drop")) { - level->entities->drop(player->camera->position, player->camera->front*8.0f+glm::vec3(0, 2, 0)+player->hitbox->velocity); - } } else { player->selection.vox.id = BLOCK_VOID; player->selection.vox.state.rotation = 0; diff --git a/src/logic/scripting/lua/api_lua.hpp b/src/logic/scripting/lua/api_lua.hpp index 83130ec2..17eebcac 100644 --- a/src/logic/scripting/lua/api_lua.hpp +++ b/src/logic/scripting/lua/api_lua.hpp @@ -10,6 +10,7 @@ extern const luaL_Reg audiolib []; extern const luaL_Reg blocklib []; extern const luaL_Reg consolelib []; extern const luaL_Reg corelib []; +extern const luaL_Reg entitylib []; extern const luaL_Reg filelib []; extern const luaL_Reg guilib []; extern const luaL_Reg hudlib []; diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp new file mode 100644 index 00000000..5ab0181b --- /dev/null +++ b/src/logic/scripting/lua/libentity.cpp @@ -0,0 +1,26 @@ +#include "api_lua.hpp" + +#include "../../LevelController.hpp" +#include "../../../world/Level.hpp" +#include "../../../objects/Player.hpp" +#include "../../../objects/Entities.hpp" +#include "../../../physics/Hitbox.hpp" +#include "../../../window/Camera.hpp" +#include "../../../frontend/hud.hpp" + +namespace scripting { + extern Hud* hud; +} +using namespace scripting; + +static int l_test(lua::State* L) { + auto level = controller->getLevel(); + auto player = hud->getPlayer(); + level->entities->drop(player->camera->position, player->camera->front*8.0f+glm::vec3(0, 2, 0)+player->hitbox->velocity); + return 0; +} + +const luaL_Reg entitylib [] = { + {"test", lua::wrap}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index a64216a6..be8d2c1d 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -31,6 +31,7 @@ static void create_libs(lua::State* L) { openlib(L, "block", blocklib); openlib(L, "console", consolelib); openlib(L, "core", corelib); + openlib(L, "entity", entitylib); openlib(L, "file", filelib); openlib(L, "gui", guilib); openlib(L, "input", inputlib); From 8e931d8f538f5c822758cb05242a46e724a4064a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 25 Jun 2024 16:35:06 +0300 Subject: [PATCH 008/178] add entity library --- res/content/base/scripts/hud.lua | 5 ++++- src/logic/scripting/lua/libentity.cpp | 28 +++++++++++++++++++++++++-- src/logic/scripting/lua/lua_util.hpp | 10 ++++++++++ src/objects/Entities.cpp | 10 +++++----- src/objects/Entities.hpp | 21 +++++++++++++++++--- 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 8e605bb8..e33f5a0f 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -1,5 +1,8 @@ function on_hud_open() input.add_callback("player.drop", function () - entity.test() + local pid = hud.get_player() + local pvel = {player.get_vel(pid)} + local eid = entity.test() + entity.set_vel(eid, pvel) end) end diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 5ab0181b..859364a8 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -8,19 +8,43 @@ #include "../../../window/Camera.hpp" #include "../../../frontend/hud.hpp" +#include + namespace scripting { extern Hud* hud; } using namespace scripting; +static std::optional get_entity(lua::State* L, int idx) { + auto id = lua::tointeger(L, idx); + auto level = controller->getLevel(); + return level->entities->get(id); +} + static int l_test(lua::State* L) { auto level = controller->getLevel(); auto player = hud->getPlayer(); - level->entities->drop(player->camera->position, player->camera->front*8.0f+glm::vec3(0, 2, 0)+player->hitbox->velocity); - return 0; + auto id = level->entities->drop(player->camera->position); + return lua::pushinteger(L, id); +} + +static int l_get_vel(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + return lua::pushvec3_arr(L, entity->getHitbox().velocity); + } + return 0; +} + +static int l_set_vel(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + entity->getHitbox().velocity = lua::tovec3(L, 2); + } + return 0; } const luaL_Reg entitylib [] = { {"test", lua::wrap}, + {"get_vel", lua::wrap}, + {"set_vel", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index a774d283..2095526b 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -379,6 +379,16 @@ namespace lua { pop(L); return glm::vec4(x, y, z, w); } + inline glm::vec3 tovec3_stack(lua::State* L, int idx) { + return glm::vec3( + tonumber(L, idx), tonumber(L, idx+1), tonumber(L, idx+2) + ); + } + inline glm::vec4 tovec4_stack(lua::State* L, int idx) { + return glm::vec4( + tonumber(L, idx), tonumber(L, idx+1), tonumber(L, idx+2), tonumber(L, idx+3) + ); + } inline glm::mat4 tomat4(lua::State* L, int idx) { pushvalue(L, idx); if (!istable(L, idx) || objlen(L, idx) < 16) { diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index fd4fe76c..a608dded 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -20,16 +20,16 @@ void Transform::refresh() { Entities::Entities(Level* level) : level(level) { } -void Entities::drop(glm::vec3 pos, glm::vec3 vel) { +entityid_t Entities::drop(glm::vec3 pos) { auto entity = registry.create(); glm::vec3 size(1); - registry.emplace(entity, static_cast(1)); + auto id = nextID++; + registry.emplace(entity, static_cast(id)); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); registry.emplace(entity, pos, glm::vec3(size.x*0.2f, size.y*0.5f, size.z*0.2f)); - - auto& hitbox = registry.get(entity); - hitbox.velocity = vel; + entities[id] = entity; + return id; } void Entities::updatePhysics(float delta){ diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 8efc7197..f51f59bb 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -2,7 +2,9 @@ #define OBJECTS_ENTITIES_HPP_ #include "../typedefs.hpp" +#include "../physics/Hitbox.hpp" +#include #include #include #include @@ -28,9 +30,9 @@ class Rig; class Entity { entt::registry& registry; - entt::entity entity; + const entt::entity entity; public: - Entity(entt::registry& registry, entt::entity entity) + Entity(entt::registry& registry, const entt::entity entity) : registry(registry), entity(entity) {} bool isValid() const { @@ -41,6 +43,10 @@ public: return registry.get(entity); } + Hitbox& getHitbox() const { + return registry.get(entity); + } + entityid_t getUID() const { return registry.get(entity).uid; } @@ -50,12 +56,21 @@ class Entities { entt::registry registry; Level* level; std::unordered_map entities; + entityid_t nextID = 1; public: Entities(Level* level); void updatePhysics(float delta); void render(Assets* assets, ModelBatch& batch, Frustum& frustum); - void drop(glm::vec3 pos, glm::vec3 vel); + entityid_t drop(glm::vec3 pos); + + std::optional get(entityid_t id) { + const auto& found = entities.find(id); + if (found != entities.end()) { + return Entity(registry, found->second); + } + return std::nullopt; + } }; #endif // OBJECTS_ENTITIES_HPP_ From 330892bbcdb67bf09a8d1c48f4bd764354bfb0ef Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 25 Jun 2024 19:09:09 +0300 Subject: [PATCH 009/178] update player.drop callback --- res/content/base/scripts/hud.lua | 2 +- src/logic/scripting/lua/libplayer.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index e33f5a0f..9807e8b2 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -3,6 +3,6 @@ function on_hud_open() local pid = hud.get_player() local pvel = {player.get_vel(pid)} local eid = entity.test() - entity.set_vel(eid, pvel) + entity.set_vel(eid, vec3.add(vec3.mul(player.get_dir(pid), {8, 8, 8}), vec3.add(pvel, {0, 3, 0}))) end) end diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp index b9315de7..20640fd4 100644 --- a/src/logic/scripting/lua/libplayer.cpp +++ b/src/logic/scripting/lua/libplayer.cpp @@ -78,6 +78,13 @@ static int l_player_set_rot(lua::State* L) { return 0; } +static int l_player_get_dir(lua::State* L) { + if (auto player = get_player(L, 1)) { + return lua::pushvec3_arr(L, player->camera->front); + } + return 0; +} + static int l_player_get_inv(lua::State* L) { auto player = get_player(L, 1); if (!player) { @@ -133,6 +140,7 @@ const luaL_Reg playerlib [] = { {"set_vel", lua::wrap}, {"get_rot", lua::wrap}, {"set_rot", lua::wrap}, + {"get_dir", lua::wrap}, {"get_inventory", lua::wrap}, {"is_flight", lua::wrap}, {"set_flight", lua::wrap}, From f3c5afa1ab401c9129b83b949af4e9507ea9d8f1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 25 Jun 2024 20:11:46 +0300 Subject: [PATCH 010/178] add debug hitboxes render --- res/content/base/scripts/hud.lua | 6 +++++- src/graphics/render/WorldRenderer.cpp | 19 ++++++++++++++----- src/graphics/render/WorldRenderer.hpp | 2 ++ src/objects/Entities.cpp | 9 +++++++++ src/objects/Entities.hpp | 3 +++ 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 9807e8b2..d85e3201 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -1,8 +1,12 @@ +local DROP_FORCE = 8 +local DROP_INIT_VEL = {0, 3, 0} + function on_hud_open() input.add_callback("player.drop", function () local pid = hud.get_player() local pvel = {player.get_vel(pid)} local eid = entity.test() - entity.set_vel(eid, vec3.add(vec3.mul(player.get_dir(pid), {8, 8, 8}), vec3.add(pvel, {0, 3, 0}))) + local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) + entity.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) end) end diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index c7722fc9..fdc5d82a 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -215,8 +215,6 @@ void WorldRenderer::renderBlockSelection(Camera* camera, Shader* linesShader) { ? block->rt.hitboxes[selection.vox.state.rotation] : block->hitboxes; - linesShader->use(); - linesShader->uniformMatrix("u_projview", camera->getProjView()); lineBatch->lineWidth(2.0f); for (auto& hitbox: hitboxes) { const glm::vec3 center = glm::vec3(pos) + hitbox.center(); @@ -226,6 +224,17 @@ void WorldRenderer::renderBlockSelection(Camera* camera, Shader* linesShader) { lineBatch->line(point, point+norm*0.5f, glm::vec4(1.0f, 0.0f, 1.0f, 1.0f)); } } +} + +void WorldRenderer::renderLines(Camera* camera, Shader* linesShader) { + linesShader->use(); + linesShader->uniformMatrix("u_projview", camera->getProjView()); + if (player->selection.vox.id != BLOCK_VOID) { + renderBlockSelection(camera, linesShader); + } + if (player->debug) { + level->entities->renderDebug(*lineBatch); + } lineBatch->render(); } @@ -313,9 +322,9 @@ void WorldRenderer::draw( ctx.setDepthTest(true); ctx.setCullFace(true); renderLevel(ctx, camera, settings); - // Selected block - if (player->selection.vox.id != BLOCK_VOID && hudVisible){ - renderBlockSelection(camera, linesShader); + // Debug lines + if (hudVisible){ + renderLines(camera, linesShader); } } diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index af8eeaff..1b58ea3f 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -48,6 +48,8 @@ class WorldRenderer { /// @param camera active camera /// @param linesShader shader used void renderBlockSelection(Camera* camera, Shader* linesShader); + + void renderLines(Camera* camera, Shader* linesShader); /// @brief Render all debug lines (chunks borders, coord system guides) /// @param context graphics context diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index a608dded..b4218fe9 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -5,6 +5,7 @@ #include "../physics/Hitbox.hpp" #include "../physics/PhysicsSolver.hpp" #include "../graphics/render/ModelBatch.hpp" +#include "../graphics/core/LineBatch.hpp" #include "../graphics/core/Model.hpp" #include "../maths/FrustumCulling.hpp" @@ -54,6 +55,14 @@ void Entities::updatePhysics(float delta){ } } +void Entities::renderDebug(LineBatch& batch) { + batch.lineWidth(1.0f); + auto view = registry.view(); + for (auto [entity, transform, hitbox] : view.each()) { + batch.box(hitbox.position, hitbox.halfsize * 2.0f, glm::vec4(1.0f)); + } +} + void Entities::render(Assets* assets, ModelBatch& batch, Frustum& frustum) { auto view = registry.view(); auto model = assets->get("cube"); diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index f51f59bb..431cf98f 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -24,6 +24,7 @@ struct Transform { class Level; class Assets; +class LineBatch; class ModelBatch; class Frustum; class Rig; @@ -60,6 +61,8 @@ class Entities { public: Entities(Level* level); void updatePhysics(float delta); + + void renderDebug(LineBatch& batch); void render(Assets* assets, ModelBatch& batch, Frustum& frustum); entityid_t drop(glm::vec3 pos); From ee9f1639e9c9935330705c9e9f932484e0ddda31 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 25 Jun 2024 22:37:53 +0300 Subject: [PATCH 011/178] refactor Content --- src/content/Content.cpp | 50 +++--------- src/content/Content.hpp | 89 ++++++++++++---------- src/content/ContentBuilder.cpp | 4 +- src/content/ContentLUT.cpp | 83 +++++++++----------- src/files/WorldFiles.cpp | 9 +-- src/frontend/ContentGfxCache.cpp | 6 +- src/frontend/debug_panel.cpp | 2 +- src/frontend/hud.cpp | 4 +- src/graphics/render/BlocksPreview.cpp | 4 +- src/graphics/render/BlocksRenderer.cpp | 2 +- src/graphics/render/WorldRenderer.cpp | 8 +- src/graphics/render/WorldRenderer.hpp | 5 +- src/graphics/ui/elements/InventoryView.cpp | 8 +- src/items/ItemStack.cpp | 2 +- src/lighting/LightSolver.cpp | 2 +- src/lighting/Lighting.cpp | 10 +-- src/logic/BlocksController.cpp | 10 +-- src/logic/PlayerController.cpp | 12 +-- src/logic/scripting/lua/libblock.cpp | 18 ++--- src/logic/scripting/lua/libhud.cpp | 2 +- src/logic/scripting/lua/libinventory.cpp | 2 +- src/logic/scripting/lua/libitem.cpp | 12 +-- src/voxels/Chunks.cpp | 20 ++--- src/voxels/ChunksStorage.cpp | 5 +- src/voxels/WorldGenerator.cpp | 20 ++--- 25 files changed, 180 insertions(+), 209 deletions(-) diff --git a/src/content/Content.cpp b/src/content/Content.cpp index 8e0b0749..fbd5af85 100644 --- a/src/content/Content.cpp +++ b/src/content/Content.cpp @@ -12,62 +12,30 @@ #include "../logic/scripting/scripting.hpp" ContentIndices::ContentIndices( - std::vector blockDefs, - std::vector itemDefs -) : blockDefs(std::move(blockDefs)), - itemDefs(std::move(itemDefs)) + std::vector blocks, + std::vector items +) : blocks(std::move(blocks)), + items(std::move(items)) {} Content::Content( std::unique_ptr indices, std::unique_ptr drawGroups, - std::unordered_map> blockDefs, - std::unordered_map> itemDefs, + ContentUnitDefs blocks, + ContentUnitDefs items, std::unordered_map> packs, std::unordered_map> blockMaterials -) : blockDefs(std::move(blockDefs)), - itemDefs(std::move(itemDefs)), - indices(std::move(indices)), +) : indices(std::move(indices)), packs(std::move(packs)), blockMaterials(std::move(blockMaterials)), + blocks(std::move(blocks)), + items(std::move(items)), drawGroups(std::move(drawGroups)) {} Content::~Content() { } -Block* Content::findBlock(const std::string& id) const { - auto found = blockDefs.find(id); - if (found == blockDefs.end()) { - return nullptr; - } - return found->second.get(); -} - -Block& Content::requireBlock(const std::string& id) const { - auto found = blockDefs.find(id); - if (found == blockDefs.end()) { - throw std::runtime_error("missing block "+id); - } - return *found->second; -} - -ItemDef* Content::findItem(const std::string& id) const { - auto found = itemDefs.find(id); - if (found == itemDefs.end()) { - return nullptr; - } - return found->second.get(); -} - -ItemDef& Content::requireItem(const std::string& id) const { - auto found = itemDefs.find(id); - if (found == itemDefs.end()) { - throw std::runtime_error("missing item "+id); - } - return *found->second; -} - const BlockMaterial* Content::findBlockMaterial(const std::string& id) const { auto found = blockMaterials.find(id); if (found == blockMaterials.end()) { diff --git a/src/content/Content.hpp b/src/content/Content.hpp index 75237757..455bedf1 100644 --- a/src/content/Content.hpp +++ b/src/content/Content.hpp @@ -43,61 +43,79 @@ public: } }; +template +class ContentUnitIndices { + std::vector defs; +public: + ContentUnitIndices(std::vector defs) : defs(std::move(defs)) {} + + inline T* get(blockid_t id) const { + if (id >= defs.size()) { + return nullptr; + } + return defs[id]; + } + + inline size_t count() const { + return defs.size(); + } + + inline const T* const* getDefs() const { + return defs.data(); + } +}; + /// @brief Runtime defs cache: indices class ContentIndices { - std::vector blockDefs; - std::vector itemDefs; public: + ContentUnitIndices blocks; + ContentUnitIndices items; + ContentIndices( std::vector blockDefs, std::vector itemDefs ); +}; - inline Block* getBlockDef(blockid_t id) const { - if (id >= blockDefs.size()) +template +class ContentUnitDefs { + std::unordered_map> defs; +public: + ContentUnitDefs(std::unordered_map> defs) + : defs(std::move(defs)) { + } + + T* find(const std::string& id) const { + const auto& found = defs.find(id); + if (found == defs.end()) { return nullptr; - return blockDefs[id]; + } + return found->second.get(); } - - inline ItemDef* getItemDef(itemid_t id) const { - if (id >= itemDefs.size()) - return nullptr; - return itemDefs[id]; - } - - inline size_t countBlockDefs() const { - return blockDefs.size(); - } - - inline size_t countItemDefs() const { - return itemDefs.size(); - } - - // use this for critical spots to prevent range check overhead - const Block* const* getBlockDefs() const { - return blockDefs.data(); - } - - const ItemDef* const* getItemDefs() const { - return itemDefs.data(); + T& require(const std::string& id) const { + const auto& found = defs.find(id); + if (found == defs.end()) { + throw std::runtime_error("missing content unit "+id); + } + return *found->second; } }; -/* Content is a definitions repository */ +/// @brief Content is a definitions repository class Content { - std::unordered_map> blockDefs; - std::unordered_map> itemDefs; std::unique_ptr indices; std::unordered_map> packs; std::unordered_map> blockMaterials; public: + ContentUnitDefs blocks; + ContentUnitDefs items; std::unique_ptr const drawGroups; Content( std::unique_ptr indices, std::unique_ptr drawGroups, - std::unordered_map> blockDefs, - std::unordered_map> itemDefs, + ContentUnitDefs blocks, + ContentUnitDefs items, std::unordered_map> packs, std::unordered_map> blockMaterials ); @@ -106,15 +124,8 @@ public: inline ContentIndices* getIndices() const { return indices.get(); } - - Block* findBlock(const std::string& id) const; - Block& requireBlock(const std::string& id) const; - - ItemDef* findItem(const std::string& id) const; - ItemDef& requireItem(const std::string& id) const; const BlockMaterial* findBlockMaterial(const std::string& id) const; - const ContentPackRuntime* getPackRuntime(const std::string& id) const; const std::unordered_map>& getBlockMaterials() const; diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp index a660ca9a..d292e863 100644 --- a/src/content/ContentBuilder.cpp +++ b/src/content/ContentBuilder.cpp @@ -99,11 +99,11 @@ std::unique_ptr ContentBuilder::build() { // Now, it's time to resolve foreign keys for (Block* def : blockDefsIndices) { - def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id; + def->rt.pickingItem = content->items.require(def->pickingItem).rt.id; } for (ItemDef* def : itemDefsIndices) { - def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id; + def->rt.placingBlock = content->blocks.require(def->placingBlock).rt.id; } return content; diff --git a/src/content/ContentLUT.cpp b/src/content/ContentLUT.cpp index bb7ed390..3b0ad1f5 100644 --- a/src/content/ContentLUT.cpp +++ b/src/content/ContentLUT.cpp @@ -10,29 +10,45 @@ #include +template +static void init(std::vector& ids, std::vector& names, + const ContentUnitIndices& indices, size_t count) { + for (size_t i = 0; i < count; i++) { + ids.push_back(i); + } + for (size_t i = 0; i < indices.count(); i++) { + names.push_back(indices.get(i)->name); + } + for (size_t i = indices.count(); i < count; i++) { + names.emplace_back(""); + } +} + ContentLUT::ContentLUT(const Content* content, size_t blocksCount, size_t itemsCount) { auto* indices = content->getIndices(); - for (size_t i = 0; i < blocksCount; i++) { - blocks.push_back(i); - } - for (size_t i = 0; i < indices->countBlockDefs(); i++) { - blockNames.push_back(indices->getBlockDef(i)->name); - } - for (size_t i = indices->countBlockDefs(); i < blocksCount; i++) { - blockNames.emplace_back(""); - } + init(blocks, blockNames, indices->blocks, blocksCount); + init(items, itemNames, indices->items, itemsCount); +} - for (size_t i = 0; i < itemsCount; i++) { - items.push_back(i); - } - for (size_t i = 0; i < indices->countItemDefs(); i++) { - itemNames.push_back(indices->getItemDef(i)->name); - } - for (size_t i = indices->countItemDefs(); i < itemsCount; i++) { - itemNames.emplace_back(); +template +static void setup_lut(ContentLUT* lut, const ContentUnitDefs& defs, dynamic::List* list) { + if (list) { + for (size_t i = 0; i < list->size(); i++) { + std::string name = list->str(i); + if (auto def = defs.find(name)) { + lut->setBlock(i, name, def->rt.id); + } else { + lut->setBlock(i, name, BLOCK_VOID); + } + } } } +template static constexpr size_t get_entries_count( + const ContentUnitIndices& indices, dynamic::List* list) { + return list ? std::max(list->size(), indices.count()) : indices.count(); +} + std::shared_ptr ContentLUT::create( const fs::path& filename, const Content* content @@ -42,38 +58,13 @@ std::shared_ptr ContentLUT::create( auto itemlist = root->list("items"); auto* indices = content->getIndices(); - size_t blocks_c = blocklist - ? std::max(blocklist->size(), indices->countBlockDefs()) - : indices->countBlockDefs(); - size_t items_c = itemlist - ? std::max(itemlist->size(), indices->countItemDefs()) - : indices->countItemDefs(); + size_t blocks_c = get_entries_count(indices->blocks, blocklist); + size_t items_c = get_entries_count(indices->items, itemlist); auto lut = std::make_shared(content, blocks_c, items_c); - if (blocklist) { - for (size_t i = 0; i < blocklist->size(); i++) { - std::string name = blocklist->str(i); - Block* def = content->findBlock(name); - if (def) { - lut->setBlock(i, name, def->rt.id); - } else { - lut->setBlock(i, name, BLOCK_VOID); - } - } - } - - if (itemlist) { - for (size_t i = 0; i < itemlist->size(); i++) { - std::string name = itemlist->str(i); - ItemDef* def = content->findItem(name); - if (def) { - lut->setItem(i, name, def->rt.id); - } else { - lut->setItem(i, name, ITEM_VOID); - } - } - } + setup_lut(lut.get(), content->blocks, blocklist); + setup_lut(lut.get(), content->items, itemlist); if (lut->hasContentReorder() || lut->hasMissingContent()) { return lut; diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index 26cef6a6..82b70881 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -96,17 +96,16 @@ void WorldFiles::writeIndices(const ContentIndices* indices) { dynamic::Map root; uint count; auto& blocks = root.putList("blocks"); - count = indices->countBlockDefs(); + count = indices->blocks.count(); for (uint i = 0; i < count; i++) { - const Block* def = indices->getBlockDef(i); + const Block* def = indices->blocks.get(i); blocks.put(def->name); } auto& items = root.putList("items"); - count = indices->countItemDefs(); + count = indices->items.count(); for (uint i = 0; i < count; i++) { - const ItemDef* def = indices->getItemDef(i); - items.put(def->name); + items.put(indices->items.get(i)->name); } files::write_json(getIndicesFile(), &root); diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp index de180760..b18492fd 100644 --- a/src/frontend/ContentGfxCache.cpp +++ b/src/frontend/ContentGfxCache.cpp @@ -14,11 +14,11 @@ ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) { auto indices = content->getIndices(); - sideregions = std::make_unique(indices->countBlockDefs() * 6); + sideregions = std::make_unique(indices->blocks.count() * 6); auto atlas = assets->get("blocks"); - for (uint i = 0; i < indices->countBlockDefs(); i++) { - Block* def = indices->getBlockDef(i); + for (uint i = 0; i < indices->blocks.count(); i++) { + Block* def = indices->blocks.get(i); for (uint side = 0; side < 6; side++) { const std::string& tex = def->textureFaces[side]; if (atlas->has(tex)) { diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index b49abf89..8af49f86 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -98,7 +98,7 @@ std::shared_ptr create_debug_panel( })); panel->add(create_label([=](){ auto* indices = level->content->getIndices(); - if (auto def = indices->getBlockDef(player->selection.vox.id)) { + if (auto def = indices->blocks.get(player->selection.vox.id)) { return L"name: " + util::str2wstr_utf8(def->name); } else { return std::wstring {L"name: void"}; diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 53f85baf..21dbc2c7 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -102,9 +102,9 @@ std::shared_ptr Hud::createContentAccess() { auto indices = content->getIndices(); auto inventory = player->getInventory(); - int itemsCount = indices->countItemDefs(); + size_t itemsCount = indices->items.count(); auto accessInventory = std::make_shared(0, itemsCount); - for (int id = 1; id < itemsCount; id++) { + for (size_t id = 1; id < itemsCount; id++) { accessInventory->getSlot(id-1).set(ItemStack(id, 1)); } diff --git a/src/graphics/render/BlocksPreview.cpp b/src/graphics/render/BlocksPreview.cpp index 88a6f111..fa62e318 100644 --- a/src/graphics/render/BlocksPreview.cpp +++ b/src/graphics/render/BlocksPreview.cpp @@ -123,7 +123,7 @@ std::unique_ptr BlocksPreview::build( const Content* content ) { auto indices = content->getIndices(); - size_t count = indices->countBlockDefs(); + size_t count = indices->blocks.count(); size_t iconSize = ITEM_ICON_SIZE; auto shader = assets->get("ui3d"); @@ -153,7 +153,7 @@ std::unique_ptr BlocksPreview::build( fbo.bind(); for (size_t i = 0; i < count; i++) { - auto def = indices->getBlockDef(i); + auto def = indices->blocks.get(i); atlas->getTexture()->bind(); builder.add(def->name, draw(cache, shader, &fbo, &batch, def, iconSize)); } diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index e143f271..ed20f7b3 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -40,7 +40,7 @@ BlocksRenderer::BlocksRenderer( CHUNK_W + voxelBufferPadding*2, CHUNK_H, CHUNK_D + voxelBufferPadding*2); - blockDefsCache = content->getIndices()->getBlockDefs(); + blockDefsCache = content->getIndices()->blocks.getDefs(); } BlocksRenderer::~BlocksRenderer() { diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index fdc5d82a..5d1c639b 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -179,7 +179,7 @@ void WorldRenderer::renderLevel( { auto inventory = player->getInventory(); ItemStack& stack = inventory->getSlot(player->getChosenSlot()); - auto item = indices->getItemDef(stack.getItemId()); + auto item = indices->items.get(stack.getItemId()); float multiplier = 0.5f; shader->uniform3f("u_torchlightColor", item->emission[0] / 15.0f * multiplier, @@ -202,11 +202,11 @@ void WorldRenderer::renderLevel( skybox->unbind(); } -void WorldRenderer::renderBlockSelection(Camera* camera, Shader* linesShader) { +void WorldRenderer::renderBlockSelection() { const auto& selection = player->selection; auto indices = level->content->getIndices(); blockid_t id = selection.vox.id; - auto block = indices->getBlockDef(id); + auto block = indices->blocks.get(id); const glm::ivec3 pos = player->selection.position; const glm::vec3 point = selection.hitPosition; const glm::vec3 norm = selection.normal; @@ -230,7 +230,7 @@ void WorldRenderer::renderLines(Camera* camera, Shader* linesShader) { linesShader->use(); linesShader->uniformMatrix("u_projview", camera->getProjView()); if (player->selection.vox.id != BLOCK_VOID) { - renderBlockSelection(camera, linesShader); + renderBlockSelection(); } if (player->debug) { level->entities->renderDebug(*lineBatch); diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index 1b58ea3f..31cb847c 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -45,10 +45,11 @@ class WorldRenderer { void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); /// @brief Render block selection lines + void renderBlockSelection(); + + /// @brief Render lines (selection and debug) /// @param camera active camera /// @param linesShader shader used - void renderBlockSelection(Camera* camera, Shader* linesShader); - void renderLines(Camera* camera, Shader* linesShader); /// @brief Render all debug lines (chunks borders, coord system guides) diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 92084c37..de121327 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -121,7 +121,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { itemid_t itemid = bound->getItemId(); if (itemid != prevItem) { if (itemid) { - auto def = content->getIndices()->getItemDef(itemid); + auto def = content->getIndices()->items.get(itemid); tooltip = util::pascal_case( langs::get(util::str2wstr_utf8(def->caption)) ); @@ -159,12 +159,12 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { auto previews = assets->get("block-previews"); auto indices = content->getIndices(); - ItemDef* item = indices->getItemDef(stack.getItemId()); + ItemDef* item = indices->items.get(stack.getItemId()); switch (item->iconType) { case item_icon_type::none: break; case item_icon_type::block: { - const Block& cblock = content->requireBlock(item->icon); + const Block& cblock = content->blocks.require(item->icon); batch->texture(previews->getTexture()); UVRegion region = previews->get(cblock.name); @@ -268,7 +268,7 @@ void SlotView::clicked(gui::GUI* gui, mousecode button) { stack.setCount(halfremain); } } else { - auto stackDef = content->getIndices()->getItemDef(stack.getItemId()); + auto stackDef = content->getIndices()->items.get(stack.getItemId()); if (stack.isEmpty()) { stack.set(grabbed); stack.setCount(1); diff --git a/src/items/ItemStack.cpp b/src/items/ItemStack.cpp index c2c338e0..d60246c3 100644 --- a/src/items/ItemStack.cpp +++ b/src/items/ItemStack.cpp @@ -22,7 +22,7 @@ bool ItemStack::accepts(const ItemStack& other) const { } void ItemStack::move(ItemStack& item, const ContentIndices* indices) { - auto def = indices->getItemDef(item.getItemId()); + auto def = indices->items.get(item.getItemId()); int count = std::min(item.count, def->stackSize-this->count); if (isEmpty()) { set(ItemStack(item.getItemId(), count)); diff --git a/src/lighting/LightSolver.cpp b/src/lighting/LightSolver.cpp index f9865956..d2df6b4b 100644 --- a/src/lighting/LightSolver.cpp +++ b/src/lighting/LightSolver.cpp @@ -81,7 +81,7 @@ void LightSolver::solve(){ } } - const Block* const* blockDefs = contentIds->getBlockDefs(); + const Block* const* blockDefs = contentIds->blocks.getDefs(); while (!addqueue.empty()){ const lightentry entry = addqueue.front(); addqueue.pop(); diff --git a/src/lighting/Lighting.cpp b/src/lighting/Lighting.cpp index 99cf1fcc..6d2d5cc4 100644 --- a/src/lighting/Lighting.cpp +++ b/src/lighting/Lighting.cpp @@ -36,7 +36,7 @@ void Lighting::clear(){ } void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){ - auto* blockDefs = indices->getBlockDefs(); + const auto* blockDefs = indices->blocks.getDefs(); int highestPoint = 0; for (int z = 0; z < CHUNK_D; z++){ @@ -60,7 +60,7 @@ void Lighting::prebuildSkyLight(Chunk* chunk, const ContentIndices* indices){ } void Lighting::buildSkyLight(int cx, int cz){ - const Block* const* blockDefs = content->getIndices()->getBlockDefs(); + const auto blockDefs = content->getIndices()->blocks.getDefs(); Chunk* chunk = chunks->getChunk(cx, cz); for (int z = 0; z < CHUNK_D; z++){ @@ -92,8 +92,8 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand){ LightSolver* solverB = this->solverB.get(); LightSolver* solverS = this->solverS.get(); - const Block* const* blockDefs = content->getIndices()->getBlockDefs(); - const Chunk* chunk = chunks->getChunk(cx, cz); + auto blockDefs = content->getIndices()->blocks.getDefs(); + auto chunk = chunks->getChunk(cx, cz); for (uint y = 0; y < CHUNK_H; y++){ for (uint z = 0; z < CHUNK_D; z++){ @@ -150,7 +150,7 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand){ } void Lighting::onBlockSet(int x, int y, int z, blockid_t id){ - Block* block = content->getIndices()->getBlockDef(id); + Block* block = content->getIndices()->blocks.get(id); solverR->remove(x,y,z); solverG->remove(x,y,z); solverB->remove(x,y,z); diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 4748e7e3..95a3d47a 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -83,7 +83,7 @@ void BlocksController::updateBlock(int x, int y, int z) { voxel* vox = chunks->get(x, y, z); if (vox == nullptr) return; - const Block* def = level->content->getIndices()->getBlockDef(vox->id); + auto def = level->content->getIndices()->blocks.get(vox->id); if (def->grounded && !chunks->isSolidBlock(x, y-1, z)) { breakBlock(nullptr, def, x, y, z); return; @@ -109,10 +109,10 @@ void BlocksController::onBlocksTick(int tickid, int parts) { auto content = level->content; auto indices = content->getIndices(); int tickRate = blocksTickClock.getTickRate(); - for (size_t id = 0; id < indices->countBlockDefs(); id++) { + for (size_t id = 0; id < indices->blocks.count(); id++) { if ((id + tickid) % parts != 0) continue; - auto def = indices->getBlockDef(id); + auto def = indices->blocks.get(id); auto interval = def->tickInterval; if (def->rt.funcsset.onblockstick && tickid / parts % interval == 0) { scripting::on_blocks_tick(def, tickRate / interval); @@ -143,7 +143,7 @@ void BlocksController::randomTick(int tickid, int parts) { int by = random.rand() % segheight + s * segheight; int bz = random.rand() % CHUNK_D; const voxel& vox = chunk->voxels[(by * CHUNK_D + bz) * CHUNK_W + bx]; - Block* block = indices->getBlockDef(vox.id); + Block* block = indices->blocks.get(vox.id); if (block->rt.funcsset.randupdate) { scripting::random_update_block( block, @@ -167,7 +167,7 @@ int64_t BlocksController::createBlockInventory(int x, int y, int z) { auto inv = chunk->getBlockInventory(lx, y, lz); if (inv == nullptr) { auto indices = level->content->getIndices(); - auto def = indices->getBlockDef(chunk->voxels[vox_index(lx, y, lz)].id); + auto def = indices->blocks.get(chunk->voxels[vox_index(lx, y, lz)].id); int invsize = def->inventorySize; if (invsize == 0) { return 0; diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index a37128b8..ef680c56 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -203,7 +203,7 @@ void PlayerController::onFootstep() { int z = std::floor(pos.z+half.z*offsetZ); auto vox = level->chunks->get(x, y, z); if (vox) { - auto def = level->content->getIndices()->getBlockDef(vox->id); + auto def = level->content->getIndices()->blocks.get(vox->id); if (!def->obstacle) continue; onBlockInteraction( @@ -317,7 +317,7 @@ static int determine_rotation(Block* def, const glm::ivec3& norm, glm::vec3& cam } static void pick_block(ContentIndices* indices, Chunks* chunks, Player* player, int x, int y, int z) { - Block* block = indices->getBlockDef(chunks->get(x,y,z)->id); + auto block = indices->blocks.get(chunks->get(x,y,z)->id); itemid_t id = block->rt.pickingItem; auto inventory = player->getInventory(); size_t slotid = inventory->findSlotByItem(id, 0, 10); @@ -356,7 +356,7 @@ voxel* PlayerController::updateSelection(float maxDistance) { selection.actualPosition = iend; if (selectedState.segment) { selection.position = chunks->seekOrigin( - iend, indices->getBlockDef(selection.vox.id), selectedState + iend, indices->blocks.get(selection.vox.id), selectedState ); auto origin = chunks->get(iend); if (origin && origin->id != vox->id) { @@ -430,7 +430,7 @@ void PlayerController::updateInteraction() { auto inventory = player->getInventory(); const ItemStack& stack = inventory->getSlot(player->getChosenSlot()); - ItemDef* item = indices->getItemDef(stack.getItemId()); + ItemDef* item = indices->items.get(stack.getItemId()); auto vox = updateSelection(maxDistance); if (vox == nullptr) { @@ -446,7 +446,7 @@ void PlayerController::updateInteraction() { return; } } - auto target = indices->getBlockDef(vox->id); + auto target = indices->blocks.get(vox->id); if (lclick && target->breakable){ onBlockInteraction( iend, target, @@ -467,7 +467,7 @@ void PlayerController::updateInteraction() { return; } } - auto def = indices->getBlockDef(item->rt.placingBlock); + auto def = indices->blocks.get(item->rt.placingBlock); if (def && rclick) { processRightClick(def, target); } diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index f992b32e..4f2b3902 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -14,10 +14,10 @@ using namespace scripting; static Block* require_block(lua::State* L) { auto indices = content->getIndices(); auto id = lua::tointeger(L, 1); - if (static_cast(id) >= indices->countBlockDefs()) { + if (static_cast(id) >= indices->blocks.count()) { return nullptr; } - return indices->getBlockDef(id); + return indices->blocks.get(id); } static int l_name(lua::State* L) { @@ -43,12 +43,12 @@ static int l_is_solid_at(lua::State* L) { } static int l_count(lua::State* L) { - return lua::pushinteger(L, indices->countBlockDefs()); + return lua::pushinteger(L, indices->blocks.count()); } static int l_index(lua::State* L) { auto name = lua::require_string(L, 1); - return lua::pushinteger(L, content->requireBlock(name).rt.id); + return lua::pushinteger(L, content->blocks.require(name).rt.id); } static int l_is_extended(lua::State* L) { @@ -78,7 +78,7 @@ static int l_seek_origin(lua::State* L) { auto y = lua::tointeger(L, 2); auto z = lua::tointeger(L, 3); auto vox = level->chunks->get(x, y, z); - auto def = indices->getBlockDef(vox->id); + auto def = indices->blocks.get(vox->id); return lua::pushivec3(L, level->chunks->seekOrigin({x, y, z}, def, vox->state)); } @@ -89,7 +89,7 @@ static int l_set(lua::State* L) { auto id = lua::tointeger(L, 4); auto state = lua::tointeger(L, 5); bool noupdate = lua::toboolean(L, 6); - if (static_cast(id) >= indices->countBlockDefs()) { + if (static_cast(id) >= indices->blocks.count()) { return 0; } if (!level->chunks->get(x, y, z)) { @@ -120,7 +120,7 @@ static int l_get_x(lua::State* L) { if (vox == nullptr) { return lua::pushivec3(L, 1, 0, 0); } - auto def = level->content->getIndices()->getBlockDef(vox->id); + auto def = level->content->getIndices()->blocks.get(vox->id); if (!def->rotatable) { return lua::pushivec3(L, 1, 0, 0); } else { @@ -137,7 +137,7 @@ static int l_get_y(lua::State* L) { if (vox == nullptr) { return lua::pushivec3(L, 0, 1, 0); } - auto def = level->content->getIndices()->getBlockDef(vox->id); + auto def = level->content->getIndices()->blocks.get(vox->id); if (!def->rotatable) { return lua::pushivec3(L, 0, 1, 0); } else { @@ -154,7 +154,7 @@ static int l_get_z(lua::State* L) { if (vox == nullptr) { return lua::pushivec3(L, 0, 0, 1); } - auto def = level->content->getIndices()->getBlockDef(vox->id); + auto def = level->content->getIndices()->blocks.get(vox->id); if (!def->rotatable) { return lua::pushivec3(L, 0, 0, 1); } else { diff --git a/src/logic/scripting/lua/libhud.cpp b/src/logic/scripting/lua/libhud.cpp index 5395e7a1..b5731d1b 100644 --- a/src/logic/scripting/lua/libhud.cpp +++ b/src/logic/scripting/lua/libhud.cpp @@ -49,7 +49,7 @@ static int l_hud_open_block(lua::State* L) { std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z) ); } - auto def = content->getIndices()->getBlockDef(vox->id); + auto def = content->getIndices()->blocks.get(vox->id); auto assets = engine->getAssets(); auto layout = assets->get(def->uiLayout); if (layout == nullptr) { diff --git a/src/logic/scripting/lua/libinventory.cpp b/src/logic/scripting/lua/libinventory.cpp index 549593a8..717583b6 100644 --- a/src/logic/scripting/lua/libinventory.cpp +++ b/src/logic/scripting/lua/libinventory.cpp @@ -9,7 +9,7 @@ using namespace scripting; static void validate_itemid(itemid_t id) { - if (id >= indices->countItemDefs()) { + if (id >= indices->items.count()) { throw std::runtime_error("invalid item id"); } } diff --git a/src/logic/scripting/lua/libitem.cpp b/src/logic/scripting/lua/libitem.cpp index 25466217..7f554301 100644 --- a/src/logic/scripting/lua/libitem.cpp +++ b/src/logic/scripting/lua/libitem.cpp @@ -8,30 +8,30 @@ using namespace scripting; static int l_item_name(lua::State* L) { auto indices = content->getIndices(); auto id = lua::tointeger(L, 1); - if (static_cast(id) >= indices->countItemDefs()) { + if (static_cast(id) >= indices->items.count()) { return 0; } - auto def = indices->getItemDef(id); + auto def = indices->items.get(id); return lua::pushstring(L, def->name); } static int l_item_index(lua::State* L) { auto name = lua::require_string(L, 1); - return lua::pushinteger(L, content->requireItem(name).rt.id); + return lua::pushinteger(L, content->items.require(name).rt.id); } static int l_item_stack_size(lua::State* L) { auto indices = content->getIndices(); auto id = lua::tointeger(L, 1); - if (static_cast(id) >= indices->countItemDefs()) { + if (static_cast(id) >= indices->items.count()) { return 0; } - auto def = indices->getItemDef(id); + auto def = indices->items.get(id); return lua::pushinteger(L, def->stackSize); } static int l_item_defs_count(lua::State* L) { - return lua::pushinteger(L, indices->countItemDefs()); + return lua::pushinteger(L, indices->items.count()); } const luaL_Reg itemlib [] = { diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 4d530d90..9edc4e16 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -66,7 +66,7 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){ return ∅ } } - const Block* def = indices->getBlockDef(v->id); + const auto def = indices->blocks.get(v->id); if (def->obstacle) { glm::ivec3 offset {}; if (v->state.segment) { @@ -89,21 +89,21 @@ bool Chunks::isSolidBlock(int32_t x, int32_t y, int32_t z) { voxel* v = get(x, y, z); if (v == nullptr) return false; - return indices->getBlockDef(v->id)->rt.solid; + return indices->blocks.get(v->id)->rt.solid; } bool Chunks::isReplaceableBlock(int32_t x, int32_t y, int32_t z) { voxel* v = get(x, y, z); if (v == nullptr) return false; - return indices->getBlockDef(v->id)->replaceable; + return indices->blocks.get(v->id)->replaceable; } bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) { voxel* v = get(x, y, z); if (v == nullptr) return false; - return indices->getBlockDef(v->id)->obstacle; + return indices->blocks.get(v->id)->obstacle; } ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel){ @@ -240,7 +240,7 @@ bool Chunks::checkReplaceability(const Block* def, blockstate state, glm::ivec3 pos += rotation.axisY * sy; pos += rotation.axisZ * sz; if (auto vox = get(pos.x, pos.y, pos.z)) { - auto target = indices->getBlockDef(vox->id); + auto target = indices->blocks.get(vox->id); if (!target->replaceable && vox->id != ignore) { return false; } @@ -316,7 +316,7 @@ void Chunks::setRotation(int32_t x, int32_t y, int32_t z, uint8_t index) { if (vox == nullptr) { return; } - auto def = indices->getBlockDef(vox->id); + auto def = indices->blocks.get(vox->id); if (!def->rotatable || vox->state.rotation == index) { return; } @@ -351,7 +351,7 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state) // block finalization voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx]; - auto prevdef = indices->getBlockDef(vox.id); + auto prevdef = indices->blocks.get(vox.id); if (prevdef->inventorySize == 0) { chunk->removeBlockInventory(lx, y, lz); } @@ -360,7 +360,7 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state) } // block initialization - auto newdef = indices->getBlockDef(id); + auto newdef = indices->blocks.get(id); vox.id = id; vox.state = state; chunk->setModifiedAndUnsaved(); @@ -429,7 +429,7 @@ voxel* Chunks::rayCast( if (voxel == nullptr){ return nullptr; } - const auto def = indices->getBlockDef(voxel->id); + const auto def = indices->blocks.get(voxel->id); if (def->selectable){ end.x = px + t * dx; end.y = py + t * dy; @@ -553,7 +553,7 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis if (voxel == nullptr) { return glm::vec3(px + t * dx, py + t * dy, pz + t * dz); } - const auto def = indices->getBlockDef(voxel->id); + const auto def = indices->blocks.get(voxel->id); if (def->obstacle) { if (!def->rt.solid) { const std::vector& hitboxes = def->rotatable diff --git a/src/voxels/ChunksStorage.cpp b/src/voxels/ChunksStorage.cpp index 1ffb2b03..73b690af 100644 --- a/src/voxels/ChunksStorage.cpp +++ b/src/voxels/ChunksStorage.cpp @@ -40,7 +40,7 @@ void ChunksStorage::remove(int x, int z) { static void verifyLoadedChunk(ContentIndices* indices, Chunk* chunk) { for (size_t i = 0; i < CHUNK_VOL; i++) { blockid_t id = chunk->voxels[i].id; - if (indices->getBlockDef(id) == nullptr) { + if (indices->blocks.get(id) == nullptr) { auto logline = logger.error(); logline << "corruped block detected at " << i << " of chunk "; logline << chunk->x << "x" << chunk->z; @@ -79,6 +79,7 @@ std::shared_ptr ChunksStorage::create(int x, int z) { } // reduce nesting on next modification +// 25.06.2024: not now void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const { const Content* content = level->content; auto indices = content->getIndices(); @@ -137,7 +138,7 @@ void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const { voxels[vidx] = cvoxels[cidx]; light_t light = clights[cidx]; if (backlight) { - const Block* block = indices->getBlockDef(voxels[vidx].id); + auto block = indices->blocks.get(voxels[vidx].id); if (block->lightPassing) { light = Lightmap::combine( min(15, Lightmap::extract(light, 0)+1), diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index a893ba7d..9bcccdeb 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -6,13 +6,13 @@ #include "../content/Content.hpp" WorldGenerator::WorldGenerator(const Content* content) - : idStone(content->requireBlock("base:stone").rt.id), - idDirt(content->requireBlock("base:dirt").rt.id), - idGrassBlock(content->requireBlock("base:grass_block").rt.id), - idSand(content->requireBlock("base:sand").rt.id), - idWater(content->requireBlock("base:water").rt.id), - idWood(content->requireBlock("base:wood").rt.id), - idLeaves(content->requireBlock("base:leaves").rt.id), - idGrass(content->requireBlock("base:grass").rt.id), - idFlower(content->requireBlock("base:flower").rt.id), - idBazalt(content->requireBlock("base:bazalt").rt.id) {} + : idStone(content->blocks.require("base:stone").rt.id), + idDirt(content->blocks.require("base:dirt").rt.id), + idGrassBlock(content->blocks.require("base:grass_block").rt.id), + idSand(content->blocks.require("base:sand").rt.id), + idWater(content->blocks.require("base:water").rt.id), + idWood(content->blocks.require("base:wood").rt.id), + idLeaves(content->blocks.require("base:leaves").rt.id), + idGrass(content->blocks.require("base:grass").rt.id), + idFlower(content->blocks.require("base:flower").rt.id), + idBazalt(content->blocks.require("base:bazalt").rt.id) {} From 1acced4475d27a34d85eb893bf14f7f4d12b4ac3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 25 Jun 2024 23:36:07 +0300 Subject: [PATCH 012/178] fix and refactor ContentLUT --- src/content/ContentLUT.cpp | 59 +++-------------- src/content/ContentLUT.hpp | 127 +++++++++++++++++++++---------------- src/items/Inventory.cpp | 2 +- src/objects/EntityDef.hpp | 16 +++++ src/voxels/Chunk.cpp | 2 +- 5 files changed, 99 insertions(+), 107 deletions(-) create mode 100644 src/objects/EntityDef.hpp diff --git a/src/content/ContentLUT.cpp b/src/content/ContentLUT.cpp index 3b0ad1f5..53245444 100644 --- a/src/content/ContentLUT.cpp +++ b/src/content/ContentLUT.cpp @@ -6,43 +6,12 @@ #include "../coders/json.hpp" #include "../voxels/Block.hpp" #include "../items/ItemDef.hpp" -#include "../data/dynamic.hpp" - #include -template -static void init(std::vector& ids, std::vector& names, - const ContentUnitIndices& indices, size_t count) { - for (size_t i = 0; i < count; i++) { - ids.push_back(i); - } - for (size_t i = 0; i < indices.count(); i++) { - names.push_back(indices.get(i)->name); - } - for (size_t i = indices.count(); i < count; i++) { - names.emplace_back(""); - } -} - -ContentLUT::ContentLUT(const Content* content, size_t blocksCount, size_t itemsCount) { - auto* indices = content->getIndices(); - init(blocks, blockNames, indices->blocks, blocksCount); - init(items, itemNames, indices->items, itemsCount); -} - -template -static void setup_lut(ContentLUT* lut, const ContentUnitDefs& defs, dynamic::List* list) { - if (list) { - for (size_t i = 0; i < list->size(); i++) { - std::string name = list->str(i); - if (auto def = defs.find(name)) { - lut->setBlock(i, name, def->rt.id); - } else { - lut->setBlock(i, name, BLOCK_VOID); - } - } - } -} +ContentLUT::ContentLUT(const ContentIndices* indices, size_t blocksCount, size_t itemsCount) + : blocks(blocksCount, indices->blocks, BLOCK_VOID, contenttype::block), + items(itemsCount, indices->items, ITEM_VOID, contenttype::item) +{} template static constexpr size_t get_entries_count( const ContentUnitIndices& indices, dynamic::List* list) { @@ -61,10 +30,10 @@ std::shared_ptr ContentLUT::create( size_t blocks_c = get_entries_count(indices->blocks, blocklist); size_t items_c = get_entries_count(indices->items, itemlist); - auto lut = std::make_shared(content, blocks_c, items_c); + auto lut = std::make_shared(indices, blocks_c, items_c); - setup_lut(lut.get(), content->blocks, blocklist); - setup_lut(lut.get(), content->items, itemlist); + lut->blocks.setup(blocklist, content->blocks); + lut->items.setup(itemlist, content->items); if (lut->hasContentReorder() || lut->hasMissingContent()) { return lut; @@ -75,17 +44,7 @@ std::shared_ptr ContentLUT::create( std::vector ContentLUT::getMissingContent() const { std::vector entries; - for (size_t i = 0; i < blocks.size(); i++) { - if (blocks[i] == BLOCK_VOID) { - auto& name = blockNames[i]; - entries.push_back(contententry {contenttype::block, name}); - } - } - for (size_t i = 0; i < items.size(); i++) { - if (items[i] == ITEM_VOID) { - auto& name = itemNames[i]; - entries.push_back(contententry {contenttype::item, name}); - } - } + blocks.getMissingContent(entries); + items.getMissingContent(entries); return entries; } diff --git a/src/content/ContentLUT.hpp b/src/content/ContentLUT.hpp index f7c8a799..baf347d7 100644 --- a/src/content/ContentLUT.hpp +++ b/src/content/ContentLUT.hpp @@ -5,6 +5,7 @@ #include "../typedefs.hpp" #include "../constants.hpp" +#include "../data/dynamic.hpp" #include #include @@ -18,58 +19,82 @@ struct contententry { std::string name; }; -// TODO: make it unified for all types of content +template +class ContentUnitLUT { + std::vector indices; + std::vector names; + bool missingContent = false; + bool reorderContent = false; + T missingValue; + contenttype type; +public: + ContentUnitLUT(size_t count, const ContentUnitIndices& unitIndices, T missingValue, contenttype type) + : missingValue(missingValue), type(type) { + for (size_t i = 0; i < count; i++) { + indices.push_back(i); + } + for (size_t i = 0; i < unitIndices.count(); i++) { + names.push_back(unitIndices.get(i)->name); + } + for (size_t i = unitIndices.count(); i < count; i++) { + names.emplace_back(""); + } + } + void setup(dynamic::List* list, const ContentUnitDefs& defs) { + if (list) { + for (size_t i = 0; i < list->size(); i++) { + std::string name = list->str(i); + if (auto def = defs.find(name)) { + set(i, name, def->rt.id); + } else { + set(i, name, missingValue); + } + } + } + } + void getMissingContent(std::vector& entries) const { + for (size_t i = 0; i < count(); i++) { + if (indices[i] == missingValue) { + auto& name = names[i]; + entries.push_back(contententry {type, name}); + } + } + } + inline const std::string& getName(T index) const { + return names[index]; + } + inline T getId(T index) const { + return indices[index]; + } + inline void set(T index, std::string name, T id) { + indices[index] = id; + names[index] = std::move(name); + if (id == missingValue) { + missingContent = true; + } else if (index != id) { + reorderContent = true; + } + } + inline size_t count() const { + return indices.size(); + } + inline bool hasContentReorder() const { + return reorderContent; + } + inline bool hasMissingContent() const { + return missingContent; + } +}; /// @brief Content indices lookup table or report /// used to convert world with different indices /// Building with indices.json class ContentLUT { - std::vector blocks; - std::vector blockNames; - - std::vector items; - std::vector itemNames; - - bool reorderContent = false; - bool missingContent = false; public: - ContentLUT(const Content* content, size_t blocks, size_t items); + ContentUnitLUT blocks; + ContentUnitLUT items; - inline const std::string& getBlockName(blockid_t index) const { - return blockNames[index]; - } - - inline blockid_t getBlockId(blockid_t index) const { - return blocks[index]; - } - - inline void setBlock(blockid_t index, std::string name, blockid_t id) { - blocks[index] = id; - blockNames[index] = std::move(name); - if (id == BLOCK_VOID) { - missingContent = true; - } else if (index != id) { - reorderContent = true; - } - } - - inline const std::string& getItemName(blockid_t index) const { - return itemNames[index]; - } - - inline itemid_t getItemId(itemid_t index) const { - return items[index]; - } - - inline void setItem(itemid_t index, std::string name, itemid_t id) { - items[index] = id; - itemNames[index] = std::move(name); - if (id == ITEM_VOID) { - missingContent = true; - } else if (index != id) { - reorderContent = true; - } - } + ContentLUT(const ContentIndices* indices, size_t blocks, size_t items); static std::shared_ptr create( const fs::path& filename, @@ -77,18 +102,10 @@ public: ); inline bool hasContentReorder() const { - return reorderContent; + return blocks.hasContentReorder() || items.hasContentReorder(); } inline bool hasMissingContent() const { - return missingContent; - } - - inline size_t countBlocks() const { - return blocks.size(); - } - - inline size_t countItems() const { - return items.size(); + return blocks.hasMissingContent() || items.hasMissingContent(); } std::vector getMissingContent() const; diff --git a/src/items/Inventory.cpp b/src/items/Inventory.cpp index e09dad45..8361f63d 100644 --- a/src/items/Inventory.cpp +++ b/src/items/Inventory.cpp @@ -89,7 +89,7 @@ void Inventory::convert(dynamic::Map* data, const ContentLUT* lut) { for (size_t i = 0; i < slotsarr->size(); i++) { auto item = slotsarr->map(i); itemid_t id = item->get("id", ITEM_EMPTY); - itemid_t replacement = lut->getItemId(id); + itemid_t replacement = lut->items.getId(id); item->put("id", replacement); if (replacement == 0 && item->has("count")) { item->remove("count"); diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp new file mode 100644 index 00000000..06510099 --- /dev/null +++ b/src/objects/EntityDef.hpp @@ -0,0 +1,16 @@ +#ifndef OBJECTS_ENTITY_DEF_HPP_ +#define OBJECTS_ENTITY_DEF_HPP_ + +#include + +#include "../typedefs.hpp" + +struct EntityDef { + /// @brief Entity string id (with prefix included) + std::string const name; + + EntityDef(const std::string& name); + EntityDef(const EntityDef&) = delete; +}; + +#endif // OBJECTS_ENTITY_DEF_HPP_ diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index be8238c6..bd6dc0bc 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -127,7 +127,7 @@ void Chunk::convert(ubyte* data, const ContentLUT* lut) { // see encode method to understand what the hell is going on here blockid_t id = ((static_cast(data[i]) << 8) | static_cast(data[CHUNK_VOL+i])); - blockid_t replacement = lut->getBlockId(id); + blockid_t replacement = lut->blocks.getId(id); data[i] = replacement >> 8; data[CHUNK_VOL+i] = replacement & 0xFF; } From 66a1240fbc2441a9c6a0d16bd02ee6faf23a20c6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 26 Jun 2024 03:40:14 +0300 Subject: [PATCH 013/178] refactor ContentBuilder and add entities support --- src/content/Content.cpp | 11 +++-- src/content/Content.hpp | 14 +++++-- src/content/ContentBuilder.cpp | 69 ++++++++++--------------------- src/content/ContentBuilder.hpp | 54 +++++++++++++++++++----- src/content/ContentLoader.cpp | 6 +-- src/content/ContentLoader.hpp | 2 +- src/core_defs.cpp | 4 +- src/items/ItemDef.hpp | 3 +- src/logic/scripting/scripting.hpp | 2 +- 9 files changed, 90 insertions(+), 75 deletions(-) diff --git a/src/content/Content.cpp b/src/content/Content.cpp index fbd5af85..cb8d11a6 100644 --- a/src/content/Content.cpp +++ b/src/content/Content.cpp @@ -7,15 +7,18 @@ #include "../voxels/Block.hpp" #include "../items/ItemDef.hpp" +#include "../objects/EntityDef.hpp" #include "ContentPack.hpp" #include "../logic/scripting/scripting.hpp" ContentIndices::ContentIndices( - std::vector blocks, - std::vector items + ContentUnitIndices blocks, + ContentUnitIndices items, + ContentUnitIndices entities ) : blocks(std::move(blocks)), - items(std::move(items)) + items(std::move(items)), + entities(std::move(entities)) {} Content::Content( @@ -23,6 +26,7 @@ Content::Content( std::unique_ptr drawGroups, ContentUnitDefs blocks, ContentUnitDefs items, + ContentUnitDefs entities, std::unordered_map> packs, std::unordered_map> blockMaterials ) : indices(std::move(indices)), @@ -30,6 +34,7 @@ Content::Content( blockMaterials(std::move(blockMaterials)), blocks(std::move(blocks)), items(std::move(items)), + entities(std::move(entities)), drawGroups(std::move(drawGroups)) {} diff --git a/src/content/Content.hpp b/src/content/Content.hpp index 455bedf1..1fd21a71 100644 --- a/src/content/Content.hpp +++ b/src/content/Content.hpp @@ -14,12 +14,13 @@ using DrawGroups = std::set; class Block; struct BlockMaterial; -class ItemDef; +struct ItemDef; +struct EntityDef; class Content; class ContentPackRuntime; enum class contenttype { - none, block, item + none, block, item, entity }; inline const char* contenttype_name(contenttype type) { @@ -27,6 +28,7 @@ inline const char* contenttype_name(contenttype type) { case contenttype::none: return "none"; case contenttype::block: return "block"; case contenttype::item: return "item"; + case contenttype::entity: return "entity"; default: return "unknown"; } @@ -70,10 +72,12 @@ class ContentIndices { public: ContentUnitIndices blocks; ContentUnitIndices items; + ContentUnitIndices entities; ContentIndices( - std::vector blockDefs, - std::vector itemDefs + ContentUnitIndices blocks, + ContentUnitIndices items, + ContentUnitIndices entities ); }; @@ -109,6 +113,7 @@ class Content { public: ContentUnitDefs blocks; ContentUnitDefs items; + ContentUnitDefs entities; std::unique_ptr const drawGroups; Content( @@ -116,6 +121,7 @@ public: std::unique_ptr drawGroups, ContentUnitDefs blocks, ContentUnitDefs items, + ContentUnitDefs entities, std::unordered_map> packs, std::unordered_map> blockMaterials ); diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp index d292e863..adbe6425 100644 --- a/src/content/ContentBuilder.cpp +++ b/src/content/ContentBuilder.cpp @@ -6,28 +6,6 @@ void ContentBuilder::add(std::unique_ptr pack) { packs[pack->getId()] = std::move(pack); } -Block& ContentBuilder::createBlock(const std::string& id) { - auto found = blockDefs.find(id); - if (found != blockDefs.end()) { - return *found->second; - } - checkIdentifier(id); - blockIds.push_back(id); - blockDefs[id] = std::make_unique(id); - return *blockDefs[id]; -} - -ItemDef& ContentBuilder::createItem(const std::string& id) { - auto found = itemDefs.find(id); - if (found != itemDefs.end()) { - return *found->second; - } - checkIdentifier(id); - itemIds.push_back(id); - itemDefs[id] = std::make_unique(id); - return *itemDefs[id]; -} - BlockMaterial& ContentBuilder::createBlockMaterial(const std::string& id) { blockMaterials[id] = std::make_unique(); auto& material = *blockMaterials[id]; @@ -35,28 +13,11 @@ BlockMaterial& ContentBuilder::createBlockMaterial(const std::string& id) { return material; } -void ContentBuilder::checkIdentifier(const std::string& id) { - contenttype result; - if (((result = checkContentType(id)) != contenttype::none)) { - throw namereuse_error("name "+id+" is already used", result); - } -} - -contenttype ContentBuilder::checkContentType(const std::string& id) { - if (blockDefs.find(id) != blockDefs.end()) { - return contenttype::block; - } - if (itemDefs.find(id) != itemDefs.end()) { - return contenttype::item; - } - return contenttype::none; -} - std::unique_ptr ContentBuilder::build() { std::vector blockDefsIndices; auto groups = std::make_unique(); - for (const std::string& name : blockIds) { - Block& def = *blockDefs[name]; + for (const std::string& name : blocks.names) { + Block& def = *blocks.defs[name]; // Generating runtime info def.rt.id = blockDefsIndices.size(); @@ -79,8 +40,8 @@ std::unique_ptr ContentBuilder::build() { } std::vector itemDefsIndices; - for (const std::string& name : itemIds) { - ItemDef& def = *itemDefs[name]; + for (const std::string& name : items.names) { + ItemDef& def = *items.defs[name]; // Generating runtime info def.rt.id = itemDefsIndices.size(); @@ -88,12 +49,24 @@ std::unique_ptr ContentBuilder::build() { itemDefsIndices.push_back(&def); } + std::vector entityDefsIndices; + for (const std::string& name : entities.names) { + EntityDef& def = *entities.defs[name]; + + // Generating runtime info + entityDefsIndices.push_back(&def); + } + auto content = std::make_unique( - std::make_unique(blockDefsIndices, itemDefsIndices), - std::move(groups), - std::move(blockDefs), - std::move(itemDefs), - std::move(packs), + std::make_unique( + blockDefsIndices, + itemDefsIndices, + entityDefsIndices), + std::move(groups), + blocks.build(), + items.build(), + entities.build(), + std::move(packs), std::move(blockMaterials) ); diff --git a/src/content/ContentBuilder.hpp b/src/content/ContentBuilder.hpp index 0c7a6d31..33e85e6e 100644 --- a/src/content/ContentBuilder.hpp +++ b/src/content/ContentBuilder.hpp @@ -3,6 +3,7 @@ #include "../items/ItemDef.hpp" #include "../voxels/Block.hpp" +#include "../objects/EntityDef.hpp" #include "../content/Content.hpp" #include "../content/ContentPack.hpp" @@ -10,27 +11,58 @@ #include #include +template +class ContentUnitBuilder { + std::unordered_map& allNames; + contenttype type; + + void checkIdentifier(const std::string& id) { + const auto& found = allNames.find(id); + if (found != allNames.end()) { + throw namereuse_error("name "+id+" is already used", found->second); + } + } +public: + std::unordered_map> defs; + std::vector names; + + ContentUnitBuilder( + std::unordered_map& allNames, + contenttype type + ) : allNames(allNames), type(type) {} + + T& create(const std::string& id) { + auto found = defs.find(id); + if (found != defs.end()) { + return *found->second; + } + checkIdentifier(id); + allNames[id] = type; + names.push_back(id); + defs[id] = std::make_unique(id); + return *defs[id]; + } + + auto build() { + return std::move(defs); + } +}; + class ContentBuilder { - std::unordered_map> blockDefs; - std::vector blockIds; - - std::unordered_map> itemDefs; - std::vector itemIds; - std::unordered_map> blockMaterials; std::unordered_map> packs; + std::unordered_map allNames; public: + ContentUnitBuilder blocks {allNames, contenttype::block}; + ContentUnitBuilder items {allNames, contenttype::item}; + ContentUnitBuilder entities {allNames, contenttype::entity}; + ~ContentBuilder(); void add(std::unique_ptr pack); - Block& createBlock(const std::string& id); - ItemDef& createItem(const std::string& id); BlockMaterial& createBlockMaterial(const std::string& id); - void checkIdentifier(const std::string& id); - contenttype checkContentType(const std::string& id); - std::unique_ptr build(); }; diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 73d8b3a3..265c93b7 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -363,14 +363,14 @@ void ContentLoader::load(ContentBuilder& builder) { auto colon = name.find(':'); std::string full = colon == std::string::npos ? pack->id + ":" + name : name; if (colon != std::string::npos) name[colon] = '/'; - auto& def = builder.createBlock(full); + auto& def = builder.blocks.create(full); if (colon != std::string::npos) { def.scriptName = name.substr(0, colon) + '/' + def.scriptName; } loadBlock(def, full, name); stats.totalBlocks++; if (!def.hidden) { - auto& item = builder.createItem(full+BLOCK_ITEM_SUFFIX); + auto& item = builder.items.create(full+BLOCK_ITEM_SUFFIX); item.generated = true; item.caption = def.caption; item.iconType = item_icon_type::block; @@ -392,7 +392,7 @@ void ContentLoader::load(ContentBuilder& builder) { auto colon = name.find(':'); std::string full = colon == std::string::npos ? pack->id + ":" + name : name; if (colon != std::string::npos) name[colon] = '/'; - auto& def = builder.createItem(full); + auto& def = builder.items.create(full); if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName; loadItem(def, full, name); stats.totalItems++; diff --git a/src/content/ContentLoader.hpp b/src/content/ContentLoader.hpp index fa1c4b61..7a5068eb 100644 --- a/src/content/ContentLoader.hpp +++ b/src/content/ContentLoader.hpp @@ -10,7 +10,7 @@ namespace fs = std::filesystem; class Block; struct BlockMaterial; -class ItemDef; +struct ItemDef; struct ContentPack; class ContentBuilder; diff --git a/src/core_defs.cpp b/src/core_defs.cpp index 57c85bbc..549988d0 100644 --- a/src/core_defs.cpp +++ b/src/core_defs.cpp @@ -12,7 +12,7 @@ // All in-game definitions (blocks, items, etc..) void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) { - Block& block = builder->createBlock("core:air"); + Block& block = builder->blocks.create("core:air"); block.replaceable = true; block.drawGroup = 1; block.lightPassing = true; @@ -22,7 +22,7 @@ void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) { block.model = BlockModel::none; block.pickingItem = "core:empty"; - ItemDef& item = builder->createItem("core:empty"); + ItemDef& item = builder->items.create("core:empty"); item.iconType = item_icon_type::none; auto bindsFile = paths->getResources()/fs::path("bindings.toml"); diff --git a/src/items/ItemDef.hpp b/src/items/ItemDef.hpp index 5abb2e32..015cfb21 100644 --- a/src/items/ItemDef.hpp +++ b/src/items/ItemDef.hpp @@ -19,8 +19,7 @@ enum class item_icon_type { block, // block preview: icon is string block id }; -class ItemDef { -public: +struct ItemDef { /// @brief Item string id (with prefix included) std::string const name; diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 6ac25e7b..3082420c 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -22,7 +22,7 @@ class ContentIndices; class Level; class Block; class Player; -class ItemDef; +struct ItemDef; class Inventory; class UiDocument; struct block_funcs_set; From f13589668313e69854947657b71dc4650631982a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 26 Jun 2024 18:14:04 +0300 Subject: [PATCH 014/178] add entities indexing --- src/content/ContentBuilder.cpp | 1 + src/content/ContentLoader.cpp | 51 +++++++++++++++++----------------- src/content/ContentLoader.hpp | 5 ++-- src/content/ContentPack.cpp | 4 --- src/content/ContentPack.hpp | 9 +++--- src/files/WorldFiles.cpp | 26 ++++++++--------- src/objects/EntityDef.hpp | 4 +++ 7 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp index adbe6425..723eabe1 100644 --- a/src/content/ContentBuilder.cpp +++ b/src/content/ContentBuilder.cpp @@ -54,6 +54,7 @@ std::unique_ptr ContentBuilder::build() { EntityDef& def = *entities.defs[name]; // Generating runtime info + def.rt.id = entityDefsIndices.size(); entityDefsIndices.push_back(&def); } diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 265c93b7..799ef94a 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -27,38 +27,36 @@ static debug::Logger logger("content-loader"); ContentLoader::ContentLoader(ContentPack* pack) : pack(pack) { } +static void detect_defs( + const fs::path& folder, + const std::string& prefix, + std::vector& detected +) { + if (fs::is_directory(folder)) { + for (const auto& entry : fs::directory_iterator(folder)) { + const fs::path& file = entry.path(); + std::string name = file.stem().string(); + if (name[0] == '_') { + continue; + } + if (fs::is_regular_file(file) && file.extension() == ".json") { + detected.push_back(prefix.empty() ? name : prefix + ":" + name); + } else if (fs::is_directory(file)) { + detect_defs(file, name, detected); + } + } + } +} + bool ContentLoader::fixPackIndices( const fs::path& folder, dynamic::Map* indicesRoot, const std::string& contentSection ) { std::vector detected; - std::vector indexed; - if (fs::is_directory(folder)) { - for (const auto& entry : fs::directory_iterator(folder)) { - const fs::path& file = entry.path(); - if (fs::is_regular_file(file) && file.extension() == ".json") { - std::string name = file.stem().string(); - if (name[0] == '_') - continue; - detected.push_back(name); - } else if (fs::is_directory(file)) { - std::string space = file.stem().string(); - if (space[0] == '_') - continue; - for (const auto& entry : fs::directory_iterator(file)) { - const fs::path& file = entry.path(); - if (fs::is_regular_file(file) && file.extension() == ".json") { - std::string name = file.stem().string(); - if (name[0] == '_') - continue; - detected.push_back(space + ':' + name); - } - } - } - } - } + detect_defs(folder, "", detected); + std::vector indexed; bool modified = false; if (!indicesRoot->has(contentSection)) { indicesRoot->putList(contentSection); @@ -90,6 +88,7 @@ void ContentLoader::fixPackIndices() { auto indexFile = pack->getContentFile(); auto blocksFolder = folder/ContentPack::BLOCKS_FOLDER; auto itemsFolder = folder/ContentPack::ITEMS_FOLDER; + auto entitiesFolder = folder/ContentPack::ENTITIES_FOLDER; dynamic::Map_sptr root; if (fs::is_regular_file(indexFile)) { @@ -99,9 +98,9 @@ void ContentLoader::fixPackIndices() { } bool modified = false; - modified |= fixPackIndices(blocksFolder, root.get(), "blocks"); modified |= fixPackIndices(itemsFolder, root.get(), "items"); + modified |= fixPackIndices(entitiesFolder, root.get(), "entities"); if (modified){ // rewrite modified json diff --git a/src/content/ContentLoader.hpp b/src/content/ContentLoader.hpp index 7a5068eb..6c04b6db 100644 --- a/src/content/ContentLoader.hpp +++ b/src/content/ContentLoader.hpp @@ -26,6 +26,9 @@ class ContentLoader { void loadCustomBlockModel(Block& def, dynamic::Map* primitives); void loadItem(ItemDef& def, const std::string& full, const std::string& name); void loadBlockMaterial(BlockMaterial& def, const fs::path& file); + + void loadBlock(Block& def, const std::string& name, const fs::path& file); + void loadItem(ItemDef& def, const std::string& name, const fs::path& file); public: ContentLoader(ContentPack* pack); @@ -35,8 +38,6 @@ public: const std::string& contentSection ); void fixPackIndices(); - void loadBlock(Block& def, const std::string& name, const fs::path& file); - void loadItem(ItemDef& def, const std::string& name, const fs::path& file); void load(ContentBuilder& builder); }; diff --git a/src/content/ContentPack.cpp b/src/content/ContentPack.cpp index e3a5f0f1..8388e30c 100644 --- a/src/content/ContentPack.cpp +++ b/src/content/ContentPack.cpp @@ -11,10 +11,6 @@ namespace fs = std::filesystem; -const std::string ContentPack::PACKAGE_FILENAME = "package.json"; -const std::string ContentPack::CONTENT_FILENAME = "content.json"; -const fs::path ContentPack::BLOCKS_FOLDER = "blocks"; -const fs::path ContentPack::ITEMS_FOLDER = "items"; const std::vector ContentPack::RESERVED_NAMES = { "res", "abs", "local", "core", "user", "world", "none", "null" }; diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index ca0aff2e..dfb62033 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -46,10 +46,11 @@ struct ContentPack { fs::path getContentFile() const; - static const std::string PACKAGE_FILENAME; - static const std::string CONTENT_FILENAME; - static const fs::path BLOCKS_FOLDER; - static const fs::path ITEMS_FOLDER; + static inline const std::string PACKAGE_FILENAME = "package.json"; + static inline const std::string CONTENT_FILENAME = "content.json"; + static inline const fs::path BLOCKS_FOLDER = "blocks"; + static inline const fs::path ITEMS_FOLDER = "items"; + static inline const fs::path ENTITIES_FOLDER = "entities"; static const std::vector RESERVED_NAMES; static bool is_pack(const fs::path& folder); diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index 82b70881..b497b69a 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -11,6 +11,7 @@ #include "../lighting/Lightmap.hpp" #include "../maths/voxmaths.hpp" #include "../objects/Player.hpp" +#include "../objects/EntityDef.hpp" #include "../physics/Hitbox.hpp" #include "../typedefs.hpp" #include "../settings.hpp" @@ -92,22 +93,19 @@ void WorldFiles::writePacks(const std::vector& packs) { files::write_string(packsFile, ss.str()); } +template +static void write_indices(const ContentUnitIndices& indices, dynamic::List& list) { + size_t count = indices.count(); + for (size_t i = 0; i < count; i++) { + list.put(indices.get(i)->name); + } +} + void WorldFiles::writeIndices(const ContentIndices* indices) { dynamic::Map root; - uint count; - auto& blocks = root.putList("blocks"); - count = indices->blocks.count(); - for (uint i = 0; i < count; i++) { - const Block* def = indices->blocks.get(i); - blocks.put(def->name); - } - - auto& items = root.putList("items"); - count = indices->items.count(); - for (uint i = 0; i < count; i++) { - items.put(indices->items.get(i)->name); - } - + write_indices(indices->blocks, root.putList("blocks")); + write_indices(indices->items, root.putList("items")); + write_indices(indices->entities, root.putList("entities")); files::write_json(getIndicesFile(), &root); } diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index 06510099..70f8653b 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -8,6 +8,10 @@ struct EntityDef { /// @brief Entity string id (with prefix included) std::string const name; + + struct { + entityid_t id; + } rt; EntityDef(const std::string& name); EntityDef(const EntityDef&) = delete; From 8d41f6af115ac2e0c26ba70b57a2bad28104454d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 26 Jun 2024 23:36:01 +0300 Subject: [PATCH 015/178] update ContentLoader part 1 --- src/content/ContentLoader.cpp | 119 ++++++++++++++++++++++------------ src/content/ContentLoader.hpp | 21 ++++-- src/content/ContentPack.hpp | 3 +- src/engine.cpp | 5 +- src/objects/EntityDef.hpp | 4 +- 5 files changed, 98 insertions(+), 54 deletions(-) diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 799ef94a..40b0b625 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -24,7 +24,15 @@ namespace fs = std::filesystem; static debug::Logger logger("content-loader"); -ContentLoader::ContentLoader(ContentPack* pack) : pack(pack) { +ContentLoader::ContentLoader(ContentPack* pack, ContentBuilder& builder) + : pack(pack), builder(builder) +{ + auto runtime = std::make_unique( + *pack, scripting::create_pack_environment(*pack) + ); + stats = &runtime->getStatsWriteable(); + env = runtime->getEnvironment(); + builder.add(std::move(runtime)); } static void detect_defs( @@ -172,7 +180,7 @@ void ContentLoader::loadBlock(Block& def, const std::string& name, const fs::pat def.hitboxes[i].b = glm::vec3(box->num(3), box->num(4), box->num(5)); def.hitboxes[i].b += def.hitboxes[i].a; } - } else if (auto boxarr = root->list("hitbox")){ + } else if ((boxarr = root->list("hitbox"))){ AABB aabb; aabb.a = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2)); aabb.b = glm::vec3(boxarr->num(3), boxarr->num(4), boxarr->num(5)); @@ -301,25 +309,47 @@ void ContentLoader::loadItem(ItemDef& def, const std::string& name, const fs::pa } } +void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs::path& file) { + auto root = files::read_json(file); + +} + +void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const std::string& name) { + auto folder = pack->folder; + auto configFile = folder/fs::path("entities/"+name+".json"); + if (fs::exists(configFile)) loadEntity(def, full, configFile); +} + void ContentLoader::loadBlock(Block& def, const std::string& full, const std::string& name) { auto folder = pack->folder; - - fs::path configFile = folder/fs::path("blocks/"+name+".json"); + auto configFile = folder/fs::path("blocks/"+name+".json"); if (fs::exists(configFile)) loadBlock(def, full, configFile); - fs::path scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua"); + auto scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua"); if (fs::is_regular_file(scriptfile)) { scripting::load_block_script(env, full, scriptfile, def.rt.funcsset); } + if (!def.hidden) { + auto& item = builder.items.create(full+BLOCK_ITEM_SUFFIX); + item.generated = true; + item.caption = def.caption; + item.iconType = item_icon_type::block; + item.icon = full; + item.placingBlock = full; + + for (uint j = 0; j < 4; j++) { + item.emission[j] = def.emission[j]; + } + stats->totalItems++; + } } void ContentLoader::loadItem(ItemDef& def, const std::string& full, const std::string& name) { auto folder = pack->folder; - - fs::path configFile = folder/fs::path("items/"+name+".json"); + auto configFile = folder/fs::path("items/"+name+".json"); if (fs::exists(configFile)) loadItem(def, full, configFile); - fs::path scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua"); + auto scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua"); if (fs::is_regular_file(scriptfile)) { scripting::load_item_script(env, full, scriptfile, def.rt.funcsset); } @@ -332,15 +362,27 @@ void ContentLoader::loadBlockMaterial(BlockMaterial& def, const fs::path& file) root->str("break-sound", def.breakSound); } -void ContentLoader::load(ContentBuilder& builder) { - logger.info() << "loading pack [" << pack->id << "]"; +template +static void load_defs(ContentLoader* cl, dynamic::List* arr, const ContentPack* pack, ContentUnitBuilder& builder, size_t& counter) { + if (arr == nullptr) { + return; + } + for (size_t i = 0; i < arr->size(); i++) { + std::string name = arr->str(i); + auto colon = name.find(':'); + std::string full = colon == std::string::npos ? pack->id + ":" + name : name; + if (colon != std::string::npos) name[colon] = '/'; + auto& def = builder.create(full); + if (colon != std::string::npos) { + def.scriptName = name.substr(0, colon) + '/' + def.scriptName; + } + cl->*loadfunc(def, full, name); + counter++; + } +} - auto runtime = std::make_unique( - *pack, scripting::create_pack_environment(*pack) - ); - env = runtime->getEnvironment(); - ContentPackStats& stats = runtime->getStatsWriteable(); - builder.add(std::move(runtime)); +void ContentLoader::load() { + logger.info() << "loading pack [" << pack->id << "]"; fixPackIndices(); @@ -355,38 +397,21 @@ void ContentLoader::load(ContentBuilder& builder) { return; auto root = files::read_json(pack->getContentFile()); - auto blocksarr = root->list("blocks"); - if (blocksarr) { - for (uint i = 0; i < blocksarr->size(); i++) { + + if (auto blocksarr = root->list("blocks")) { + for (size_t i = 0; i < blocksarr->size(); i++) { std::string name = blocksarr->str(i); auto colon = name.find(':'); std::string full = colon == std::string::npos ? pack->id + ":" + name : name; if (colon != std::string::npos) name[colon] = '/'; auto& def = builder.blocks.create(full); - if (colon != std::string::npos) { - def.scriptName = name.substr(0, colon) + '/' + def.scriptName; - } + if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName; loadBlock(def, full, name); - stats.totalBlocks++; - if (!def.hidden) { - auto& item = builder.items.create(full+BLOCK_ITEM_SUFFIX); - item.generated = true; - item.caption = def.caption; - item.iconType = item_icon_type::block; - item.icon = full; - item.placingBlock = full; - - for (uint j = 0; j < 4; j++) { - item.emission[j] = def.emission[j]; - } - stats.totalItems++; - } + stats->totalBlocks++; } } - - auto itemsarr = root->list("items"); - if (itemsarr) { - for (uint i = 0; i < itemsarr->size(); i++) { + if (auto itemsarr = root->list("items")) { + for (size_t i = 0; i < itemsarr->size(); i++) { std::string name = itemsarr->str(i); auto colon = name.find(':'); std::string full = colon == std::string::npos ? pack->id + ":" + name : name; @@ -394,7 +419,19 @@ void ContentLoader::load(ContentBuilder& builder) { auto& def = builder.items.create(full); if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName; loadItem(def, full, name); - stats.totalItems++; + stats->totalItems++; + } + } + if (auto entitiesarr = root->list("entities")) { + for (size_t i = 0; i < entitiesarr->size(); i++) { + std::string name = entitiesarr->str(i); + auto colon = name.find(':'); + std::string full = colon == std::string::npos ? pack->id + ":" + name : name; + if (colon != std::string::npos) name[colon] = '/'; + auto& def = builder.entities.create(full); + if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName; + loadEntity(def, full, name); + stats->totalEntities++; } } diff --git a/src/content/ContentLoader.hpp b/src/content/ContentLoader.hpp index 6c04b6db..8d236d35 100644 --- a/src/content/ContentLoader.hpp +++ b/src/content/ContentLoader.hpp @@ -4,6 +4,7 @@ #include "../typedefs.hpp" #include +#include #include namespace fs = std::filesystem; @@ -11,8 +12,10 @@ namespace fs = std::filesystem; class Block; struct BlockMaterial; struct ItemDef; +struct EntityDef; struct ContentPack; class ContentBuilder; +struct ContentPackStats; namespace dynamic { class Map; @@ -21,16 +24,20 @@ namespace dynamic { class ContentLoader { const ContentPack* pack; scriptenv env; - + ContentBuilder& builder; + ContentPackStats* stats; + void loadBlock(Block& def, const std::string& full, const std::string& name); - void loadCustomBlockModel(Block& def, dynamic::Map* primitives); void loadItem(ItemDef& def, const std::string& full, const std::string& name); - void loadBlockMaterial(BlockMaterial& def, const fs::path& file); + void loadEntity(EntityDef& def, const std::string& full, const std::string& name); - void loadBlock(Block& def, const std::string& name, const fs::path& file); - void loadItem(ItemDef& def, const std::string& name, const fs::path& file); + static void loadCustomBlockModel(Block& def, dynamic::Map* primitives); + static void loadBlockMaterial(BlockMaterial& def, const fs::path& file); + static void loadBlock(Block& def, const std::string& name, const fs::path& file); + static void loadItem(ItemDef& def, const std::string& name, const fs::path& file); + static void loadEntity(EntityDef& def, const std::string& name, const fs::path& file); public: - ContentLoader(ContentPack* pack); + ContentLoader(ContentPack* pack, ContentBuilder& builder); bool fixPackIndices( const fs::path& folder, @@ -38,7 +45,7 @@ public: const std::string& contentSection ); void fixPackIndices(); - void load(ContentBuilder& builder); + void load(); }; #endif // CONTENT_CONTENT_LOADER_HPP_ diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index dfb62033..1dc17521 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -73,9 +73,10 @@ struct ContentPack { struct ContentPackStats { size_t totalBlocks; size_t totalItems; + size_t totalEntities; inline bool hasSavingContent() const { - return totalBlocks + totalItems > 0; + return totalBlocks + totalItems + totalEntities > 0; } }; diff --git a/src/engine.cpp b/src/engine.cpp index b7396ff3..a87f52fa 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -289,10 +289,7 @@ void Engine::loadContent() { std::vector resRoots; for (auto& pack : contentPacks) { resRoots.push_back({pack.id, pack.folder}); - - ContentLoader loader(&pack); - loader.load(contentBuilder); - + ContentLoader(&pack, contentBuilder).load(); load_configs(pack.folder); } load_configs(paths->getResources()); diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index 70f8653b..f80fd5be 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -9,11 +9,13 @@ struct EntityDef { /// @brief Entity string id (with prefix included) std::string const name; + std::string scriptName = name.substr(name.find(':')+1); + struct { entityid_t id; } rt; - EntityDef(const std::string& name); + EntityDef(const std::string& name) : name(name) {} EntityDef(const EntityDef&) = delete; }; From 20ab48ecabd5b585989c758e04ff2ce01ee3399a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 27 Jun 2024 03:09:16 +0300 Subject: [PATCH 016/178] add drop.json --- res/content/base/content.json | 7 +++++-- res/content/base/entities/drop.json | 3 +++ res/content/base/scripts/hud.lua | 2 +- src/content/ContentLoader.cpp | 9 ++++++--- src/logic/scripting/lua/libentity.cpp | 9 ++++++--- src/objects/Entities.cpp | 6 +++--- src/objects/Entities.hpp | 3 ++- src/objects/EntityDef.hpp | 2 ++ 8 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 res/content/base/entities/drop.json diff --git a/res/content/base/content.json b/res/content/base/content.json index 0e6dc07f..dd1573a1 100644 --- a/res/content/base/content.json +++ b/res/content/base/content.json @@ -1,6 +1,6 @@ { - "items": [ - "bazalt_breaker" + "entities": [ + "drop" ], "blocks": [ "dirt", @@ -27,5 +27,8 @@ "lightbulb", "torch", "wooden_door" + ], + "items": [ + "bazalt_breaker" ] } \ No newline at end of file diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json new file mode 100644 index 00000000..c0b8db42 --- /dev/null +++ b/res/content/base/entities/drop.json @@ -0,0 +1,3 @@ +{ + "hitbox": [0.2, 0.2, 0.2] +} diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index d85e3201..f5bc77ba 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -5,7 +5,7 @@ function on_hud_open() input.add_callback("player.drop", function () local pid = hud.get_player() local pvel = {player.get_vel(pid)} - local eid = entity.test() + local eid = entity.spawn("base:drop") local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) entity.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) end) diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 40b0b625..f966c633 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -301,8 +301,7 @@ void ContentLoader::loadItem(ItemDef& def, const std::string& name, const fs::pa root->num("stack-size", def.stackSize); // item light emission [r, g, b] where r,g,b in range [0..15] - auto emissionarr = root->list("emission"); - if (emissionarr) { + if (auto emissionarr = root->list("emission")) { def.emission[0] = emissionarr->num(0); def.emission[1] = emissionarr->num(1); def.emission[2] = emissionarr->num(2); @@ -311,7 +310,11 @@ void ContentLoader::loadItem(ItemDef& def, const std::string& name, const fs::pa void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs::path& file) { auto root = files::read_json(file); - + root->str("script-name", def.scriptName); + if (auto boxarr = root->list("hitbox")) { + def.hitbox = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2)); + } + std::cout << "loading entity " << name << " from " << file.u8string() << std::endl; } void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const std::string& name) { diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 859364a8..c66cda80 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -7,6 +7,7 @@ #include "../../../physics/Hitbox.hpp" #include "../../../window/Camera.hpp" #include "../../../frontend/hud.hpp" +#include "../../../content/Content.hpp" #include @@ -21,10 +22,12 @@ static std::optional get_entity(lua::State* L, int idx) { return level->entities->get(id); } -static int l_test(lua::State* L) { +static int l_spawn(lua::State* L) { auto level = controller->getLevel(); auto player = hud->getPlayer(); - auto id = level->entities->drop(player->camera->position); + auto defname = lua::tostring(L, 1); + auto& def = content->entities.require(defname); + auto id = level->entities->spawn(def, player->camera->position); return lua::pushinteger(L, id); } @@ -43,7 +46,7 @@ static int l_set_vel(lua::State* L) { } const luaL_Reg entitylib [] = { - {"test", lua::wrap}, + {"spawn", lua::wrap}, {"get_vel", lua::wrap}, {"set_vel", lua::wrap}, {NULL, NULL} diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index b4218fe9..0b83b52c 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -8,6 +8,7 @@ #include "../graphics/core/LineBatch.hpp" #include "../graphics/core/Model.hpp" #include "../maths/FrustumCulling.hpp" +#include "../objects/EntityDef.hpp" #include @@ -21,14 +22,13 @@ void Transform::refresh() { Entities::Entities(Level* level) : level(level) { } -entityid_t Entities::drop(glm::vec3 pos) { +entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { auto entity = registry.create(); glm::vec3 size(1); auto id = nextID++; registry.emplace(entity, static_cast(id)); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); - registry.emplace(entity, pos, - glm::vec3(size.x*0.2f, size.y*0.5f, size.z*0.2f)); + registry.emplace(entity, pos, def.hitbox); entities[id] = entity; return id; } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 431cf98f..3613f860 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -28,6 +28,7 @@ class LineBatch; class ModelBatch; class Frustum; class Rig; +struct EntityDef; class Entity { entt::registry& registry; @@ -65,7 +66,7 @@ public: void renderDebug(LineBatch& batch); void render(Assets* assets, ModelBatch& batch, Frustum& frustum); - entityid_t drop(glm::vec3 pos); + entityid_t spawn(EntityDef& def, glm::vec3 pos); std::optional get(entityid_t id) { const auto& found = entities.find(id); diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index f80fd5be..e001bdbe 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -2,6 +2,7 @@ #define OBJECTS_ENTITY_DEF_HPP_ #include +#include #include "../typedefs.hpp" @@ -10,6 +11,7 @@ struct EntityDef { std::string const name; std::string scriptName = name.substr(name.find(':')+1); + glm::vec3 hitbox {0.5f}; struct { entityid_t id; From f70e923c7c2f09f9a0c4ad6cbb2135090365cb35 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 27 Jun 2024 05:23:44 +0300 Subject: [PATCH 017/178] entity.get_rot, .set_rot --- res/content/base/entities/drop.json | 2 +- res/content/base/scripts/hud.lua | 1 + src/logic/scripting/lua/libentity.cpp | 16 ++++++++++++++++ src/objects/Entities.cpp | 4 ++-- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json index c0b8db42..e895490b 100644 --- a/res/content/base/entities/drop.json +++ b/res/content/base/entities/drop.json @@ -1,3 +1,3 @@ { - "hitbox": [0.2, 0.2, 0.2] + "hitbox": [0.2, 0.15, 0.2] } diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index f5bc77ba..d9f27bc0 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -8,5 +8,6 @@ function on_hud_open() local eid = entity.spawn("base:drop") local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) entity.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) + entity.set_rot(eid, mat4.rotate({0, 1, 0}, math.random() * 360)) end) end diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index c66cda80..fae0054b 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -45,9 +45,25 @@ static int l_set_vel(lua::State* L) { return 0; } +static int l_get_rot(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + return lua::pushmat4(L, entity->getTransform().rot); + } + return 0; +} + +static int l_set_rot(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + entity->getTransform().rot = lua::tomat4(L, 2); + } + return 0; +} + const luaL_Reg entitylib [] = { {"spawn", lua::wrap}, {"get_vel", lua::wrap}, {"set_vel", lua::wrap}, + {"get_rot", lua::wrap}, + {"set_rot", lua::wrap}, {NULL, NULL} }; diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 0b83b52c..6d886afc 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -46,9 +46,9 @@ void Entities::updatePhysics(float delta){ 1.0f, true ); - hitbox.linear_damping = hitbox.grounded * 5; + hitbox.linear_damping = hitbox.grounded * 12; transform.pos = hitbox.position; - transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); + //transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); if (hitbox.grounded) { //hitbox.velocity.y = 10; } From 94dd69350de0fd1d9629d4bdf69fb89fb74765b4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 27 Jun 2024 07:43:38 +0300 Subject: [PATCH 018/178] add Transform and Rigidbody components (test) --- res/content/base/scripts/hud.lua | 4 ++-- src/logic/scripting/lua/api_lua.hpp | 2 ++ src/logic/scripting/lua/libentity.cpp | 28 ++++++++++++++++++++++++-- src/logic/scripting/lua/lua_engine.cpp | 4 ++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index d9f27bc0..09e83f6b 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -7,7 +7,7 @@ function on_hud_open() local pvel = {player.get_vel(pid)} local eid = entity.spawn("base:drop") local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) - entity.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) - entity.set_rot(eid, mat4.rotate({0, 1, 0}, math.random() * 360)) + Rigidbody.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) + Transform.set_rot(eid, mat4.rotate({0, 1, 0}, math.random() * 360)) end) end diff --git a/src/logic/scripting/lua/api_lua.hpp b/src/logic/scripting/lua/api_lua.hpp index 7026325d..5b709c8d 100644 --- a/src/logic/scripting/lua/api_lua.hpp +++ b/src/logic/scripting/lua/api_lua.hpp @@ -21,8 +21,10 @@ extern const luaL_Reg jsonlib []; extern const luaL_Reg mat4lib []; extern const luaL_Reg packlib []; extern const luaL_Reg playerlib []; +extern const luaL_Reg rigidbodylib []; extern const luaL_Reg timelib []; extern const luaL_Reg tomllib []; +extern const luaL_Reg transformlib []; extern const luaL_Reg vec2lib []; extern const luaL_Reg vec3lib []; extern const luaL_Reg vec4lib []; diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index fae0054b..36676655 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -31,6 +31,20 @@ static int l_spawn(lua::State* L) { return lua::pushinteger(L, id); } +static int l_get_pos(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + return lua::pushvec3_arr(L, entity->getTransform().pos); + } + return 0; +} + +static int l_set_pos(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + entity->getTransform().pos = lua::tovec3(L, 2); + } + return 0; +} + static int l_get_vel(lua::State* L) { if (auto entity = get_entity(L, 1)) { return lua::pushvec3_arr(L, entity->getHitbox().velocity); @@ -61,9 +75,19 @@ static int l_set_rot(lua::State* L) { const luaL_Reg entitylib [] = { {"spawn", lua::wrap}, - {"get_vel", lua::wrap}, - {"set_vel", lua::wrap}, + {NULL, NULL} +}; + + const luaL_Reg transformlib [] = { + {"get_pos", lua::wrap}, + {"set_pos", lua::wrap}, {"get_rot", lua::wrap}, {"set_rot", lua::wrap}, {NULL, NULL} + }; + +const luaL_Reg rigidbodylib [] = { + {"get_vel", lua::wrap}, + {"set_vel", lua::wrap}, + {NULL, NULL} }; diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index 6d5facfb..3339204d 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -48,6 +48,10 @@ static void create_libs(lua::State* L) { openlib(L, "vec4", vec4lib); openlib(L, "world", worldlib); + // components + openlib(L, "Rigidbody", rigidbodylib); + openlib(L, "Transform", transformlib); + addfunc(L, "print", lua::wrap); } From 1ca0761f49a5af388416a02b2676204e3d70ef90 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 27 Jun 2024 07:50:26 +0300 Subject: [PATCH 019/178] update entity.spawn(...) --- res/content/base/scripts/hud.lua | 3 ++- src/logic/scripting/lua/libentity.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 09e83f6b..710a8e5e 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -5,7 +5,8 @@ function on_hud_open() input.add_callback("player.drop", function () local pid = hud.get_player() local pvel = {player.get_vel(pid)} - local eid = entity.spawn("base:drop") + local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) + local eid = entity.spawn("base:drop", ppos) local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) Rigidbody.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) Transform.set_rot(eid, mat4.rotate({0, 1, 0}, math.random() * 360)) diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 36676655..894e17c9 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -24,10 +24,10 @@ static std::optional get_entity(lua::State* L, int idx) { static int l_spawn(lua::State* L) { auto level = controller->getLevel(); - auto player = hud->getPlayer(); auto defname = lua::tostring(L, 1); auto& def = content->entities.require(defname); - auto id = level->entities->spawn(def, player->camera->position); + auto pos = lua::tovec3(L, 2); + auto id = level->entities->spawn(def, pos); return lua::pushinteger(L, id); } From 6d7f950410719ab971d76fc105e16e98e82fb6f5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 27 Jun 2024 08:23:01 +0300 Subject: [PATCH 020/178] add Rigidbody.is_enabled, .set_enabled --- src/logic/scripting/lua/libentity.cpp | 20 ++++++++++++++++++-- src/objects/Entities.cpp | 10 +++++++--- src/objects/Entities.hpp | 9 +++++++-- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 894e17c9..1a7cf027 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -47,14 +47,14 @@ static int l_set_pos(lua::State* L) { static int l_get_vel(lua::State* L) { if (auto entity = get_entity(L, 1)) { - return lua::pushvec3_arr(L, entity->getHitbox().velocity); + return lua::pushvec3_arr(L, entity->getRigidbody().hitbox.velocity); } return 0; } static int l_set_vel(lua::State* L) { if (auto entity = get_entity(L, 1)) { - entity->getHitbox().velocity = lua::tovec3(L, 2); + entity->getRigidbody().hitbox.velocity = lua::tovec3(L, 2); } return 0; } @@ -73,6 +73,20 @@ static int l_set_rot(lua::State* L) { return 0; } +static int l_is_enabled(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + lua::pushboolean(L, entity->getRigidbody().enabled); + } + return 0; +} + +static int l_set_enabled(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + entity->getRigidbody().enabled = lua::toboolean(L, 2); + } + return 0; +} + const luaL_Reg entitylib [] = { {"spawn", lua::wrap}, {NULL, NULL} @@ -87,6 +101,8 @@ const luaL_Reg entitylib [] = { }; const luaL_Reg rigidbodylib [] = { + {"is_enabled", lua::wrap}, + {"set_enabled", lua::wrap}, {"get_vel", lua::wrap}, {"set_vel", lua::wrap}, {NULL, NULL} diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 6d886afc..9261db2a 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -28,15 +28,19 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { auto id = nextID++; registry.emplace(entity, static_cast(id)); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); - registry.emplace(entity, pos, def.hitbox); + registry.emplace(entity, true, Hitbox {pos, def.hitbox}); entities[id] = entity; return id; } void Entities::updatePhysics(float delta){ - auto view = registry.view(); + auto view = registry.view(); auto physics = level->physics.get(); - for (auto [entity, transform, hitbox] : view.each()) { + for (auto [entity, transform, rigidbody] : view.each()) { + if (!rigidbody.enabled) { + continue; + } + auto& hitbox = rigidbody.hitbox; physics->step( level->chunks.get(), &hitbox, diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 3613f860..376462df 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -22,6 +22,11 @@ struct Transform { void refresh(); }; +struct Rigidbody { + bool enabled = true; + Hitbox hitbox; +}; + class Level; class Assets; class LineBatch; @@ -45,8 +50,8 @@ public: return registry.get(entity); } - Hitbox& getHitbox() const { - return registry.get(entity); + Rigidbody& getRigidbody() const { + return registry.get(entity); } entityid_t getUID() const { From e11760a5e4a9a300b3266d319fc50c75bbafd401 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 27 Jun 2024 14:26:51 +0300 Subject: [PATCH 021/178] add entity.despawn(...) --- src/logic/LevelController.cpp | 1 + src/logic/scripting/lua/libentity.cpp | 16 ++++++++++++++++ src/objects/Entities.cpp | 10 ++++++++++ src/objects/Entities.hpp | 16 +++++++++++++--- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index 551beb71..f42bc926 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -40,6 +40,7 @@ void LevelController::update(float delta, bool input, bool pause) { level->objects.end() ); + level->entities->clean(); if (!pause) { // update all objects that needed for (const auto& obj : level->objects) { diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 1a7cf027..fbc19c1c 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -31,6 +31,13 @@ static int l_spawn(lua::State* L) { return lua::pushinteger(L, id); } +static int l_despawn(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + entity->destroy(); + } + return 0; +} + static int l_get_pos(lua::State* L) { if (auto entity = get_entity(L, 1)) { return lua::pushvec3_arr(L, entity->getTransform().pos); @@ -87,8 +94,16 @@ static int l_set_enabled(lua::State* L) { return 0; } +static int l_get_size(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + return lua::pushvec3(L, entity->getRigidbody().hitbox.halfsize * 2.0f); + } + return 0; +} + const luaL_Reg entitylib [] = { {"spawn", lua::wrap}, + {"despawn", lua::wrap}, {NULL, NULL} }; @@ -105,5 +120,6 @@ const luaL_Reg rigidbodylib [] = { {"set_enabled", lua::wrap}, {"get_vel", lua::wrap}, {"set_vel", lua::wrap}, + {"get_size", lua::wrap}, {NULL, NULL} }; diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 9261db2a..ce1cc171 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -33,6 +33,16 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { return id; } +void Entities::clean() { + for (auto it = entities.begin(); it != entities.end(); ++it) { + if (registry.valid(it->second)) { + ++it; + } else { + it = entities.erase(it); + } + } +} + void Entities::updatePhysics(float delta){ auto view = registry.view(); auto physics = level->physics.get(); diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 376462df..5d684a8b 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -36,11 +36,16 @@ class Rig; struct EntityDef; class Entity { + entityid_t id; entt::registry& registry; const entt::entity entity; public: - Entity(entt::registry& registry, const entt::entity entity) - : registry(registry), entity(entity) {} + Entity(entityid_t id, entt::registry& registry, const entt::entity entity) + : id(id), registry(registry), entity(entity) {} + + entityid_t getID() const { + return id; + } bool isValid() const { return registry.valid(entity); @@ -57,6 +62,10 @@ public: entityid_t getUID() const { return registry.get(entity).uid; } + + void destroy() { + registry.destroy(entity); + } }; class Entities { @@ -66,6 +75,7 @@ class Entities { entityid_t nextID = 1; public: Entities(Level* level); + void clean(); void updatePhysics(float delta); void renderDebug(LineBatch& batch); @@ -76,7 +86,7 @@ public: std::optional get(entityid_t id) { const auto& found = entities.find(id); if (found != entities.end()) { - return Entity(registry, found->second); + return Entity(id, registry, found->second); } return std::nullopt; } From 4df0f4e1e43090d07e06d0c285121116326b30d7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 27 Jun 2024 15:53:51 +0300 Subject: [PATCH 022/178] fix destroyed entities validation --- src/objects/Entities.cpp | 2 +- src/objects/Entities.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index ce1cc171..291ac1fd 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -34,7 +34,7 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { } void Entities::clean() { - for (auto it = entities.begin(); it != entities.end(); ++it) { + for (auto it = entities.begin(); it != entities.end();) { if (registry.valid(it->second)) { ++it; } else { diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 5d684a8b..1e020605 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -85,7 +85,7 @@ public: std::optional get(entityid_t id) { const auto& found = entities.find(id); - if (found != entities.end()) { + if (found != entities.end() && registry.valid(found->second)) { return Entity(id, registry, found->second); } return std::nullopt; From e1eb652ef4faab5de04478216124baf2a490cade Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 27 Jun 2024 16:07:40 +0300 Subject: [PATCH 023/178] add entity.exists(...) --- src/logic/scripting/lua/libentity.cpp | 5 +++++ src/objects/Entities.hpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index fbc19c1c..42cc01fb 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -22,6 +22,10 @@ static std::optional get_entity(lua::State* L, int idx) { return level->entities->get(id); } +static int l_exists(lua::State* L) { + return lua::pushboolean(L, get_entity(L, 1).has_value()); +} + static int l_spawn(lua::State* L) { auto level = controller->getLevel(); auto defname = lua::tostring(L, 1); @@ -102,6 +106,7 @@ static int l_get_size(lua::State* L) { } const luaL_Reg entitylib [] = { + {"exists", lua::wrap}, {"spawn", lua::wrap}, {"despawn", lua::wrap}, {NULL, NULL} diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 1e020605..c4845e00 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -90,6 +90,10 @@ public: } return std::nullopt; } + + inline size_t size() const { + return entities.size(); + } }; #endif // OBJECTS_ENTITIES_HPP_ From eb2be5e8b6a0c590c5ea59eec1a1905e4191f5f9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 28 Jun 2024 12:16:31 +0300 Subject: [PATCH 024/178] add entity events: on_spawn, on_despawn --- res/content/base/scripts/drop.lua | 7 +++++++ src/content/ContentLoader.cpp | 5 +++++ src/logic/scripting/scripting.cpp | 26 ++++++++++++++++++++++++++ src/logic/scripting/scripting.hpp | 25 +++++++++++++++++++++++-- src/objects/Entities.cpp | 21 +++++++++++++++++++-- src/objects/Entities.hpp | 24 ++++++++++++++++++------ src/objects/EntityDef.hpp | 7 +++++++ src/objects/Player.cpp | 6 +++--- src/objects/Player.hpp | 2 +- src/physics/Hitbox.cpp | 2 +- src/physics/Hitbox.hpp | 5 ++--- src/physics/PhysicsSolver.cpp | 6 +++--- src/physics/PhysicsSolver.hpp | 2 +- 13 files changed, 116 insertions(+), 22 deletions(-) create mode 100644 res/content/base/scripts/drop.lua diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua new file mode 100644 index 00000000..9a691298 --- /dev/null +++ b/res/content/base/scripts/drop.lua @@ -0,0 +1,7 @@ +function on_spawn(eid) + print("spawn", eid) +end + +function on_despawn(eid) + print("despawn", eid) +end diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index f966c633..ad4f7072 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -321,6 +321,11 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const st auto folder = pack->folder; auto configFile = folder/fs::path("entities/"+name+".json"); if (fs::exists(configFile)) loadEntity(def, full, configFile); + + auto scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua"); + if (fs::is_regular_file(scriptfile)) { + scripting::load_entity_script(env, full, scriptfile, def.rt.funcsset); + } } void ContentLoader::loadBlock(Block& def, const std::string& full, const std::string& name) { diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 7572faa2..8d017d5b 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -13,6 +13,8 @@ #include "../../logic/BlocksController.hpp" #include "../../logic/LevelController.hpp" #include "../../objects/Player.hpp" +#include "../../objects/EntityDef.hpp" +#include "../../objects/Entities.hpp" #include "../../util/stringutil.hpp" #include "../../util/timeutil.hpp" #include "../../util/timeutil.hpp" @@ -225,6 +227,22 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, }); } +bool scripting::on_entity_spawn(const EntityDef& def, entityid_t eid) { + std::string name = def.name + ".spawn"; + return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { + lua::pushinteger(L, eid); + return 1; + }); +} + +bool scripting::on_entity_despawn(const EntityDef& def, entityid_t eid) { + std::string name = def.name + ".despawn"; + return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { + lua::pushinteger(L, eid); + return 1; + }); +} + void scripting::on_ui_open( UiDocument* layout, std::vector args @@ -308,6 +326,14 @@ void scripting::load_item_script(const scriptenv& senv, const std::string& prefi funcsset.on_block_break_by = register_event(env, "on_block_break_by", prefix+".blockbreakby"); } +void scripting::load_entity_script(const scriptenv& senv, const std::string& prefix, const fs::path& file, entity_funcs_set& funcsset) { + int env = *senv; + load_script(env, "entity", file); + funcsset.init = register_event(env, "init", prefix+".init"); + funcsset.on_spawn = register_event(env, "on_spawn", prefix+".spawn"); + funcsset.on_despawn = register_event(env, "on_despawn", prefix+".despawn"); +} + void scripting::load_world_script(const scriptenv& senv, const std::string& prefix, const fs::path& file) { int env = *senv; load_script(env, "world", file); diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 3082420c..6ad140c8 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -27,9 +27,12 @@ class Inventory; class UiDocument; struct block_funcs_set; struct item_funcs_set; +struct entity_funcs_set; struct uidocscript; class BlocksController; class LevelController; +class Entity; +struct EntityDef; namespace scripting { extern Engine* engine; @@ -73,6 +76,10 @@ namespace scripting { /// @return true if prevents default action bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); + bool on_entity_spawn(const EntityDef& def, entityid_t eid); + + bool on_entity_despawn(const EntityDef& def, entityid_t eid); + /// @brief Called on UI view show void on_ui_open( UiDocument* layout, @@ -89,14 +96,28 @@ namespace scripting { /// @param prefix pack id /// @param file item script file /// @param funcsset block callbacks set - void load_block_script(const scriptenv& env, const std::string& prefix, const fs::path& file, block_funcs_set& funcsset); + void load_block_script( + const scriptenv& env, + const std::string& prefix, + const fs::path& file, + block_funcs_set& funcsset); /// @brief Load script associated with an Item /// @param env environment /// @param prefix pack id /// @param file item script file /// @param funcsset item callbacks set - void load_item_script(const scriptenv& env, const std::string& prefix, const fs::path& file, item_funcs_set& funcsset); + void load_item_script( + const scriptenv& env, + const std::string& prefix, + const fs::path& file, + item_funcs_set& funcsset); + + void load_entity_script( + const scriptenv& env, + const std::string& prefix, + const fs::path& file, + entity_funcs_set& funcsset); /// @brief Load package-specific world script /// @param env environment diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 291ac1fd..a6915b67 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -9,6 +9,7 @@ #include "../graphics/core/Model.hpp" #include "../maths/FrustumCulling.hpp" #include "../objects/EntityDef.hpp" +#include "../logic/scripting/scripting.hpp" #include @@ -19,6 +20,12 @@ void Transform::refresh() { combined = combined * glm::mat4(rot); } +void Entity::destroy() { + if (isValid()){ + entities.despawn(id); + } +} + Entities::Entities(Level* level) : level(level) { } @@ -26,13 +33,23 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { auto entity = registry.create(); glm::vec3 size(1); auto id = nextID++; - registry.emplace(entity, static_cast(id)); + registry.emplace(entity, static_cast(id), def); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); registry.emplace(entity, true, Hitbox {pos, def.hitbox}); entities[id] = entity; + if (def.rt.funcsset.on_spawn) { + scripting::on_entity_spawn(def, id); + } return id; } +void Entities::despawn(entityid_t id) { + if (auto entity = get(id)) { + scripting::on_entity_despawn(entity->getDef(), id); + registry.destroy(get(id)->getHandler()); + } +} + void Entities::clean() { for (auto it = entities.begin(); it != entities.end();) { if (registry.valid(it->second)) { @@ -60,7 +77,7 @@ void Entities::updatePhysics(float delta){ 1.0f, true ); - hitbox.linear_damping = hitbox.grounded * 12; + hitbox.linearDamping = hitbox.grounded * 12; transform.pos = hitbox.position; //transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); if (hitbox.grounded) { diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index c4845e00..ed4427cb 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -9,8 +9,11 @@ #include #include +struct EntityDef; + struct EntityId { entityid_t uid; + const EntityDef& def; }; struct Transform { @@ -33,15 +36,16 @@ class LineBatch; class ModelBatch; class Frustum; class Rig; -struct EntityDef; +class Entities; class Entity { + Entities& entities; entityid_t id; entt::registry& registry; const entt::entity entity; public: - Entity(entityid_t id, entt::registry& registry, const entt::entity entity) - : id(id), registry(registry), entity(entity) {} + Entity(Entities& entities, entityid_t id, entt::registry& registry, const entt::entity entity) + : entities(entities), id(id), registry(registry), entity(entity) {} entityid_t getID() const { return id; @@ -51,6 +55,10 @@ public: return registry.valid(entity); } + const EntityDef& getDef() const { + return registry.get(entity).def; + } + Transform& getTransform() const { return registry.get(entity); } @@ -63,9 +71,11 @@ public: return registry.get(entity).uid; } - void destroy() { - registry.destroy(entity); + entt::entity getHandler() const { + return entity; } + + void destroy(); }; class Entities { @@ -86,11 +96,13 @@ public: std::optional get(entityid_t id) { const auto& found = entities.find(id); if (found != entities.end() && registry.valid(found->second)) { - return Entity(id, registry, found->second); + return Entity(*this, id, registry, found->second); } return std::nullopt; } + void despawn(entityid_t id); + inline size_t size() const { return entities.size(); } diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index e001bdbe..b5dbdc80 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -6,6 +6,12 @@ #include "../typedefs.hpp" +struct entity_funcs_set { + bool init : 1; + bool on_spawn : 1; + bool on_despawn : 1; +}; + struct EntityDef { /// @brief Entity string id (with prefix included) std::string const name; @@ -15,6 +21,7 @@ struct EntityDef { struct { entityid_t id; + entity_funcs_set funcsset; } rt; EntityDef(const std::string& name) : name(name) {} diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index fe81a5c7..7d295819 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -110,9 +110,9 @@ void Player::updateInput( noclip = !noclip; } - hitbox->linear_damping = PLAYER_GROUND_DAMPING; + hitbox->linearDamping = PLAYER_GROUND_DAMPING; if (flight){ - hitbox->linear_damping = PLAYER_AIR_DAMPING; + hitbox->linearDamping = PLAYER_AIR_DAMPING; hitbox->velocity.y *= 1.0f - delta * 9; if (input.jump){ hitbox->velocity.y += speed * delta * 9; @@ -122,7 +122,7 @@ void Player::updateInput( } } if (!hitbox->grounded) { - hitbox->linear_damping = PLAYER_AIR_DAMPING; + hitbox->linearDamping = PLAYER_AIR_DAMPING; } input.noclip = false; diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index fdae39b5..4d8a10af 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -11,10 +11,10 @@ #include class Camera; -class Hitbox; class Inventory; class ContentLUT; class Level; +struct Hitbox; struct EngineSettings; struct PlayerInput { diff --git a/src/physics/Hitbox.cpp b/src/physics/Hitbox.cpp index df94d9f6..8cd127e4 100644 --- a/src/physics/Hitbox.cpp +++ b/src/physics/Hitbox.cpp @@ -4,5 +4,5 @@ Hitbox::Hitbox(glm::vec3 position, glm::vec3 halfsize) : position(position), halfsize(halfsize), velocity(0.0f,0.0f,0.0f), - linear_damping(0.1f) + linearDamping(0.1f) {} diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index a32b0ada..718a8a0d 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -3,12 +3,11 @@ #include -class Hitbox { -public: +struct Hitbox { glm::vec3 position; glm::vec3 halfsize; glm::vec3 velocity; - float linear_damping; + float linearDamping; bool grounded = false; Hitbox(glm::vec3 position, glm::vec3 halfsize); diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 28c82312..5e03a04f 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -22,7 +22,7 @@ void PhysicsSolver::step( bool collisions ) { float dt = delta / static_cast(substeps); - float linear_damping = hitbox->linear_damping; + float linearDamping = hitbox->linearDamping; float s = 2.0f/BLOCK_AABB_GRID; const glm::vec3& half = hitbox->halfsize; @@ -41,8 +41,8 @@ void PhysicsSolver::step( colisionCalc(chunks, hitbox, vel, pos, half, (prevGrounded && gravityScale > 0.0f) ? 0.5f : 0.0f); } - vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping); - vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping); + vel.x *= glm::max(0.0f, 1.0f - dt * linearDamping); + vel.z *= glm::max(0.0f, 1.0f - dt * linearDamping); pos += vel * dt + gravity * gravityScale * dt * dt * 0.5f; if (hitbox->grounded && pos.y < py) { diff --git a/src/physics/PhysicsSolver.hpp b/src/physics/PhysicsSolver.hpp index 6e940f99..a9807af4 100644 --- a/src/physics/PhysicsSolver.hpp +++ b/src/physics/PhysicsSolver.hpp @@ -7,8 +7,8 @@ #include class Block; -class Hitbox; class Chunks; +struct Hitbox; class PhysicsSolver { glm::vec3 gravity; From e0e5faa4a8795e8628daac4ad54b298d89996cd5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 28 Jun 2024 12:47:45 +0300 Subject: [PATCH 025/178] add entity event: on_grounded --- res/content/base/scripts/drop.lua | 4 ++++ res/content/base/scripts/hud.lua | 4 +++- src/logic/scripting/scripting.cpp | 9 +++++++++ src/logic/scripting/scripting.hpp | 2 +- src/objects/Entities.cpp | 9 +++++---- src/objects/Entities.hpp | 1 + src/objects/EntityDef.hpp | 1 + 7 files changed, 24 insertions(+), 6 deletions(-) diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua index 9a691298..155e401b 100644 --- a/res/content/base/scripts/drop.lua +++ b/res/content/base/scripts/drop.lua @@ -5,3 +5,7 @@ end function on_despawn(eid) print("despawn", eid) end + +function on_grounded(eid) + Transform.set_rot(eid, mat4.rotate({0, 1, 0}, math.random()*360)) +end diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 710a8e5e..94103056 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -9,6 +9,8 @@ function on_hud_open() local eid = entity.spawn("base:drop", ppos) local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) Rigidbody.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) - Transform.set_rot(eid, mat4.rotate({0, 1, 0}, math.random() * 360)) + Transform.set_rot(eid, + mat4.rotate(mat4.rotate(mat4.rotate({0, 1, 0}, math.random() * 360), + {1, 0, 0}, math.random() * 360), {0, 0, 1}, math.random() * 360)) end) end diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 8d017d5b..085c7ac2 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -243,6 +243,14 @@ bool scripting::on_entity_despawn(const EntityDef& def, entityid_t eid) { }); } +bool scripting::on_entity_grounded(const EntityDef& def, entityid_t eid) { + std::string name = def.name + ".grounded"; + return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { + lua::pushinteger(L, eid); + return 1; + }); +} + void scripting::on_ui_open( UiDocument* layout, std::vector args @@ -332,6 +340,7 @@ void scripting::load_entity_script(const scriptenv& senv, const std::string& pre funcsset.init = register_event(env, "init", prefix+".init"); funcsset.on_spawn = register_event(env, "on_spawn", prefix+".spawn"); funcsset.on_despawn = register_event(env, "on_despawn", prefix+".despawn"); + funcsset.on_grounded = register_event(env, "on_grounded", prefix+".grounded"); } void scripting::load_world_script(const scriptenv& senv, const std::string& prefix, const fs::path& file) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 6ad140c8..7bbd59d1 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -77,8 +77,8 @@ namespace scripting { bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); bool on_entity_spawn(const EntityDef& def, entityid_t eid); - bool on_entity_despawn(const EntityDef& def, entityid_t eid); + bool on_entity_grounded(const EntityDef& def, entityid_t eid); /// @brief Called on UI view show void on_ui_open( diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index a6915b67..1fed9c82 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -61,13 +61,14 @@ void Entities::clean() { } void Entities::updatePhysics(float delta){ - auto view = registry.view(); + auto view = registry.view(); auto physics = level->physics.get(); - for (auto [entity, transform, rigidbody] : view.each()) { + for (auto [entity, eid, transform, rigidbody] : view.each()) { if (!rigidbody.enabled) { continue; } auto& hitbox = rigidbody.hitbox; + bool grounded = hitbox.grounded; physics->step( level->chunks.get(), &hitbox, @@ -80,8 +81,8 @@ void Entities::updatePhysics(float delta){ hitbox.linearDamping = hitbox.grounded * 12; transform.pos = hitbox.position; //transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); - if (hitbox.grounded) { - //hitbox.velocity.y = 10; + if (hitbox.grounded && !grounded) { + scripting::on_entity_grounded(eid.def, eid.uid); } } } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index ed4427cb..79df3e49 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -85,6 +85,7 @@ class Entities { entityid_t nextID = 1; public: Entities(Level* level); + void clean(); void updatePhysics(float delta); diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index b5dbdc80..c481e4ef 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -10,6 +10,7 @@ struct entity_funcs_set { bool init : 1; bool on_spawn : 1; bool on_despawn : 1; + bool on_grounded : 1; }; struct EntityDef { From c54be7b2b155f95756ac85c8be97fe27a288b8b3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 28 Jun 2024 18:57:40 +0300 Subject: [PATCH 026/178] add standard components test --- res/content/base/scripts/drop.lua | 3 ++- res/content/base/scripts/hud.lua | 4 +-- res/modules/internal/stdcomp.lua | 35 ++++++++++++++++++++++++++ res/scripts/stdlib.lua | 2 ++ src/logic/scripting/lua/lua_engine.cpp | 4 +-- src/logic/scripting/scripting.cpp | 9 +++---- 6 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 res/modules/internal/stdcomp.lua diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua index 155e401b..d059d07c 100644 --- a/res/content/base/scripts/drop.lua +++ b/res/content/base/scripts/drop.lua @@ -7,5 +7,6 @@ function on_despawn(eid) end function on_grounded(eid) - Transform.set_rot(eid, mat4.rotate({0, 1, 0}, math.random()*360)) + local entity = stdcomp.new_Entity(eid) -- test + entity.transform:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) end diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 94103056..069ae7de 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -8,8 +8,8 @@ function on_hud_open() local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) local eid = entity.spawn("base:drop", ppos) local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) - Rigidbody.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) - Transform.set_rot(eid, + __rigidbody.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) + __transform.set_rot(eid, mat4.rotate(mat4.rotate(mat4.rotate({0, 1, 0}, math.random() * 360), {1, 0, 0}, math.random() * 360), {0, 0, 1}, math.random() * 360)) end) diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua new file mode 100644 index 00000000..d526c65f --- /dev/null +++ b/res/modules/internal/stdcomp.lua @@ -0,0 +1,35 @@ +-- Standard components OOP wrappers (__index tables of metatables) + +local Transform = {__index={ + get_pos=function(self) return __transform.get_pos(self.eid) end, + set_pos=function(self, v) return __transform.set_pos(self.eid, v) end, + get_rot=function(self) return __transform.get_rot(self.eid) end, + set_rot=function(self, m) return __transform.set_rot(self.eid, m) end, +}} + +function new_Transform(eid) + return setmetatable({eid=eid}, Transform) +end + +local Rigidbody = {__index={ + is_enabled=function(self) return __rigidbody.is_enabled(self.eid) end, + set_enabled=function(self, f) return __rigidbody.set_enabled(self.eid, f) end, + get_vel=function(self) return __rigidbody.get_vel(self.eid) end, + set_vel=function(self, v) return __rigidbody.set_vel(self.eid, v) end, + get_size=function(self) return __rigidbody.get_size(self.eid) end, +}} + +function new_Rigidbody(eid) + return setmetatable({eid=eid}, Rigidbody) +end + +-- Entity class + +local Entity = {__index={}} + +return {new_Entity = function(eid) + local entity = setmetatable({eid=eid}, Entity) + entity.transform = new_Transform(eid) + entity.rigidbody = new_Rigidbody(eid) + return entity +end} diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 1873dd3e..eb0b08c4 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -303,6 +303,8 @@ function file.readlines(path) return lines end +stdcomp = require "core:internal/stdcomp" + -- Deprecated functions block_index = block.index block_name = block.name diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index 3339204d..0ca13127 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -49,8 +49,8 @@ static void create_libs(lua::State* L) { openlib(L, "world", worldlib); // components - openlib(L, "Rigidbody", rigidbodylib); - openlib(L, "Transform", transformlib); + openlib(L, "__rigidbody", rigidbodylib); + openlib(L, "__transform", transformlib); addfunc(L, "print", lua::wrap); } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 085c7ac2..126fdb5b 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -230,24 +230,21 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, bool scripting::on_entity_spawn(const EntityDef& def, entityid_t eid) { std::string name = def.name + ".spawn"; return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { - lua::pushinteger(L, eid); - return 1; + return lua::pushinteger(L, eid); }); } bool scripting::on_entity_despawn(const EntityDef& def, entityid_t eid) { std::string name = def.name + ".despawn"; return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { - lua::pushinteger(L, eid); - return 1; + return lua::pushinteger(L, eid); }); } bool scripting::on_entity_grounded(const EntityDef& def, entityid_t eid) { std::string name = def.name + ".grounded"; return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { - lua::pushinteger(L, eid); - return 1; + return lua::pushinteger(L, eid); }); } From fc3994446a2a21875bb5a58b0da0c8866da50ba8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 29 Jun 2024 21:01:30 +0300 Subject: [PATCH 027/178] update entity script semantics --- res/content/base/scripts/drop.lua | 11 +-- res/modules/internal/stdcomp.lua | 28 +++++-- src/content/ContentLoader.cpp | 2 +- src/logic/scripting/lua/lua_engine.cpp | 3 + src/logic/scripting/lua/lua_util.cpp | 8 +- src/logic/scripting/lua/lua_util.hpp | 53 +++++++++++- src/logic/scripting/scripting.cpp | 107 +++++++++++++++++++------ src/logic/scripting/scripting.hpp | 11 ++- src/objects/Entities.cpp | 14 ++-- src/objects/Entities.hpp | 15 ++++ src/objects/EntityDef.hpp | 10 +-- 11 files changed, 193 insertions(+), 69 deletions(-) diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua index d059d07c..4b09fc3b 100644 --- a/res/content/base/scripts/drop.lua +++ b/res/content/base/scripts/drop.lua @@ -1,12 +1,7 @@ -function on_spawn(eid) - print("spawn", eid) +function on_despawn() + print("despawn") end -function on_despawn(eid) - print("despawn", eid) -end - -function on_grounded(eid) - local entity = stdcomp.new_Entity(eid) -- test +function on_grounded() entity.transform:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index d526c65f..fa1fc020 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -25,11 +25,25 @@ end -- Entity class -local Entity = {__index={}} +local Entity = {__index={ + despawn=function(self) return entity.despawn(self.eid) end, +}} -return {new_Entity = function(eid) - local entity = setmetatable({eid=eid}, Entity) - entity.transform = new_Transform(eid) - entity.rigidbody = new_Rigidbody(eid) - return entity -end} +local entities = {} + +return { + new_Entity = function(eid) + local entity = setmetatable({eid=eid}, Entity) + entity.transform = new_Transform(eid) + entity.rigidbody = new_Rigidbody(eid) + entities[eid] = entity; + return entity + end, + remove_Entity = function(eid) + local entity = entities[eid] + if entity and entity.on_despawn then + entity.on_despawn() + end + entities[eid] = nil; + end +} diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index ad4f7072..530d218a 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -324,7 +324,7 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const st auto scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua"); if (fs::is_regular_file(scriptfile)) { - scripting::load_entity_script(env, full, scriptfile, def.rt.funcsset); + scripting::load_entity_script(env, def, scriptfile); } } diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index 0ca13127..fab28a7b 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -91,6 +91,9 @@ void lua::initialize() { createtable(L, 0, 0); setglobal(L, LAMBDAS_TABLE); + createtable(L, 0, 0); + setglobal(L, CHUNKS_TABLE); + newusertype(L, "bytearray"); } diff --git a/src/logic/scripting/lua/lua_util.cpp b/src/logic/scripting/lua/lua_util.cpp index 745889d2..ca2c3c00 100644 --- a/src/logic/scripting/lua/lua_util.cpp +++ b/src/logic/scripting/lua/lua_util.cpp @@ -118,15 +118,15 @@ int lua::call(State* L, int argc, int nresults) { if (lua_pcall(L, argc, nresults, 0)) { throw luaerror(tostring(L, -1)); } - return 1; + return nresults == -1 ? 1 : nresults; } -int lua::call_nothrow(State* L, int argc) { +int lua::call_nothrow(State* L, int argc, int nresults) { if (lua_pcall(L, argc, LUA_MULTRET, 0)) { log_error(tostring(L, -1)); return 0; } - return 1; + return nresults == -1 ? 1 : nresults; } void lua::dump_stack(State* L) { @@ -198,7 +198,7 @@ scripting::common_func lua::create_lambda(State* L) { }; } -int lua::createEnvironment(State* L, int parent) { +int lua::create_environment(State* L, int parent) { int id = nextEnvironment++; // local env = {} diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index 9a9665a0..ed0b1cde 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -8,8 +8,10 @@ #include #include +// NOTE: const std::string& used instead of string_view because c_str() needed namespace lua { - inline std::string LAMBDAS_TABLE = "$L"; + inline std::string LAMBDAS_TABLE = "$L"; // lambdas storage + inline std::string CHUNKS_TABLE = "$C"; // precompiled lua chunks extern std::unordered_map usertypeNames; int userdata_destructor(lua::State* L); @@ -79,6 +81,14 @@ namespace lua { return true; } + inline int requireglobal(lua::State* L, const std::string& name) { + if (getglobal(L, name)) { + return 1; + } else { + throw std::runtime_error("global name "+name+" not found"); + } + } + inline bool hasglobal(lua::State* L, const std::string& name) { lua_getglobal(L, name.c_str()); if (isnil(L, -1)) { @@ -443,6 +453,16 @@ namespace lua { return true; } + inline bool hasfield(lua::State* L, const std::string& name, int idx=-1) { + lua_getfield(L, idx, name.c_str()); + if (isnil(L, -1)) { + pop(L); + return false; + } + pop(L); + return true; + } + inline const char* require_string(lua::State* L, int idx) { if (!isstring(L, idx)) { throw luaerror("string expected at "+std::to_string(idx)); @@ -471,6 +491,10 @@ namespace lua { setglobal(L, name); } + inline int setfenv(lua::State* L, int idx=-2) { + return lua_setfenv(L, idx); + } + inline void loadbuffer(lua::State* L, int env, const std::string& src, const std::string& file) { if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) { throw luaerror(tostring(L, -1)); @@ -480,8 +504,31 @@ namespace lua { } } + inline void store_in(lua::State* L, const std::string& tableName, const std::string& name) { + if (getglobal(L, tableName)) { + pushvalue(L, -2); + setfield(L, name); + pop(L, 2); + } else { + throw std::runtime_error("table "+tableName+" not found"); + } + } + + inline int get_from(lua::State* L, const std::string& tableName, const std::string& name, bool required=false) { + if (getglobal(L, tableName)) { + if (getfield(L, name)) { + return 1; + } else if (required) { + throw std::runtime_error("table "+tableName+" has no member "+name); + } + return 0; + } else { + throw std::runtime_error("table "+tableName+" not found"); + } + } + int call(lua::State*, int argc, int nresults=-1); - int call_nothrow(lua::State*, int argc); + int call_nothrow(lua::State*, int argc, int nresults=1); inline int eval(lua::State* L, int env, const std::string& src, const std::string& file="") { auto srcText = "return "+src; @@ -503,7 +550,7 @@ namespace lua { } return 0; } - int createEnvironment(lua::State*, int parent); + int create_environment(lua::State*, int parent); void removeEnvironment(lua::State*, int id); void dump_stack(lua::State*); diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 126fdb5b..b33e1162 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -28,6 +28,8 @@ using namespace scripting; static debug::Logger logger("scripting"); +static inline const std::string STDCOMP = "stdcomp"; + Engine* scripting::engine = nullptr; Level* scripting::level = nullptr; const Content* scripting::content = nullptr; @@ -51,13 +53,15 @@ void scripting::initialize(Engine* engine) { load_script(fs::path("stdcmd.lua")); } +[[nodiscard]] scriptenv scripting::get_root_environment() { return std::make_shared(0); } +[[nodiscard]] scriptenv scripting::create_pack_environment(const ContentPack& pack) { auto L = lua::get_main_thread(); - int id = lua::createEnvironment(L, 0); + int id = lua::create_environment(L, 0); lua::pushenv(L, id); lua::pushvalue(L, -1); lua::setfield(L, "PACK_ENV"); @@ -70,9 +74,10 @@ scriptenv scripting::create_pack_environment(const ContentPack& pack) { }); } +[[nodiscard]] scriptenv scripting::create_doc_environment(const scriptenv& parent, const std::string& name) { auto L = lua::get_main_thread(); - int id = lua::createEnvironment(L, *parent); + int id = lua::create_environment(L, *parent); lua::pushenv(L, id); lua::pushvalue(L, -1); lua::setfield(L, "DOC_ENV"); @@ -95,6 +100,29 @@ scriptenv scripting::create_doc_environment(const scriptenv& parent, const std:: }); } +[[nodiscard]] +static scriptenv create_entity_environment(const scriptenv& parent, int entityIdx) { + auto L = lua::get_main_thread(); + int id = lua::create_environment(L, *parent); + + lua::pushvalue(L, entityIdx); + + lua::pushenv(L, id); + + lua::pushvalue(L, -1); + lua::setfield(L, "this"); + + lua::pushvalue(L, -2); + lua::setfield(L, "entity"); + + lua::pop(L, 2); + + return std::shared_ptr(new int(id), [=](int* id) { + lua::removeEnvironment(L, *id); + delete id; + }); +} + void scripting::process_post_runnables() { auto L = lua::get_main_thread(); if (lua::getglobal(L, "__process_post_runnables")) { @@ -227,25 +255,57 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, }); } -bool scripting::on_entity_spawn(const EntityDef& def, entityid_t eid) { - std::string name = def.name + ".spawn"; - return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { - return lua::pushinteger(L, eid); - }); +scriptenv scripting::on_entity_spawn(const EntityDef& def, entityid_t eid, entity_funcs_set& funcsset) { + auto L = lua::get_main_thread(); + lua::requireglobal(L, STDCOMP); + if (lua::getfield(L, "new_Entity")) { + lua::pushinteger(L, eid); + lua::call(L, 1); + } + auto entityenv = create_entity_environment(get_root_environment(), -1); + lua::get_from(L, lua::CHUNKS_TABLE, def.scriptName, true); + lua::pushenv(L, *entityenv); + lua::setfenv(L); + lua::call_nothrow(L, 0, 0); + + lua::pushenv(L, *entityenv); + funcsset.on_grounded = lua::hasfield(L, "on_grounded"); + funcsset.on_despawn = lua::hasfield(L, "on_despawn"); + return entityenv; } -bool scripting::on_entity_despawn(const EntityDef& def, entityid_t eid) { - std::string name = def.name + ".despawn"; - return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { - return lua::pushinteger(L, eid); - }); +static bool process_entity_callback( + const scriptenv& env, + const std::string& name, + std::function args +) { + auto L = lua::get_main_thread(); + lua::pushenv(L, *env); + if (lua::getfield(L, name)) { + if (args) { + lua::call_nothrow(L, args(L), 0); + } else { + lua::call_nothrow(L, 0, 0); + } + } + lua::pop(L); + return true; } -bool scripting::on_entity_grounded(const EntityDef& def, entityid_t eid) { - std::string name = def.name + ".grounded"; - return lua::emit_event(lua::get_main_thread(), name, [eid] (auto L) { - return lua::pushinteger(L, eid); - }); +bool scripting::on_entity_despawn(const EntityDef& def, const Entity& entity) { + const auto& script = entity.getScripting(); + if (script.funcsset.on_despawn) { + return process_entity_callback(script.env, "on_despawn", nullptr); + } + return true; +} + +bool scripting::on_entity_grounded(const EntityDef& def, const Entity& entity) { + const auto& script = entity.getScripting(); + if (script.funcsset.on_despawn) { + return process_entity_callback(script.env, "on_grounded", nullptr); + } + return true; } void scripting::on_ui_open( @@ -331,13 +391,12 @@ void scripting::load_item_script(const scriptenv& senv, const std::string& prefi funcsset.on_block_break_by = register_event(env, "on_block_break_by", prefix+".blockbreakby"); } -void scripting::load_entity_script(const scriptenv& senv, const std::string& prefix, const fs::path& file, entity_funcs_set& funcsset) { - int env = *senv; - load_script(env, "entity", file); - funcsset.init = register_event(env, "init", prefix+".init"); - funcsset.on_spawn = register_event(env, "on_spawn", prefix+".spawn"); - funcsset.on_despawn = register_event(env, "on_despawn", prefix+".despawn"); - funcsset.on_grounded = register_event(env, "on_grounded", prefix+".grounded"); +void scripting::load_entity_script(const scriptenv& penv, const EntityDef& def, const fs::path& file) { + auto L = lua::get_main_thread(); + std::string src = files::read_string(file); + logger.info() << "script (entity) " << file.u8string(); + lua::loadbuffer(L, 0, src, file); + lua::store_in(L, lua::CHUNKS_TABLE, def.scriptName); } void scripting::load_world_script(const scriptenv& senv, const std::string& prefix, const fs::path& file) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 7bbd59d1..75a36f14 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -76,9 +76,9 @@ namespace scripting { /// @return true if prevents default action bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); - bool on_entity_spawn(const EntityDef& def, entityid_t eid); - bool on_entity_despawn(const EntityDef& def, entityid_t eid); - bool on_entity_grounded(const EntityDef& def, entityid_t eid); + scriptenv on_entity_spawn(const EntityDef& def, entityid_t eid, entity_funcs_set&); + bool on_entity_despawn(const EntityDef& def, const Entity& entity); + bool on_entity_grounded(const EntityDef& def, const Entity& entity); /// @brief Called on UI view show void on_ui_open( @@ -115,9 +115,8 @@ namespace scripting { void load_entity_script( const scriptenv& env, - const std::string& prefix, - const fs::path& file, - entity_funcs_set& funcsset); + const EntityDef& def, + const fs::path& file); /// @brief Load package-specific world script /// @param env environment diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 1fed9c82..799d7f1a 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -36,16 +36,15 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { registry.emplace(entity, static_cast(id), def); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); registry.emplace(entity, true, Hitbox {pos, def.hitbox}); + auto& scripting = registry.emplace(entity, entity_funcs_set {}, nullptr); entities[id] = entity; - if (def.rt.funcsset.on_spawn) { - scripting::on_entity_spawn(def, id); - } + scripting.env = scripting::on_entity_spawn(def, id, scripting.funcsset); return id; } void Entities::despawn(entityid_t id) { if (auto entity = get(id)) { - scripting::on_entity_despawn(entity->getDef(), id); + scripting::on_entity_despawn(entity->getDef(), *entity); registry.destroy(get(id)->getHandler()); } } @@ -82,15 +81,16 @@ void Entities::updatePhysics(float delta){ transform.pos = hitbox.position; //transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); if (hitbox.grounded && !grounded) { - scripting::on_entity_grounded(eid.def, eid.uid); + scripting::on_entity_grounded(eid.def, *get(eid.uid)); } } } void Entities::renderDebug(LineBatch& batch) { batch.lineWidth(1.0f); - auto view = registry.view(); - for (auto [entity, transform, hitbox] : view.each()) { + auto view = registry.view(); + for (auto [entity, transform, rigidbody] : view.each()) { + const auto& hitbox = rigidbody.hitbox; batch.box(hitbox.position, hitbox.halfsize * 2.0f, glm::vec4(1.0f)); } } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 79df3e49..7cc49ab0 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -9,6 +9,12 @@ #include #include +struct entity_funcs_set { + bool init : 1; + bool on_despawn : 1; + bool on_grounded : 1; +}; + struct EntityDef; struct EntityId { @@ -30,6 +36,11 @@ struct Rigidbody { Hitbox hitbox; }; +struct Scripting { + entity_funcs_set funcsset; + scriptenv env; +}; + class Level; class Assets; class LineBatch; @@ -67,6 +78,10 @@ public: return registry.get(entity); } + Scripting& getScripting() const { + return registry.get(entity); + } + entityid_t getUID() const { return registry.get(entity).uid; } diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index c481e4ef..a409de09 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -6,13 +6,6 @@ #include "../typedefs.hpp" -struct entity_funcs_set { - bool init : 1; - bool on_spawn : 1; - bool on_despawn : 1; - bool on_grounded : 1; -}; - struct EntityDef { /// @brief Entity string id (with prefix included) std::string const name; @@ -22,8 +15,7 @@ struct EntityDef { struct { entityid_t id; - entity_funcs_set funcsset; - } rt; + } rt {}; EntityDef(const std::string& name) : name(name) {} EntityDef(const EntityDef&) = delete; From d22948f45cda6ea7825a42f2b35ed14c2dc16b7b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 29 Jun 2024 21:10:23 +0300 Subject: [PATCH 028/178] update entity.spawn(...): now returns an Entity instead of id --- res/content/base/scripts/drop.lua | 1 + res/content/base/scripts/hud.lua | 8 ++++---- src/logic/scripting/lua/libentity.cpp | 4 ++-- src/logic/scripting/scripting.cpp | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua index 4b09fc3b..ae61f963 100644 --- a/res/content/base/scripts/drop.lua +++ b/res/content/base/scripts/drop.lua @@ -4,4 +4,5 @@ end function on_grounded() entity.transform:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) + entity:despawn() end diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 069ae7de..26083c49 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -6,11 +6,11 @@ function on_hud_open() local pid = hud.get_player() local pvel = {player.get_vel(pid)} local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) - local eid = entity.spawn("base:drop", ppos) local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) - __rigidbody.set_vel(eid, vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) - __transform.set_rot(eid, - mat4.rotate(mat4.rotate(mat4.rotate({0, 1, 0}, math.random() * 360), + + local drop = entity.spawn("base:drop", ppos) + drop.rigidbody:set_vel(vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) + drop.transform:set_rot(mat4.rotate(mat4.rotate(mat4.rotate({0, 1, 0}, math.random() * 360), {1, 0, 0}, math.random() * 360), {0, 0, 1}, math.random() * 360)) end) end diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 42cc01fb..326e4da7 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -31,8 +31,8 @@ static int l_spawn(lua::State* L) { auto defname = lua::tostring(L, 1); auto& def = content->entities.require(defname); auto pos = lua::tovec3(L, 2); - auto id = level->entities->spawn(def, pos); - return lua::pushinteger(L, id); + level->entities->spawn(def, pos); + return 1; } static int l_despawn(lua::State* L) { diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index b33e1162..2925a553 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -271,6 +271,7 @@ scriptenv scripting::on_entity_spawn(const EntityDef& def, entityid_t eid, entit lua::pushenv(L, *entityenv); funcsset.on_grounded = lua::hasfield(L, "on_grounded"); funcsset.on_despawn = lua::hasfield(L, "on_despawn"); + lua::pop(L, 2); return entityenv; } From f42cd9e567820f2bd4e83894e4f15dbf0b22d20c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 29 Jun 2024 21:20:12 +0300 Subject: [PATCH 029/178] fix entity removal --- res/content/base/scripts/drop.lua | 1 + res/modules/internal/stdcomp.lua | 4 ---- src/logic/scripting/scripting.cpp | 6 +++++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua index ae61f963..3740cc0e 100644 --- a/res/content/base/scripts/drop.lua +++ b/res/content/base/scripts/drop.lua @@ -4,5 +4,6 @@ end function on_grounded() entity.transform:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) + print(stdcomp) entity:despawn() end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index fa1fc020..3316bae4 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -40,10 +40,6 @@ return { return entity end, remove_Entity = function(eid) - local entity = entities[eid] - if entity and entity.on_despawn then - entity.on_despawn() - end entities[eid] = nil; end } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 2925a553..2aa6c48f 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -296,8 +296,12 @@ static bool process_entity_callback( bool scripting::on_entity_despawn(const EntityDef& def, const Entity& entity) { const auto& script = entity.getScripting(); if (script.funcsset.on_despawn) { - return process_entity_callback(script.env, "on_despawn", nullptr); + process_entity_callback(script.env, "on_despawn", nullptr); } + auto L = lua::get_main_thread(); + lua::get_from(L, "stdcomp", "remove_Entity", true); + lua::pushinteger(L, entity.getUID()); + lua::call(L, 1, 0); return true; } From bb1c0b4b441d444007ab20f6964312962b5a0f63 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 29 Jun 2024 21:21:41 +0300 Subject: [PATCH 030/178] fix msvc build --- src/logic/scripting/scripting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 2aa6c48f..fb4fc4ea 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -400,7 +400,7 @@ void scripting::load_entity_script(const scriptenv& penv, const EntityDef& def, auto L = lua::get_main_thread(); std::string src = files::read_string(file); logger.info() << "script (entity) " << file.u8string(); - lua::loadbuffer(L, 0, src, file); + lua::loadbuffer(L, 0, src, file.u8string()); lua::store_in(L, lua::CHUNKS_TABLE, def.scriptName); } From 982c8b132da6bb5dd8d11b387d3a275bfb1fdb16 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 29 Jun 2024 22:19:42 +0300 Subject: [PATCH 031/178] add on_update event --- res/content/base/scripts/drop.lua | 14 ++++++++------ res/modules/internal/stdcomp.lua | 17 ++++++++++++++++- src/logic/LevelController.cpp | 1 + src/logic/scripting/scripting.cpp | 13 ++++++++++--- src/logic/scripting/scripting.hpp | 1 + src/objects/Entities.cpp | 4 ++++ src/objects/Entities.hpp | 1 + 7 files changed, 41 insertions(+), 10 deletions(-) diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua index 3740cc0e..dbdace91 100644 --- a/res/content/base/scripts/drop.lua +++ b/res/content/base/scripts/drop.lua @@ -1,9 +1,11 @@ -function on_despawn() - print("despawn") -end - +inair = true function on_grounded() entity.transform:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) - print(stdcomp) - entity:despawn() + inair = false +end + +function on_update() + if inair then + entity.transform:set_rot(mat4.rotate(entity.transform:get_rot(), {0, 1, 0}, math.random()*32)) + end end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 3316bae4..1fd16e1b 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -40,6 +40,21 @@ return { return entity end, remove_Entity = function(eid) - entities[eid] = nil; + local entity = entities[eid] + if entity then + entity.env = nil + entities[eid] = nil; + end + end, + update = function() + for id,entity in pairs(entities) do + local callback = entity.env.on_update + if callback then + local result, err = pcall(callback) + if err then + print(err) + end + end + end end } diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index f42bc926..11c7533d 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -50,6 +50,7 @@ void LevelController::update(float delta, bool input, bool pause) { } blocks->update(delta); level->entities->updatePhysics(delta); + level->entities->update(); } } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index fb4fc4ea..cd6c407f 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -114,8 +114,9 @@ static scriptenv create_entity_environment(const scriptenv& parent, int entityId lua::pushvalue(L, -2); lua::setfield(L, "entity"); - - lua::pop(L, 2); + + lua::setfield(L, "env"); + lua::pop(L); return std::shared_ptr(new int(id), [=](int* id) { lua::removeEnvironment(L, *id); @@ -307,12 +308,18 @@ bool scripting::on_entity_despawn(const EntityDef& def, const Entity& entity) { bool scripting::on_entity_grounded(const EntityDef& def, const Entity& entity) { const auto& script = entity.getScripting(); - if (script.funcsset.on_despawn) { + if (script.funcsset.on_grounded) { return process_entity_callback(script.env, "on_grounded", nullptr); } return true; } +void scripting::on_entities_update() { + auto L = lua::get_main_thread(); + lua::get_from(L, STDCOMP, "update", true); + lua::call_nothrow(L, 0, 0); +} + void scripting::on_ui_open( UiDocument* layout, std::vector args diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 75a36f14..98b9b9a2 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -79,6 +79,7 @@ namespace scripting { scriptenv on_entity_spawn(const EntityDef& def, entityid_t eid, entity_funcs_set&); bool on_entity_despawn(const EntityDef& def, const Entity& entity); bool on_entity_grounded(const EntityDef& def, const Entity& entity); + void on_entities_update(); /// @brief Called on UI view show void on_ui_open( diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 799d7f1a..1d1fc214 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -86,6 +86,10 @@ void Entities::updatePhysics(float delta){ } } +void Entities::update() { + scripting::on_entities_update(); +} + void Entities::renderDebug(LineBatch& batch) { batch.lineWidth(1.0f); auto view = registry.view(); diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 7cc49ab0..52cdcbde 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -103,6 +103,7 @@ public: void clean(); void updatePhysics(float delta); + void update(); void renderDebug(LineBatch& batch); void render(Assets* assets, ModelBatch& batch, Frustum& frustum); From e08bfd071b34e7c31835422a7649c1f1191d205d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 29 Jun 2024 22:39:41 +0300 Subject: [PATCH 032/178] fix lua stack leak --- res/content/base/scripts/hud.lua | 9 ++++++++- src/frontend/debug_panel.cpp | 4 ++++ src/logic/scripting/scripting.cpp | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 26083c49..155a0a00 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -3,14 +3,21 @@ local DROP_INIT_VEL = {0, 3, 0} function on_hud_open() input.add_callback("player.drop", function () + for i=1,5 do local pid = hud.get_player() local pvel = {player.get_vel(pid)} local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) - local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) + local throw_force = vec3.mul(vec3.add(player.get_dir(pid), + { + math.random() - 0.5, + math.random() - 0.5, + math.random() - 0.5 + }), DROP_FORCE) local drop = entity.spawn("base:drop", ppos) drop.rigidbody:set_vel(vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) drop.transform:set_rot(mat4.rotate(mat4.rotate(mat4.rotate({0, 1, 0}, math.random() * 360), {1, 0, 0}, math.random() * 360), {0, 0, 1}, math.random() * 360)) + end end) end diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index 8af49f86..6960a6e9 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -10,6 +10,7 @@ #include "../graphics/render/WorldRenderer.hpp" #include "../logic/scripting/scripting.hpp" #include "../objects/Player.hpp" +#include "../objects/Entities.hpp" #include "../physics/Hitbox.hpp" #include "../util/stringutil.hpp" #include "../voxels/Block.hpp" @@ -83,6 +84,9 @@ std::shared_ptr create_debug_panel( return L"chunks: "+std::to_wstring(level->chunks->chunksCount)+ L" visible: "+std::to_wstring(level->chunks->visible); })); + panel->add(create_label([=]() { + return L"entities: "+std::to_wstring(level->entities->size()); + })); panel->add(create_label([=](){ const auto& vox = player->selection.vox; std::wstringstream stream; diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index cd6c407f..cc50014b 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -318,6 +318,7 @@ void scripting::on_entities_update() { auto L = lua::get_main_thread(); lua::get_from(L, STDCOMP, "update", true); lua::call_nothrow(L, 0, 0); + lua::pop(L); } void scripting::on_ui_open( From 3946119a676a82559161f417b175a20e374d7d21 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 30 Jun 2024 00:31:25 +0300 Subject: [PATCH 033/178] fix vecn.normalize --- src/logic/scripting/lua/libvecn.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logic/scripting/lua/libvecn.cpp b/src/logic/scripting/lua/libvecn.cpp index 80c5143e..9a1b4f9b 100644 --- a/src/logic/scripting/lua/libvecn.cpp +++ b/src/logic/scripting/lua/libvecn.cpp @@ -52,8 +52,8 @@ static int l_unaryop(lua::State* L) { lua::rawseti(L, i+1); } return 1; - case 3: - return lua::setvec(L, 3, vec); + case 2: + return lua::setvec(L, 2, vec); default: { throw std::runtime_error("invalid arguments number (1 or 2 expected)"); } From 50c714692af86e2d16015004f9c48dd223ad9fe4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 30 Jun 2024 00:32:02 +0300 Subject: [PATCH 034/178] add entity event: on_fall --- res/content/base/scripts/drop.lua | 22 +++++++++++++++++----- src/logic/scripting/scripting.cpp | 15 +++++++++++++-- src/logic/scripting/scripting.hpp | 3 ++- src/objects/Entities.cpp | 8 ++++++-- src/objects/Entities.hpp | 1 + 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua index dbdace91..b228ec59 100644 --- a/res/content/base/scripts/drop.lua +++ b/res/content/base/scripts/drop.lua @@ -1,11 +1,23 @@ inair = true -function on_grounded() + +function on_grounded(force) entity.transform:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) inair = false end -function on_update() - if inair then - entity.transform:set_rot(mat4.rotate(entity.transform:get_rot(), {0, 1, 0}, math.random()*32)) - end +function on_fall() + inair = true +end + +function on_update() + local tsf = entity.transform + local body = entity.rigidbody + if inair then + tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 1, 0}, math.random()*12)) + tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 0, 1}, math.random()*12)) + end + local dir = vec3.sub({player.get_pos(hud.get_player())}, tsf:get_pos()) + vec3.normalize(dir, dir) + vec3.mul(dir, time.delta()*50.0, dir) + --body:set_vel(vec3.add(rigidbody:get_vel(), dir)) end diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index cc50014b..720e2083 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -271,6 +271,7 @@ scriptenv scripting::on_entity_spawn(const EntityDef& def, entityid_t eid, entit lua::pushenv(L, *entityenv); funcsset.on_grounded = lua::hasfield(L, "on_grounded"); + funcsset.on_fall = lua::hasfield(L, "on_fall"); funcsset.on_despawn = lua::hasfield(L, "on_despawn"); lua::pop(L, 2); return entityenv; @@ -306,10 +307,20 @@ bool scripting::on_entity_despawn(const EntityDef& def, const Entity& entity) { return true; } -bool scripting::on_entity_grounded(const EntityDef& def, const Entity& entity) { +bool scripting::on_entity_grounded(const Entity& entity, float force) { const auto& script = entity.getScripting(); if (script.funcsset.on_grounded) { - return process_entity_callback(script.env, "on_grounded", nullptr); + return process_entity_callback(script.env, "on_grounded", [force](auto L){ + return lua::pushnumber(L, force); + }); + } + return true; +} + +bool scripting::on_entity_fall(const Entity& entity) { + const auto& script = entity.getScripting(); + if (script.funcsset.on_fall) { + return process_entity_callback(script.env, "on_fall", nullptr); } return true; } diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 98b9b9a2..a46d7500 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -78,7 +78,8 @@ namespace scripting { scriptenv on_entity_spawn(const EntityDef& def, entityid_t eid, entity_funcs_set&); bool on_entity_despawn(const EntityDef& def, const Entity& entity); - bool on_entity_grounded(const EntityDef& def, const Entity& entity); + bool on_entity_grounded(const Entity& entity, float force); + bool on_entity_fall(const Entity& entity); void on_entities_update(); /// @brief Called on UI view show diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 1d1fc214..52f914a6 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -67,6 +67,7 @@ void Entities::updatePhysics(float delta){ continue; } auto& hitbox = rigidbody.hitbox; + auto prevVel = hitbox.velocity; bool grounded = hitbox.grounded; physics->step( level->chunks.get(), @@ -77,11 +78,14 @@ void Entities::updatePhysics(float delta){ 1.0f, true ); - hitbox.linearDamping = hitbox.grounded * 12; + hitbox.linearDamping = hitbox.grounded * 24; transform.pos = hitbox.position; //transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); if (hitbox.grounded && !grounded) { - scripting::on_entity_grounded(eid.def, *get(eid.uid)); + scripting::on_entity_grounded(*get(eid.uid), glm::length(prevVel-hitbox.velocity)); + } + if (!hitbox.grounded && grounded) { + scripting::on_entity_fall(*get(eid.uid)); } } } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 52cdcbde..80bf7e27 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -13,6 +13,7 @@ struct entity_funcs_set { bool init : 1; bool on_despawn : 1; bool on_grounded : 1; + bool on_fall : 1; }; struct EntityDef; From 5769be8ec86b3cfe0bef4bd3f713cf070879f14d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 30 Jun 2024 16:25:08 +0300 Subject: [PATCH 035/178] add triggers --- res/content/base/scripts/components/drop.lua | 28 ++++++++ res/content/base/scripts/drop.lua | 23 ------- res/content/base/scripts/hud.lua | 8 +-- src/content/ContentLoader.cpp | 4 +- src/graphics/render/WorldRenderer.cpp | 2 +- src/logic/LevelController.cpp | 18 ++--- src/logic/scripting/scripting.cpp | 29 +++++++- src/logic/scripting/scripting.hpp | 4 +- src/maths/aabb.hpp | 43 +++++++++++- src/objects/Entities.cpp | 71 +++++++++++++++++--- src/objects/Entities.hpp | 11 ++- src/objects/Player.cpp | 3 +- src/physics/Hitbox.hpp | 16 +++++ src/physics/PhysicsSolver.cpp | 22 +++++- src/physics/PhysicsSolver.hpp | 21 ++++-- 15 files changed, 239 insertions(+), 64 deletions(-) create mode 100644 res/content/base/scripts/components/drop.lua delete mode 100644 res/content/base/scripts/drop.lua diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua new file mode 100644 index 00000000..a1ab5aa2 --- /dev/null +++ b/res/content/base/scripts/components/drop.lua @@ -0,0 +1,28 @@ +local tsf = entity.transform +local body = entity.rigidbody + +inair = true +ready = false + +function on_grounded(force) + tsf:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) + inair = false + ready = true +end + +function on_fall() + inair = true +end + +function on_trigger_enter(index, oid) + if ready then + entity:despawn() + end +end + +function on_update() + if inair then + tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 1, 0}, math.random()*12)) + tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 0, 1}, math.random()*12)) + end +end diff --git a/res/content/base/scripts/drop.lua b/res/content/base/scripts/drop.lua deleted file mode 100644 index b228ec59..00000000 --- a/res/content/base/scripts/drop.lua +++ /dev/null @@ -1,23 +0,0 @@ -inair = true - -function on_grounded(force) - entity.transform:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) - inair = false -end - -function on_fall() - inair = true -end - -function on_update() - local tsf = entity.transform - local body = entity.rigidbody - if inair then - tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 1, 0}, math.random()*12)) - tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 0, 1}, math.random()*12)) - end - local dir = vec3.sub({player.get_pos(hud.get_player())}, tsf:get_pos()) - vec3.normalize(dir, dir) - vec3.mul(dir, time.delta()*50.0, dir) - --body:set_vel(vec3.add(rigidbody:get_vel(), dir)) -end diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 155a0a00..78027e7f 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -3,15 +3,15 @@ local DROP_INIT_VEL = {0, 3, 0} function on_hud_open() input.add_callback("player.drop", function () - for i=1,5 do + for i=1,80 do local pid = hud.get_player() local pvel = {player.get_vel(pid)} local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) local throw_force = vec3.mul(vec3.add(player.get_dir(pid), { - math.random() - 0.5, - math.random() - 0.5, - math.random() - 0.5 + (math.random() - 0.5) * 5, + (math.random() - 0.5) * 5, + (math.random() - 0.5) * 5 }), DROP_FORCE) local drop = entity.spawn("base:drop", ppos) diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 530d218a..23d02953 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -322,9 +322,9 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const st auto configFile = folder/fs::path("entities/"+name+".json"); if (fs::exists(configFile)) loadEntity(def, full, configFile); - auto scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua"); + auto scriptfile = folder/fs::path("scripts/components/"+def.scriptName+".lua"); if (fs::is_regular_file(scriptfile)) { - scripting::load_entity_script(env, def, scriptfile); + scripting::load_entity_component(env, def, scriptfile); } } diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 5d1c639b..1e6dd39a 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -233,7 +233,7 @@ void WorldRenderer::renderLines(Camera* camera, Shader* linesShader) { renderBlockSelection(); } if (player->debug) { - level->entities->renderDebug(*lineBatch); + level->entities->renderDebug(*lineBatch, *frustumCulling); } lineBatch->render(); } diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index 11c7533d..20daeb00 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -30,15 +30,6 @@ void LevelController::update(float delta, bool input, bool pause) { settings.chunks.loadDistance.get() + settings.chunks.padding.get() * 2); chunks->update(settings.chunks.loadSpeed.get()); - player->update(delta, input, pause); - - // erease null pointers - level->objects.erase( - std::remove_if( - level->objects.begin(), level->objects.end(), - [](auto obj) { return obj == nullptr; }), - level->objects.end() - ); level->entities->clean(); if (!pause) { @@ -52,6 +43,15 @@ void LevelController::update(float delta, bool input, bool pause) { level->entities->updatePhysics(delta); level->entities->update(); } + player->update(delta, input, pause); + + // erease null pointers + level->objects.erase( + std::remove_if( + level->objects.begin(), level->objects.end(), + [](auto obj) { return obj == nullptr; }), + level->objects.end() + ); } void LevelController::saveWorld() { diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 720e2083..8d9e6a4c 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -273,6 +273,8 @@ scriptenv scripting::on_entity_spawn(const EntityDef& def, entityid_t eid, entit funcsset.on_grounded = lua::hasfield(L, "on_grounded"); funcsset.on_fall = lua::hasfield(L, "on_fall"); funcsset.on_despawn = lua::hasfield(L, "on_despawn"); + funcsset.on_trigger_enter = lua::hasfield(L, "on_trigger_enter"); + funcsset.on_trigger_exit = lua::hasfield(L, "on_trigger_exit"); lua::pop(L, 2); return entityenv; } @@ -325,6 +327,29 @@ bool scripting::on_entity_fall(const Entity& entity) { return true; } +void scripting::on_trigger_enter(const Entity& entity, size_t index, entityid_t oid) { + const auto& script = entity.getScripting(); + if (script.funcsset.on_trigger_enter) { + process_entity_callback(script.env, "on_trigger_enter", [index, oid](auto L) { + lua::pushinteger(L, index); + lua::pushinteger(L, oid); + return 2; + }); + } +} + + +void scripting::on_trigger_exit(const Entity& entity, size_t index, entityid_t oid) { + const auto& script = entity.getScripting(); + if (script.funcsset.on_trigger_exit) { + process_entity_callback(script.env, "on_trigger_exit", [index, oid](auto L) { + lua::pushinteger(L, index); + lua::pushinteger(L, oid); + return 2; + }); + } +} + void scripting::on_entities_update() { auto L = lua::get_main_thread(); lua::get_from(L, STDCOMP, "update", true); @@ -415,10 +440,10 @@ void scripting::load_item_script(const scriptenv& senv, const std::string& prefi funcsset.on_block_break_by = register_event(env, "on_block_break_by", prefix+".blockbreakby"); } -void scripting::load_entity_script(const scriptenv& penv, const EntityDef& def, const fs::path& file) { +void scripting::load_entity_component(const scriptenv& penv, const EntityDef& def, const fs::path& file) { auto L = lua::get_main_thread(); std::string src = files::read_string(file); - logger.info() << "script (entity) " << file.u8string(); + logger.info() << "script (component) " << file.u8string(); lua::loadbuffer(L, 0, src, file.u8string()); lua::store_in(L, lua::CHUNKS_TABLE, def.scriptName); } diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index a46d7500..f6d1ccdb 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -81,6 +81,8 @@ namespace scripting { bool on_entity_grounded(const Entity& entity, float force); bool on_entity_fall(const Entity& entity); void on_entities_update(); + void on_trigger_enter(const Entity& entity, size_t index, entityid_t oid); + void on_trigger_exit(const Entity& entity, size_t index, entityid_t oid); /// @brief Called on UI view show void on_ui_open( @@ -115,7 +117,7 @@ namespace scripting { const fs::path& file, item_funcs_set& funcsset); - void load_entity_script( + void load_entity_component( const scriptenv& env, const EntityDef& def, const fs::path& file); diff --git a/src/maths/aabb.hpp b/src/maths/aabb.hpp index 40f57ccc..7859ef65 100644 --- a/src/maths/aabb.hpp +++ b/src/maths/aabb.hpp @@ -6,13 +6,16 @@ /// @brief Axis Aligned Bounding Box struct AABB { glm::vec3 a {0.0f}; - glm::vec3 b {1.0f}; + glm::vec3 b {1.0f, 1.0f, 1.0f}; AABB() {} AABB(glm::vec3 size) : a(0.0f), b(size) { } + AABB(glm::vec3 pos, glm::vec3 size) : a(pos), b(size) { + } + /// @brief Get AABB point with minimal x,y,z inline glm::vec3 min() const { return glm::min(a, b); @@ -59,6 +62,44 @@ struct AABB { return !(pos.x < p.x || pos.y < p.y || pos.z < p.z || pos.x >= p.x+s.x || pos.y >= p.y+s.y || pos.z >= p.z+s.z); } + + void fix() { + auto beg = min(); + auto end = max(); + a = beg; + b = end; + } + + inline void addPoint(glm::vec3 p) { + a = glm::min(a, p); + b = glm::max(b, p); + } + + /// TODO: optimize + void transform(const glm::mat4& matrix) { + auto pa = a; + auto pb = b; + a = matrix * glm::vec4(a, 1.0f); + b = matrix * glm::vec4(b, 1.0f); + fix(); + addPoint(matrix * glm::vec4(pb.x, pa.y, pa.z, 1.0f)); + addPoint(matrix * glm::vec4(pb.x, pb.y, pa.z, 1.0f)); + addPoint(matrix * glm::vec4(pb.x, pb.y, pb.z, 1.0f)); + addPoint(matrix * glm::vec4(pa.x, pb.y, pa.z, 1.0f)); + addPoint(matrix * glm::vec4(pa.x, pa.y, pb.z, 1.0f)); + addPoint(matrix * glm::vec4(pb.x, pa.y, pb.z, 1.0f)); + } + + inline bool intersect(const AABB& aabb) { + return ( + a.x <= aabb.b.x && + b.x >= aabb.a.x && + a.y <= aabb.b.y && + b.y >= aabb.a.y && + a.z <= aabb.b.z && + b.z >= aabb.a.z + ); + } }; #endif // MATHS_AABB_HPP_ diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 52f914a6..95ace4a6 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -35,7 +35,22 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { auto id = nextID++; registry.emplace(entity, static_cast(id), def); registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); - registry.emplace(entity, true, Hitbox {pos, def.hitbox}); + registry.emplace(entity, true, Hitbox {pos, def.hitbox}, std::vector{ + {true, id, AABB {glm::vec3{-1.0f, -1.0f, -1.0f}, glm::vec3{1.0f, 1.0f, 1.0f}}, {}, {}, {}, + [=](auto entityid, auto index, auto otherid) { + if (auto entity = get(entityid)) { + if (entity->isValid()) { + scripting::on_trigger_enter(*entity, index, otherid); + } + } + }, [=](auto entityid, auto index, auto otherid) { + if (auto entity = get(entityid)) { + if (entity->isValid()) { + scripting::on_trigger_exit(*entity, index, otherid); + } + } + }} + }); auto& scripting = registry.emplace(entity, entity_funcs_set {}, nullptr); entities[id] = entity; scripting.env = scripting::on_entity_spawn(def, id, scripting.funcsset); @@ -44,24 +59,50 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { void Entities::despawn(entityid_t id) { if (auto entity = get(id)) { - scripting::on_entity_despawn(entity->getDef(), *entity); - registry.destroy(get(id)->getHandler()); + auto& eid = entity->getID(); + if (!eid.destroyFlag) { + eid.destroyFlag = true; + scripting::on_entity_despawn(entity->getDef(), *entity); + } } } void Entities::clean() { for (auto it = entities.begin(); it != entities.end();) { - if (registry.valid(it->second)) { + if (!registry.get(it->second).destroyFlag) { ++it; } else { + registry.destroy(it->second); it = entities.erase(it); } } } - +#include "../util/timeutil.hpp" void Entities::updatePhysics(float delta){ auto view = registry.view(); auto physics = level->physics.get(); + { + std::vector triggers; + for (auto [entity, eid, transform, rigidbody] : view.each()) { + if (!rigidbody.enabled) { + continue; + } + for (size_t i = 0; i < rigidbody.triggers.size(); i++) { + auto& trigger = rigidbody.triggers[i]; + for (auto oid : trigger.prevEntered) { + if (trigger.nextEntered.find(oid) == trigger.nextEntered.end()) { + trigger.exitCallback(trigger.entity, i, oid); + } + } + trigger.prevEntered = trigger.nextEntered; + trigger.nextEntered.clear(); + trigger.calculated = trigger.aabb; + trigger.calculated.transform(transform.combined); + triggers.push_back(&trigger); + } + } + physics->setTriggers(std::move(triggers)); + } for (auto [entity, eid, transform, rigidbody] : view.each()) { if (!rigidbody.enabled) { continue; @@ -76,11 +117,11 @@ void Entities::updatePhysics(float delta){ 10, false, 1.0f, - true + true, + eid.uid ); hitbox.linearDamping = hitbox.grounded * 24; transform.pos = hitbox.position; - //transform.rot = glm::rotate(glm::mat4(transform.rot), delta, glm::vec3(0, 1, 0)); if (hitbox.grounded && !grounded) { scripting::on_entity_grounded(*get(eid.uid), glm::length(prevVel-hitbox.velocity)); } @@ -92,14 +133,27 @@ void Entities::updatePhysics(float delta){ void Entities::update() { scripting::on_entities_update(); + auto view = registry.view(); + for (auto [entity, transform] : view.each()) { + transform.refresh(); + } } -void Entities::renderDebug(LineBatch& batch) { +void Entities::renderDebug(LineBatch& batch, Frustum& frustum) { batch.lineWidth(1.0f); auto view = registry.view(); for (auto [entity, transform, rigidbody] : view.each()) { const auto& hitbox = rigidbody.hitbox; + const auto& pos = transform.pos; + const auto& size = transform.size; + if (!frustum.isBoxVisible(pos-size, pos+size)) { + continue; + } batch.box(hitbox.position, hitbox.halfsize * 2.0f, glm::vec4(1.0f)); + + for (auto& trigger : rigidbody.triggers) { + batch.box(trigger.calculated.center(), trigger.calculated.size(), glm::vec4(1.0f, 1.0f, 0.0f, 1.0f)); + } } } @@ -110,7 +164,6 @@ void Entities::render(Assets* assets, ModelBatch& batch, Frustum& frustum) { const auto& pos = transform.pos; const auto& size = transform.size; if (frustum.isBoxVisible(pos-size, pos+size)) { - transform.refresh(); batch.pushMatrix(transform.combined); batch.draw(model); batch.popMatrix(); diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 80bf7e27..7403c645 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -4,6 +4,7 @@ #include "../typedefs.hpp" #include "../physics/Hitbox.hpp" +#include #include #include #include @@ -14,6 +15,8 @@ struct entity_funcs_set { bool on_despawn : 1; bool on_grounded : 1; bool on_fall : 1; + bool on_trigger_enter : 1; + bool on_trigger_exit : 1; }; struct EntityDef; @@ -21,6 +24,7 @@ struct EntityDef; struct EntityId { entityid_t uid; const EntityDef& def; + bool destroyFlag = false; }; struct Transform { @@ -35,6 +39,7 @@ struct Transform { struct Rigidbody { bool enabled = true; Hitbox hitbox; + std::vector triggers; }; struct Scripting { @@ -59,8 +64,8 @@ public: Entity(Entities& entities, entityid_t id, entt::registry& registry, const entt::entity entity) : entities(entities), id(id), registry(registry), entity(entity) {} - entityid_t getID() const { - return id; + EntityId& getID() const { + return registry.get(entity); } bool isValid() const { @@ -106,7 +111,7 @@ public: void updatePhysics(float delta); void update(); - void renderDebug(LineBatch& batch); + void renderDebug(LineBatch& batch, Frustum& frustum); void render(Assets* assets, ModelBatch& batch, Frustum& frustum); entityid_t spawn(EntityDef& def, glm::vec3 pos); diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 7d295819..91301c52 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -88,7 +88,8 @@ void Player::updateInput( substeps, crouch, flight ? 0.0f : 1.0f, - !noclip + !noclip, + 0 ); if (flight && hitbox->grounded) { diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index 718a8a0d..5090d7dc 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -1,8 +1,24 @@ #ifndef PHYSICS_HITBOX_HPP_ #define PHYSICS_HITBOX_HPP_ +#include "../maths/aabb.hpp" +#include "../typedefs.hpp" + +#include +#include #include +struct Trigger { + bool enabled = true; + entityid_t entity; + AABB aabb; + AABB calculated; + std::set prevEntered; + std::set nextEntered; + std::function enterCallback; + std::function exitCallback; +}; + struct Hitbox { glm::vec3 position; glm::vec3 halfsize; diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 5e03a04f..96f66ba2 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -6,12 +6,14 @@ #include "../voxels/Chunks.hpp" #include "../voxels/voxel.hpp" +#include + const float E = 0.03f; const float MAX_FIX = 0.1f; PhysicsSolver::PhysicsSolver(glm::vec3 gravity) : gravity(gravity) { } - +#include "../util/timeutil.hpp" void PhysicsSolver::step( Chunks* chunks, Hitbox* hitbox, @@ -19,7 +21,8 @@ void PhysicsSolver::step( uint substeps, bool shifting, float gravityScale, - bool collisions + bool collisions, + entityid_t entity ) { float dt = delta / static_cast(substeps); float linearDamping = hitbox->linearDamping; @@ -78,6 +81,21 @@ void PhysicsSolver::step( hitbox->grounded = true; } } + AABB aabb; + aabb.a = hitbox->position - hitbox->halfsize; + aabb.b = hitbox->position + hitbox->halfsize; + for (size_t i = 0; i < triggers.size(); i++) { + auto& trigger = triggers[i]; + if (trigger->entity == entity) { + continue; + } + if (aabb.intersect(trigger->calculated)) { + if (trigger->prevEntered.find(entity) == trigger->prevEntered.end()) { + trigger->enterCallback(trigger->entity, i, entity); + } + trigger->nextEntered.insert(entity); + } + } } void PhysicsSolver::colisionCalc( diff --git a/src/physics/PhysicsSolver.hpp b/src/physics/PhysicsSolver.hpp index a9807af4..8de77ac8 100644 --- a/src/physics/PhysicsSolver.hpp +++ b/src/physics/PhysicsSolver.hpp @@ -1,17 +1,21 @@ #ifndef PHYSICS_PHYSICSSOLVER_HPP_ #define PHYSICS_PHYSICSSOLVER_HPP_ +#include "Hitbox.hpp" + #include "../typedefs.hpp" #include "../voxels/voxel.hpp" +#include #include class Block; class Chunks; -struct Hitbox; +struct Trigger; class PhysicsSolver { glm::vec3 gravity; + std::vector triggers; public: PhysicsSolver(glm::vec3 gravity); void step( @@ -21,18 +25,23 @@ public: uint substeps, bool shifting, float gravityScale, - bool collisions + bool collisions, + entityid_t entity ); void colisionCalc( - Chunks* chunks, - Hitbox* hitbox, - glm::vec3& vel, - glm::vec3& pos, + Chunks* chunks, + Hitbox* hitbox, + glm::vec3& vel, + glm::vec3& pos, const glm::vec3 half, float stepHeight ); bool isBlockInside(int x, int y, int z, Hitbox* hitbox); bool isBlockInside(int x, int y, int z, Block* def, blockstate state, Hitbox* hitbox); + + void setTriggers(std::vector triggers) { + this->triggers = std::move(triggers); + } }; #endif // PHYSICS_PHYSICSSOLVER_HPP_ From 1ec5f0b170117cb07130c074ba3bd06aa38b73e4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 30 Jun 2024 17:23:35 +0300 Subject: [PATCH 036/178] update drop model --- res/content/base/models/cube.obj | 75 +++++++++++++++++--------------- src/objects/Entities.cpp | 6 +-- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/res/content/base/models/cube.obj b/res/content/base/models/cube.obj index 8beb020e..26e6ba76 100644 --- a/res/content/base/models/cube.obj +++ b/res/content/base/models/cube.obj @@ -1,38 +1,43 @@ -v 0.5 -0.5 -0.5 -v 0.5 -0.5 0.5 -v -0.5 -0.5 0.5 -v -0.5 -0.5 -0.5 -v 0.5 0.5 -0.5 -v 0.5 0.5 0.5 -v -0.5 0.5 0.5 -v -0.5 0.5 -0.5 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 1.0 0.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vn 0.0 -1.0 0.0 -vn 0.0 1.0 0.0 -vn 1.0 0.0 0.0 -vn -0.0 -0.0 1.0 -vn -1.0 -0.0 -0.0 -vn 0.0 0.0 -1.0 -usemtl blocks/leaves +# Blender v2.79 (sub 0) OBJ File: '' +# www.blender.org +mtllib cube.mtl +o Cube +v 0.125000 -0.125000 -0.125000 +v 0.125000 -0.125000 0.125000 +v -0.125000 -0.125000 0.125000 +v -0.125000 -0.125000 -0.125000 +v 0.125000 0.125000 -0.125000 +v 0.125000 0.125000 0.125000 +v -0.125000 0.125000 0.125000 +v -0.125000 0.125000 -0.125000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +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 +usemtl blocks/lamp +s off f 1/1/1 2/2/1 3/3/1 4/4/1 f 5/5/2 8/6/2 7/7/2 6/8/2 f 1/1/3 5/9/3 6/10/3 2/11/3 diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 95ace4a6..3feb9db7 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -34,9 +34,9 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { glm::vec3 size(1); auto id = nextID++; registry.emplace(entity, static_cast(id), def); - registry.emplace(entity, pos, size/4.0f, glm::mat3(1.0f)); + registry.emplace(entity, pos, size, glm::mat3(1.0f)); registry.emplace(entity, true, Hitbox {pos, def.hitbox}, std::vector{ - {true, id, AABB {glm::vec3{-1.0f, -1.0f, -1.0f}, glm::vec3{1.0f, 1.0f, 1.0f}}, {}, {}, {}, + {true, id, AABB {glm::vec3{-0.2f, -0.2f, -0.2f}, glm::vec3{0.2f, 0.2f, 0.2f}}, {}, {}, {}, [=](auto entityid, auto index, auto otherid) { if (auto entity = get(entityid)) { if (entity->isValid()) { @@ -77,7 +77,7 @@ void Entities::clean() { } } } -#include "../util/timeutil.hpp" + void Entities::updatePhysics(float delta){ auto view = registry.view(); auto physics = level->physics.get(); From df39a9a8f3db0f1f9803cba36ca0a7dc580e6708 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 30 Jun 2024 18:24:30 +0300 Subject: [PATCH 037/178] add new model and "optimizations" --- res/content/base/entities/drop.json | 2 +- res/content/base/models/item.mtl | 12 ++++ res/content/base/models/item.obj | 62 ++++++++++++++++++ res/content/base/preload.json | 3 +- res/content/base/scripts/components/drop.lua | 4 +- src/objects/Entities.cpp | 66 +++++++++++++------- src/objects/Entities.hpp | 6 +- 7 files changed, 125 insertions(+), 30 deletions(-) create mode 100644 res/content/base/models/item.mtl create mode 100644 res/content/base/models/item.obj diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json index e895490b..c0b8db42 100644 --- a/res/content/base/entities/drop.json +++ b/res/content/base/entities/drop.json @@ -1,3 +1,3 @@ { - "hitbox": [0.2, 0.15, 0.2] + "hitbox": [0.2, 0.2, 0.2] } diff --git a/res/content/base/models/item.mtl b/res/content/base/models/item.mtl new file mode 100644 index 00000000..379df14c --- /dev/null +++ b/res/content/base/models/item.mtl @@ -0,0 +1,12 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl Material +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 diff --git a/res/content/base/models/item.obj b/res/content/base/models/item.obj new file mode 100644 index 00000000..ec28ab68 --- /dev/null +++ b/res/content/base/models/item.obj @@ -0,0 +1,62 @@ +# Blender v2.79 (sub 0) OBJ File: '' +# www.blender.org +mtllib item.mtl +o Cube +v -0.282501 -0.015663 -0.282501 +v -0.282501 -0.015663 0.282500 +v 0.282500 -0.015663 0.282501 +v 0.282501 -0.015663 -0.282500 +v 0.282501 0.021634 -0.282500 +v 0.282500 0.021634 0.282501 +v -0.282501 0.021634 0.282500 +v -0.282501 0.021634 -0.282501 +v -0.282501 0.021634 -0.282501 +v -0.282501 0.021634 0.282500 +v 0.282500 0.021634 0.282501 +v 0.282501 0.021634 -0.282500 +v 0.282501 -0.015663 -0.282500 +v 0.282500 -0.015663 0.282501 +v -0.282501 -0.015663 0.282500 +v -0.282501 -0.015663 -0.282501 +v 0.282501 0.002840 -0.282500 +v 0.282500 0.002840 0.282501 +v -0.282501 0.002840 0.282500 +v -0.282501 0.002840 -0.282501 +v -0.282501 0.002840 -0.282501 +v -0.282501 0.002840 0.282500 +v 0.282500 0.002840 0.282501 +v 0.282501 0.002840 -0.282500 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +usemtl items/bazalt_breaker +s off +f 4/1/1 1/2/1 2/3/1 3/4/1 +f 5/5/1 8/6/1 7/7/1 6/8/1 +f 12/9/2 11/10/2 10/11/2 9/12/2 +f 13/13/2 14/14/2 15/15/2 16/16/2 +f 17/17/1 20/18/1 19/19/1 18/20/1 +f 24/21/2 23/22/2 22/23/2 21/24/2 diff --git a/res/content/base/preload.json b/res/content/base/preload.json index 238cab00..be5d5bec 100644 --- a/res/content/base/preload.json +++ b/res/content/base/preload.json @@ -4,6 +4,7 @@ "blocks/door_close" ], "models": [ - "cube" + "cube", + "item" ] } diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index a1ab5aa2..d432a2fb 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -22,7 +22,7 @@ end function on_update() if inair then - tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 1, 0}, math.random()*12)) - tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 0, 1}, math.random()*12)) + tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 1, 0}, math.random()*4)) + tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 0, 1}, math.random()*4)) end end diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 3feb9db7..f43c25a4 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -78,31 +78,42 @@ void Entities::clean() { } } -void Entities::updatePhysics(float delta){ +void Entities::preparePhysics() { + static uint64_t frameid = 0; + frameid++; auto view = registry.view(); auto physics = level->physics.get(); - { - std::vector triggers; - for (auto [entity, eid, transform, rigidbody] : view.each()) { - if (!rigidbody.enabled) { - continue; - } - for (size_t i = 0; i < rigidbody.triggers.size(); i++) { - auto& trigger = rigidbody.triggers[i]; - for (auto oid : trigger.prevEntered) { - if (trigger.nextEntered.find(oid) == trigger.nextEntered.end()) { - trigger.exitCallback(trigger.entity, i, oid); - } - } - trigger.prevEntered = trigger.nextEntered; - trigger.nextEntered.clear(); - trigger.calculated = trigger.aabb; - trigger.calculated.transform(transform.combined); - triggers.push_back(&trigger); - } + std::vector triggers; + for (auto [entity, eid, transform, rigidbody] : view.each()) { + if (!rigidbody.enabled) { + continue; + } + // TODO: temporary optimization until threaded solution + if ((eid.uid + frameid) % 3 != 0) { + continue; + } + for (size_t i = 0; i < rigidbody.triggers.size(); i++) { + auto& trigger = rigidbody.triggers[i]; + for (auto oid : trigger.prevEntered) { + if (trigger.nextEntered.find(oid) == trigger.nextEntered.end()) { + trigger.exitCallback(trigger.entity, i, oid); + } + } + trigger.prevEntered = trigger.nextEntered; + trigger.nextEntered.clear(); + trigger.calculated = trigger.aabb; + trigger.calculated.transform(transform.combined); + triggers.push_back(&trigger); } - physics->setTriggers(std::move(triggers)); } + physics->setTriggers(std::move(triggers)); +} + +void Entities::updatePhysics(float delta) { + preparePhysics(); + + auto view = registry.view(); + auto physics = level->physics.get(); for (auto [entity, eid, transform, rigidbody] : view.each()) { if (!rigidbody.enabled) { continue; @@ -110,11 +121,15 @@ void Entities::updatePhysics(float delta){ auto& hitbox = rigidbody.hitbox; auto prevVel = hitbox.velocity; bool grounded = hitbox.grounded; + + float vel = glm::length(prevVel); + int substeps = static_cast(delta * vel * 20); + substeps = std::min(100, std::max(2, substeps)); physics->step( level->chunks.get(), &hitbox, delta, - 10, + substeps, false, 1.0f, true, @@ -139,7 +154,7 @@ void Entities::update() { } } -void Entities::renderDebug(LineBatch& batch, Frustum& frustum) { +void Entities::renderDebug(LineBatch& batch, const Frustum& frustum) { batch.lineWidth(1.0f); auto view = registry.view(); for (auto [entity, transform, rigidbody] : view.each()) { @@ -157,9 +172,12 @@ void Entities::renderDebug(LineBatch& batch, Frustum& frustum) { } } -void Entities::render(Assets* assets, ModelBatch& batch, Frustum& frustum) { +void Entities::render(Assets* assets, ModelBatch& batch, const Frustum& frustum) { auto view = registry.view(); auto model = assets->get("cube"); + if (model == nullptr) { + return; + } for (auto [entity, transform] : view.each()) { const auto& pos = transform.pos; const auto& size = transform.size; diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 7403c645..0860e6a4 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -104,6 +104,8 @@ class Entities { Level* level; std::unordered_map entities; entityid_t nextID = 1; + + void preparePhysics(); public: Entities(Level* level); @@ -111,8 +113,8 @@ public: void updatePhysics(float delta); void update(); - void renderDebug(LineBatch& batch, Frustum& frustum); - void render(Assets* assets, ModelBatch& batch, Frustum& frustum); + void renderDebug(LineBatch& batch, const Frustum& frustum); + void render(Assets* assets, ModelBatch& batch, const Frustum& frustum); entityid_t spawn(EntityDef& def, glm::vec3 pos); From d4460928e55418a844a00393826c7a9b1534abf8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 30 Jun 2024 19:19:43 +0300 Subject: [PATCH 038/178] add Transform.dirty flag --- res/content/base/scripts/components/drop.lua | 5 +++-- res/content/base/scripts/hud.lua | 6 +++--- src/logic/scripting/lua/libentity.cpp | 4 ++-- src/objects/Entities.cpp | 7 +++++-- src/objects/Entities.hpp | 17 ++++++++++++++++- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index d432a2fb..6c8c4a1a 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -22,7 +22,8 @@ end function on_update() if inair then - tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 1, 0}, math.random()*4)) - tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 0, 1}, math.random()*4)) + local dt = time.delta(); + tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 1, 0}, 240*dt)) + tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 0, 1}, 240*dt)) end end diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 78027e7f..8245a22a 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -9,9 +9,9 @@ function on_hud_open() local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) local throw_force = vec3.mul(vec3.add(player.get_dir(pid), { - (math.random() - 0.5) * 5, - (math.random() - 0.5) * 5, - (math.random() - 0.5) * 5 + (math.random() - 0.5) * 1, + (math.random() - 0.5) * 1, + (math.random() - 0.5) * 1 }), DROP_FORCE) local drop = entity.spawn("base:drop", ppos) diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 326e4da7..11b16e2c 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -51,7 +51,7 @@ static int l_get_pos(lua::State* L) { static int l_set_pos(lua::State* L) { if (auto entity = get_entity(L, 1)) { - entity->getTransform().pos = lua::tovec3(L, 2); + entity->getTransform().setPos(lua::tovec3(L, 2)); } return 0; } @@ -79,7 +79,7 @@ static int l_get_rot(lua::State* L) { static int l_set_rot(lua::State* L) { if (auto entity = get_entity(L, 1)) { - entity->getTransform().rot = lua::tomat4(L, 2); + entity->getTransform().setRot(lua::tomat4(L, 2)); } return 0; } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index f43c25a4..c730a128 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -18,6 +18,7 @@ void Transform::refresh() { combined = glm::translate(combined, pos); combined = glm::scale(combined, size); combined = combined * glm::mat4(rot); + dirty = false; } void Entity::destroy() { @@ -136,7 +137,7 @@ void Entities::updatePhysics(float delta) { eid.uid ); hitbox.linearDamping = hitbox.grounded * 24; - transform.pos = hitbox.position; + transform.setPos(hitbox.position); if (hitbox.grounded && !grounded) { scripting::on_entity_grounded(*get(eid.uid), glm::length(prevVel-hitbox.velocity)); } @@ -150,7 +151,9 @@ void Entities::update() { scripting::on_entities_update(); auto view = registry.view(); for (auto [entity, transform] : view.each()) { - transform.refresh(); + if (transform.dirty) { + transform.refresh(); + } } } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 0860e6a4..289849fe 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -7,6 +7,8 @@ #include #include #include +#define GLM_ENABLE_EXPERIMENTAL +#include #include #include @@ -32,8 +34,21 @@ struct Transform { glm::vec3 size; glm::mat3 rot; glm::mat4 combined; + bool dirty = true; void refresh(); + + inline void setRot(glm::mat3 m) { + rot = m; + dirty = true; + } + + inline void setPos(glm::vec3 v) { + if (glm::distance2(pos, v) >= 0.00001f) { + dirty = true; + } + pos = v; + } }; struct Rigidbody { @@ -104,7 +119,7 @@ class Entities { Level* level; std::unordered_map entities; entityid_t nextID = 1; - + void preparePhysics(); public: Entities(Level* level); From 50f9bd508ac80c315af58cb4ce3e3a1d5935f5d0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 30 Jun 2024 20:35:42 +0300 Subject: [PATCH 039/178] update rigging --- res/content/base/models/cube.obj | 2 +- res/content/base/models/item.mtl | 12 ------------ res/content/base/scripts/components/drop.lua | 2 +- src/assets/assetload_funcs.cpp | 6 ++++-- src/objects/rigging.cpp | 10 ++++++++++ src/objects/rigging.hpp | 20 ++++++++++++++++++-- 6 files changed, 34 insertions(+), 18 deletions(-) delete mode 100644 res/content/base/models/item.mtl create mode 100644 src/objects/rigging.cpp diff --git a/res/content/base/models/cube.obj b/res/content/base/models/cube.obj index 26e6ba76..615773c1 100644 --- a/res/content/base/models/cube.obj +++ b/res/content/base/models/cube.obj @@ -36,7 +36,7 @@ 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 -usemtl blocks/lamp +usemtl $0 s off f 1/1/1 2/2/1 3/3/1 4/4/1 f 5/5/2 8/6/2 7/7/2 6/8/2 diff --git a/res/content/base/models/item.mtl b/res/content/base/models/item.mtl deleted file mode 100644 index 379df14c..00000000 --- a/res/content/base/models/item.mtl +++ /dev/null @@ -1,12 +0,0 @@ -# Blender MTL File: 'None' -# Material Count: 1 - -newmtl Material -Ns 96.078431 -Ka 1.000000 1.000000 1.000000 -Kd 0.640000 0.640000 0.640000 -Ks 0.500000 0.500000 0.500000 -Ke 0.000000 0.000000 0.000000 -Ni 1.000000 -d 1.000000 -illum 2 diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 6c8c4a1a..53e6c626 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -15,7 +15,7 @@ function on_fall() end function on_trigger_enter(index, oid) - if ready then + if ready and oid == 0 then entity:despawn() end end diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index b7fe8ccf..0fd5a36d 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -214,8 +214,10 @@ assetload::postfunc assetload::model( auto model = obj::parse(path.u8string(), text).release(); return [=](Assets* assets) { for (auto& mesh : model->meshes) { - auto filename = TEXTURES_FOLDER+"/"+mesh.texture; - loader->add(AssetType::texture, filename, mesh.texture, nullptr); + if (mesh.texture.find('$') == std::string::npos) { + auto filename = TEXTURES_FOLDER+"/"+mesh.texture; + loader->add(AssetType::texture, filename, mesh.texture, nullptr); + } } assets->store(std::unique_ptr(model), name); }; diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp new file mode 100644 index 00000000..9b6cd14f --- /dev/null +++ b/src/objects/rigging.cpp @@ -0,0 +1,10 @@ +#include "rigging.hpp" + +using namespace rigging; + +RigNode::RigNode(size_t index, std::string name, std::vector> subnodes) + : index(index), name(std::move(name)), subnodes(std::move(subnodes)) { +} + +RigConfig::RigConfig(std::unique_ptr root) : root(std::move(root)) { +} diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index a509533b..717aef87 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -5,7 +5,9 @@ #include #include +#include #include +#include namespace rigging { struct Rig; @@ -15,19 +17,33 @@ namespace rigging { }; class RigNode { - uint index; + size_t index; + std::string name; std::vector> subnodes; public: - RigNode(uint index); + RigNode(size_t index, std::string name, std::vector> subnodes); + + size_t getIndex() const { + return index; + } + + const auto& getSubnodes() const { + return subnodes; + } }; class RigConfig { std::unique_ptr root; + std::unordered_map indices; + std::vector nodes; + public: + RigConfig(std::unique_ptr root); }; struct Rig { RigConfig* config; Pose pose; + std::vector textures; }; }; From 15496070e054d71a72b653cc944eb980d6c1bfc3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 30 Jun 2024 23:14:02 +0300 Subject: [PATCH 040/178] add "triggers" entity property --- res/content/base/entities/drop.json | 5 ++++- res/content/base/scripts/components/drop.lua | 1 + res/modules/internal/stdcomp.lua | 4 ++++ res/scripts/stdlib.lua | 1 + src/content/ContentLoader.cpp | 10 ++++++++++ src/objects/Entities.cpp | 9 +++++---- src/objects/EntityDef.hpp | 3 +++ 7 files changed, 28 insertions(+), 5 deletions(-) diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json index c0b8db42..174f05b2 100644 --- a/res/content/base/entities/drop.json +++ b/res/content/base/entities/drop.json @@ -1,3 +1,6 @@ { - "hitbox": [0.2, 0.2, 0.2] + "hitbox": [0.2, 0.2, 0.2], + "triggers": [ + [-0.2, -0.2, -0.2, 0.2, 0.2, 0.2] + ] } diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 53e6c626..72acec7c 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -17,6 +17,7 @@ end function on_trigger_enter(index, oid) if ready and oid == 0 then entity:despawn() + inventory.add(player.get_inventory(oid), item.index("base:stone.item"), 1) end end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 1fd16e1b..2f97e520 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -36,9 +36,13 @@ return { local entity = setmetatable({eid=eid}, Entity) entity.transform = new_Transform(eid) entity.rigidbody = new_Rigidbody(eid) + entity.data = {} entities[eid] = entity; return entity end, + get_Entity = function(eid) + return entities[eid] + end, remove_Entity = function(eid) local entity = entities[eid] if entity then diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index eb0b08c4..ea49f0cb 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -304,6 +304,7 @@ function file.readlines(path) end stdcomp = require "core:internal/stdcomp" +entity.get = stdcomp.get_Entity -- Deprecated functions block_index = block.index diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 23d02953..c00a0f3e 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -314,6 +314,16 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs if (auto boxarr = root->list("hitbox")) { def.hitbox = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2)); } + if (auto triggersarr = root->list("triggers")) { + for (size_t i = 0; i < triggersarr->size(); i++) { + if (auto triggerarr = triggersarr->list(i)) { + def.triggers.push_back({ + {triggerarr->num(0), triggerarr->num(1), triggerarr->num(2)}, + {triggerarr->num(3), triggerarr->num(4), triggerarr->num(5)} + }); + } + } + } std::cout << "loading entity " << name << " from " << file.u8string() << std::endl; } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index c730a128..b1faee13 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -36,8 +36,9 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { auto id = nextID++; registry.emplace(entity, static_cast(id), def); registry.emplace(entity, pos, size, glm::mat3(1.0f)); - registry.emplace(entity, true, Hitbox {pos, def.hitbox}, std::vector{ - {true, id, AABB {glm::vec3{-0.2f, -0.2f, -0.2f}, glm::vec3{0.2f, 0.2f, 0.2f}}, {}, {}, {}, + auto& body = registry.emplace(entity, true, Hitbox {pos, def.hitbox}, std::vector{}); + for (auto& box : def.triggers) { + body.triggers.emplace_back(Trigger{true, id, box, AABB{}, {}, {}, [=](auto entityid, auto index, auto otherid) { if (auto entity = get(entityid)) { if (entity->isValid()) { @@ -50,8 +51,8 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { scripting::on_trigger_exit(*entity, index, otherid); } } - }} - }); + }}); + } auto& scripting = registry.emplace(entity, entity_funcs_set {}, nullptr); entities[id] = entity; scripting.env = scripting::on_entity_spawn(def, id, scripting.funcsset); diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index a409de09..3db361b0 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -2,9 +2,11 @@ #define OBJECTS_ENTITY_DEF_HPP_ #include +#include #include #include "../typedefs.hpp" +#include "../maths/aabb.hpp" struct EntityDef { /// @brief Entity string id (with prefix included) @@ -12,6 +14,7 @@ struct EntityDef { std::string scriptName = name.substr(name.find(':')+1); glm::vec3 hitbox {0.5f}; + std::vector triggers {}; struct { entityid_t id; From 1b41a75cf45c330177d9fade2e5265d82febba84 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 1 Jul 2024 00:17:58 +0300 Subject: [PATCH 041/178] add component ARGS variable --- res/content/base/entities/drop.json | 2 +- src/logic/scripting/lua/libentity.cpp | 6 +++++- src/logic/scripting/scripting.cpp | 9 ++++++++- src/logic/scripting/scripting.hpp | 7 ++++++- src/objects/Entities.cpp | 4 ++-- src/objects/Entities.hpp | 3 ++- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json index 174f05b2..cf9add8e 100644 --- a/res/content/base/entities/drop.json +++ b/res/content/base/entities/drop.json @@ -1,5 +1,5 @@ { - "hitbox": [0.2, 0.2, 0.2], + "hitbox": [0.2, 0.125, 0.2], "triggers": [ [-0.2, -0.2, -0.2, 0.2, 0.2, 0.2] ] diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 11b16e2c..622c12b6 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -31,7 +31,11 @@ static int l_spawn(lua::State* L) { auto defname = lua::tostring(L, 1); auto& def = content->entities.require(defname); auto pos = lua::tovec3(L, 2); - level->entities->spawn(def, pos); + dynamic::Value args = dynamic::NONE; + if (lua::gettop(L) > 2) { + args = lua::tovalue(L, 3); + } + level->entities->spawn(def, pos, args); return 1; } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 8d9e6a4c..5843f6d2 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -256,7 +256,12 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, }); } -scriptenv scripting::on_entity_spawn(const EntityDef& def, entityid_t eid, entity_funcs_set& funcsset) { +scriptenv scripting::on_entity_spawn( + const EntityDef& def, + entityid_t eid, + entity_funcs_set& funcsset, + dynamic::Value args +) { auto L = lua::get_main_thread(); lua::requireglobal(L, STDCOMP); if (lua::getfield(L, "new_Entity")) { @@ -266,6 +271,8 @@ scriptenv scripting::on_entity_spawn(const EntityDef& def, entityid_t eid, entit auto entityenv = create_entity_environment(get_root_environment(), -1); lua::get_from(L, lua::CHUNKS_TABLE, def.scriptName, true); lua::pushenv(L, *entityenv); + lua::pushvalue(L, args); + lua::setfield(L, "ARGS"); lua::setfenv(L); lua::call_nothrow(L, 0, 0); diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index f6d1ccdb..72900a37 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -76,7 +76,12 @@ namespace scripting { /// @return true if prevents default action bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); - scriptenv on_entity_spawn(const EntityDef& def, entityid_t eid, entity_funcs_set&); + scriptenv on_entity_spawn( + const EntityDef& def, + entityid_t eid, + entity_funcs_set&, + dynamic::Value args + ); bool on_entity_despawn(const EntityDef& def, const Entity& entity); bool on_entity_grounded(const Entity& entity, float force); bool on_entity_fall(const Entity& entity); diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index b1faee13..512f7213 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -30,7 +30,7 @@ void Entity::destroy() { Entities::Entities(Level* level) : level(level) { } -entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { +entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos, dynamic::Value args) { auto entity = registry.create(); glm::vec3 size(1); auto id = nextID++; @@ -55,7 +55,7 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos) { } auto& scripting = registry.emplace(entity, entity_funcs_set {}, nullptr); entities[id] = entity; - scripting.env = scripting::on_entity_spawn(def, id, scripting.funcsset); + scripting.env = scripting::on_entity_spawn(def, id, scripting.funcsset, std::move(args)); return id; } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 289849fe..91fe106c 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -3,6 +3,7 @@ #include "../typedefs.hpp" #include "../physics/Hitbox.hpp" +#include "../data/dynamic.hpp" #include #include @@ -131,7 +132,7 @@ public: void renderDebug(LineBatch& batch, const Frustum& frustum); void render(Assets* assets, ModelBatch& batch, const Frustum& frustum); - entityid_t spawn(EntityDef& def, glm::vec3 pos); + entityid_t spawn(EntityDef& def, glm::vec3 pos, dynamic::Value args=dynamic::NONE); std::optional get(entityid_t id) { const auto& found = entities.find(id); From beac332c968ea71895bc2c9917f7e0aef24381d1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 1 Jul 2024 05:30:27 +0300 Subject: [PATCH 042/178] update RigConfig --- res/content/base/preload.json | 3 + res/content/base/rigs/drop.json | 5 ++ res/content/base/scripts/components/drop.lua | 1 + src/assets/AssetsLoader.cpp | 75 +++++++++--------- src/assets/AssetsLoader.hpp | 15 ++-- src/assets/assetload_funcs.cpp | 24 +++++- src/assets/assetload_funcs.hpp | 23 ++++-- src/coders/json.cpp | 4 +- src/coders/json.hpp | 4 +- src/constants.hpp | 1 + src/objects/Entities.cpp | 6 +- src/objects/Entities.hpp | 7 +- src/objects/EntityDef.hpp | 6 ++ src/objects/rigging.cpp | 83 +++++++++++++++++++- src/objects/rigging.hpp | 35 ++++++++- 15 files changed, 230 insertions(+), 62 deletions(-) create mode 100644 res/content/base/rigs/drop.json diff --git a/res/content/base/preload.json b/res/content/base/preload.json index be5d5bec..364813ec 100644 --- a/res/content/base/preload.json +++ b/res/content/base/preload.json @@ -6,5 +6,8 @@ "models": [ "cube", "item" + ], + "rigs": [ + "drop" ] } diff --git a/res/content/base/rigs/drop.json b/res/content/base/rigs/drop.json new file mode 100644 index 00000000..675759f7 --- /dev/null +++ b/res/content/base/rigs/drop.json @@ -0,0 +1,5 @@ +{ + "root": { + "model": "cube" + } +} diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 72acec7c..3ce24f95 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -1,5 +1,6 @@ local tsf = entity.transform local body = entity.rigidbody +local rig = entity.modeltree inair = true ready = false diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index 65f52da7..e426a8c1 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -24,13 +24,14 @@ static debug::Logger logger("assets-loader"); AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths) : assets(assets), paths(paths) { - addLoader(AssetType::shader, assetload::shader); - addLoader(AssetType::texture, assetload::texture); - addLoader(AssetType::font, assetload::font); - addLoader(AssetType::atlas, assetload::atlas); - addLoader(AssetType::layout, assetload::layout); - addLoader(AssetType::sound, assetload::sound); - addLoader(AssetType::model, assetload::model); + addLoader(AssetType::SHADER, assetload::shader); + addLoader(AssetType::TEXTURE, assetload::texture); + addLoader(AssetType::FONT, assetload::font); + addLoader(AssetType::ATLAS, assetload::atlas); + addLoader(AssetType::LAYOUT, assetload::layout); + addLoader(AssetType::SOUND, assetload::sound); + addLoader(AssetType::MODEL, assetload::model); + addLoader(AssetType::RIG, assetload::rig); } void AssetsLoader::addLoader(AssetType tag, aloader_func func) { @@ -80,7 +81,7 @@ void addLayouts(const scriptenv& env, const std::string& prefix, const fs::path& if (file.extension().u8string() != ".xml") continue; std::string name = prefix+":"+file.stem().u8string(); - loader.add(AssetType::layout, file.u8string(), name, std::make_shared(env)); + loader.add(AssetType::LAYOUT, file.u8string(), name, std::make_shared(env)); } } @@ -89,18 +90,19 @@ void AssetsLoader::tryAddSound(const std::string& name) { return; } std::string file = SOUNDS_FOLDER+"/"+name; - add(AssetType::sound, file, name); + add(AssetType::SOUND, file, name); } static std::string assets_def_folder(AssetType tag) { switch (tag) { - case AssetType::font: return FONTS_FOLDER; - case AssetType::shader: return SHADERS_FOLDER; - case AssetType::texture: return TEXTURES_FOLDER; - case AssetType::atlas: return TEXTURES_FOLDER; - case AssetType::layout: return LAYOUTS_FOLDER; - case AssetType::sound: return SOUNDS_FOLDER; - case AssetType::model: return MODELS_FOLDER; + case AssetType::FONT: return FONTS_FOLDER; + case AssetType::SHADER: return SHADERS_FOLDER; + case AssetType::TEXTURE: return TEXTURES_FOLDER; + case AssetType::ATLAS: return TEXTURES_FOLDER; + case AssetType::LAYOUT: return LAYOUTS_FOLDER; + case AssetType::SOUND: return SOUNDS_FOLDER; + case AssetType::MODEL: return MODELS_FOLDER; + case AssetType::RIG: return RIGS_FOLDER; } return ""; } @@ -118,7 +120,7 @@ void AssetsLoader::processPreload( } map->str("path", path); switch (tag) { - case AssetType::sound: + case AssetType::SOUND: add(tag, path, name, std::make_shared( map->get("keep-pcm", false) )); @@ -153,11 +155,12 @@ void AssetsLoader::processPreloadList(AssetType tag, dynamic::List* list) { void AssetsLoader::processPreloadConfig(const fs::path& file) { auto root = files::read_json(file); - processPreloadList(AssetType::font, root->list("fonts")); - processPreloadList(AssetType::shader, root->list("shaders")); - processPreloadList(AssetType::texture, root->list("textures")); - processPreloadList(AssetType::sound, root->list("sounds")); - processPreloadList(AssetType::model, root->list("models")); + processPreloadList(AssetType::FONT, root->list("fonts")); + processPreloadList(AssetType::SHADER, root->list("shaders")); + processPreloadList(AssetType::TEXTURE, root->list("textures")); + processPreloadList(AssetType::SOUND, root->list("sounds")); + processPreloadList(AssetType::MODEL, root->list("models")); + processPreloadList(AssetType::RIG, root->list("rigs")); // layouts are loaded automatically } @@ -176,18 +179,18 @@ void AssetsLoader::processPreloadConfigs(const Content* content) { } void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) { - loader.add(AssetType::font, FONTS_FOLDER+"/font", "normal"); - loader.add(AssetType::shader, SHADERS_FOLDER+"/ui", "ui"); - loader.add(AssetType::shader, SHADERS_FOLDER+"/main", "main"); - loader.add(AssetType::shader, SHADERS_FOLDER+"/lines", "lines"); - loader.add(AssetType::texture, TEXTURES_FOLDER+"/gui/menubg", "gui/menubg"); - loader.add(AssetType::texture, TEXTURES_FOLDER+"/gui/delete_icon", "gui/delete_icon"); - loader.add(AssetType::texture, TEXTURES_FOLDER+"/gui/no_icon", "gui/no_icon"); - loader.add(AssetType::texture, TEXTURES_FOLDER+"/gui/no_world_icon", "gui/no_world_icon"); - loader.add(AssetType::texture, TEXTURES_FOLDER+"/gui/warning", "gui/warning"); - loader.add(AssetType::texture, TEXTURES_FOLDER+"/gui/error", "gui/error"); - loader.add(AssetType::texture, TEXTURES_FOLDER+"/gui/cross", "gui/cross"); - loader.add(AssetType::texture, TEXTURES_FOLDER+"/gui/refresh", "gui/refresh"); + loader.add(AssetType::FONT, FONTS_FOLDER+"/font", "normal"); + loader.add(AssetType::SHADER, SHADERS_FOLDER+"/ui", "ui"); + loader.add(AssetType::SHADER, SHADERS_FOLDER+"/main", "main"); + loader.add(AssetType::SHADER, SHADERS_FOLDER+"/lines", "lines"); + loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/menubg", "gui/menubg"); + loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/delete_icon", "gui/delete_icon"); + loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/no_icon", "gui/no_icon"); + loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/no_world_icon", "gui/no_world_icon"); + loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/warning", "gui/warning"); + loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/error", "gui/error"); + loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/cross", "gui/cross"); + loader.add(AssetType::TEXTURE, TEXTURES_FOLDER+"/gui/refresh", "gui/refresh"); if (content) { loader.processPreloadConfigs(content); @@ -206,8 +209,8 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) { addLayouts(pack->getEnvironment(), info.id, folder, loader); } } - loader.add(AssetType::atlas, TEXTURES_FOLDER+"/blocks", "blocks"); - loader.add(AssetType::atlas, TEXTURES_FOLDER+"/items", "items"); + loader.add(AssetType::ATLAS, TEXTURES_FOLDER+"/blocks", "blocks"); + loader.add(AssetType::ATLAS, TEXTURES_FOLDER+"/items", "items"); } bool AssetsLoader::loadExternalTexture( diff --git a/src/assets/AssetsLoader.hpp b/src/assets/AssetsLoader.hpp index 91eb1036..29a23428 100644 --- a/src/assets/AssetsLoader.hpp +++ b/src/assets/AssetsLoader.hpp @@ -20,13 +20,14 @@ namespace dynamic { } enum class AssetType { - texture, - shader, - font, - atlas, - layout, - sound, - model, + TEXTURE, + SHADER, + FONT, + ATLAS, + LAYOUT, + SOUND, + MODEL, + RIG, }; class ResPaths; diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 0fd5a36d..690422cb 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -18,6 +18,7 @@ #include "../graphics/core/Font.hpp" #include "../graphics/core/Model.hpp" #include "../graphics/core/TextureAnimation.hpp" +#include "../objects/rigging.hpp" #include "../frontend/UiDocument.hpp" #include "../constants.hpp" @@ -216,7 +217,7 @@ assetload::postfunc assetload::model( for (auto& mesh : model->meshes) { if (mesh.texture.find('$') == std::string::npos) { auto filename = TEXTURES_FOLDER+"/"+mesh.texture; - loader->add(AssetType::texture, filename, mesh.texture, nullptr); + loader->add(AssetType::TEXTURE, filename, mesh.texture, nullptr); } } assets->store(std::unique_ptr(model), name); @@ -227,6 +228,27 @@ assetload::postfunc assetload::model( } } +assetload::postfunc assetload::rig( + AssetsLoader* loader, + const ResPaths* paths, + const std::string& file, + const std::string& name, + const std::shared_ptr& +) { + auto path = paths->find(file+".json"); + auto text = files::read_string(path); + try { + auto rig = rigging::RigConfig::parse(text, path.u8string()).release(); + return [=](Assets* assets) { + // TODO: add models loading + assets->store(std::unique_ptr(rig), name); + }; + } catch (const parsing_error& err) { + std::cerr << err.errorLog() << std::endl; + throw; + } +} + static void read_anim_file( const std::string& animFile, std::vector>& frameList diff --git a/src/assets/assetload_funcs.hpp b/src/assets/assetload_funcs.hpp index 71b3cb93..cad64d32 100644 --- a/src/assets/assetload_funcs.hpp +++ b/src/assets/assetload_funcs.hpp @@ -18,49 +18,56 @@ namespace assetload { AssetsLoader*, const ResPaths* paths, const std::string& filename, - const std::string &name, + const std::string& name, const std::shared_ptr& settings ); postfunc shader( AssetsLoader*, const ResPaths* paths, const std::string& filename, - const std::string &name, + const std::string& name, const std::shared_ptr& settings ); postfunc atlas( AssetsLoader*, const ResPaths* paths, - const std::string &directory, - const std::string &name, + const std::string& directory, + const std::string& name, const std::shared_ptr& settings ); postfunc font( AssetsLoader*, const ResPaths* paths, const std::string& filename, - const std::string &name, + const std::string& name, const std::shared_ptr& settings ); postfunc layout( AssetsLoader*, const ResPaths* paths, const std::string& file, - const std::string &name, + const std::string& name, const std::shared_ptr& settings ); postfunc sound( AssetsLoader*, const ResPaths* paths, const std::string& file, - const std::string &name, + const std::string& name, const std::shared_ptr& settings ); postfunc model( AssetsLoader*, const ResPaths* paths, const std::string& file, - const std::string &name, + const std::string& name, + const std::shared_ptr& settings + ); + postfunc rig( + AssetsLoader*, + const ResPaths* paths, + const std::string& file, + const std::string& name, const std::shared_ptr& settings ); } diff --git a/src/coders/json.cpp b/src/coders/json.cpp index dbe42b5a..b3b3d1ea 100644 --- a/src/coders/json.cpp +++ b/src/coders/json.cpp @@ -238,11 +238,11 @@ Value Parser::parseValue() { throw error("unexpected character '"+std::string({next})+"'"); } -dynamic::Map_sptr json::parse(const std::string& filename, const std::string& source) { +dynamic::Map_sptr json::parse(std::string_view filename, std::string_view source) { Parser parser(filename, source); return parser.parse(); } -dynamic::Map_sptr json::parse(const std::string& source) { +dynamic::Map_sptr json::parse(std::string_view source) { return parse("", source); } diff --git a/src/coders/json.hpp b/src/coders/json.hpp index f4379fdc..7dc7b92e 100644 --- a/src/coders/json.hpp +++ b/src/coders/json.hpp @@ -9,8 +9,8 @@ #include namespace json { - dynamic::Map_sptr parse(const std::string& filename, const std::string& source); - dynamic::Map_sptr parse(const std::string& source); + dynamic::Map_sptr parse(std::string_view filename, std::string_view source); + dynamic::Map_sptr parse(std::string_view source); std::string stringify( const dynamic::Map* obj, diff --git a/src/constants.hpp b/src/constants.hpp index 76c13a74..022fa955 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -50,5 +50,6 @@ inline const std::string FONTS_FOLDER = "fonts"; inline const std::string LAYOUTS_FOLDER = "layouts"; inline const std::string SOUNDS_FOLDER = "sounds"; inline const std::string MODELS_FOLDER = "models"; +inline const std::string RIGS_FOLDER = "rigs"; #endif // CONSTANTS_HPP_ diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 512f7213..9df28497 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -36,7 +36,8 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos, dynamic::Value args) { auto id = nextID++; registry.emplace(entity, static_cast(id), def); registry.emplace(entity, pos, size, glm::mat3(1.0f)); - auto& body = registry.emplace(entity, true, Hitbox {pos, def.hitbox}, std::vector{}); + auto& body = registry.emplace( + entity, true, Hitbox {pos, def.hitbox}, std::vector{}); for (auto& box : def.triggers) { body.triggers.emplace_back(Trigger{true, id, box, AABB{}, {}, {}, [=](auto entityid, auto index, auto otherid) { @@ -140,7 +141,8 @@ void Entities::updatePhysics(float delta) { hitbox.linearDamping = hitbox.grounded * 24; transform.setPos(hitbox.position); if (hitbox.grounded && !grounded) { - scripting::on_entity_grounded(*get(eid.uid), glm::length(prevVel-hitbox.velocity)); + scripting::on_entity_grounded( + *get(eid.uid), glm::length(prevVel-hitbox.velocity)); } if (!hitbox.grounded && grounded) { scripting::on_entity_fall(*get(eid.uid)); diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 91fe106c..0e0982a3 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -77,7 +77,12 @@ class Entity { entt::registry& registry; const entt::entity entity; public: - Entity(Entities& entities, entityid_t id, entt::registry& registry, const entt::entity entity) + Entity( + Entities& entities, + entityid_t id, + entt::registry& registry, + const entt::entity entity + ) : entities(entities), id(id), registry(registry), entity(entity) {} EntityId& getID() const { diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index 3db361b0..5c4293c0 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -8,6 +8,10 @@ #include "../typedefs.hpp" #include "../maths/aabb.hpp" +namespace rigging { + class RigConfig; +} + struct EntityDef { /// @brief Entity string id (with prefix included) std::string const name; @@ -15,9 +19,11 @@ struct EntityDef { std::string scriptName = name.substr(name.find(':')+1); glm::vec3 hitbox {0.5f}; std::vector triggers {}; + std::string rigName = name.substr(name.find(":")+1); struct { entityid_t id; + rigging::RigConfig* rig; } rt {}; EntityDef(const std::string& name) : name(name) {} diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index 9b6cd14f..4d08548d 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -1,10 +1,89 @@ #include "rigging.hpp" +#include "../assets/Assets.hpp" +#include "../graphics/core/Model.hpp" +#include "../coders/json.hpp" + using namespace rigging; -RigNode::RigNode(size_t index, std::string name, std::vector> subnodes) - : index(index), name(std::move(name)), subnodes(std::move(subnodes)) { +RigNode::RigNode( + size_t index, + std::string name, + std::string model, + std::vector> subnodes) + : index(index), + name(std::move(name)), + modelName(model), + subnodes(std::move(subnodes)) +{} + +void RigNode::setModel(const Assets* assets, const std::string& name) { + modelName = name; + model = assets->get(name); } RigConfig::RigConfig(std::unique_ptr root) : root(std::move(root)) { } + +size_t RigConfig::update( + size_t index, + Rig& rig, + RigNode* node, + glm::mat4 matrix) +{ + rig.calculated.matrices[index] = matrix * rig.pose.matrices[index]; + index++; + for (auto& subnode : node->getSubnodes()) { + index = update(index, rig, subnode.get(), rig.calculated.matrices[index]); + } + return index; +} + +void RigConfig::update(Rig& rig, glm::mat4 matrix) { + update(0, rig, root.get(), matrix); +} + +void RigConfig::setup(const Assets* assets, RigNode* node) { + if (node == nullptr) { + setup(assets, root.get()); + } else { + node->setModel(assets, node->getModelName()); + for (auto& subnode : node->getSubnodes()) { + setup(assets, subnode.get()); + } + } +} + +static std::tuple> read_node( + dynamic::Map* root, size_t index +) { + std::string name; + std::string model; + root->str("name", name); + root->str("model", model); + std::vector> subnodes; + size_t count = 1; + if (auto nodesList = root->list("nodes")) { + for (size_t i = 0; i < nodesList->size(); i++) { + if (auto map = nodesList->map(i)) { + auto [subcount, subNode] = read_node(map, index+count); + subcount += count; + subnodes.push_back(std::move(subNode)); + } + } + } + return {index, std::make_unique(index, name, model, std::move(subnodes))}; +} + +std::unique_ptr RigConfig::parse( + std::string_view src, + std::string_view file +) { + auto root = json::parse(file, src); + auto rootNodeMap = root->map("root"); + if (rootNodeMap == nullptr) { + throw std::runtime_error("missing 'root' element"); + } + auto [count, rootNode] = read_node(root.get(), 0); + return std::make_unique(std::move(rootNode)); +} diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index 717aef87..ed084f27 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -9,6 +9,12 @@ #include #include +class Assets; + +namespace model { + struct Model; +} + namespace rigging { struct Rig; @@ -19,9 +25,21 @@ namespace rigging { class RigNode { size_t index; std::string name; + std::string modelName; std::vector> subnodes; + model::Model* model = nullptr; public: - RigNode(size_t index, std::string name, std::vector> subnodes); + RigNode( + size_t index, + std::string name, + std::string model, + std::vector> subnodes); + + void setModel(const Assets* assets, const std::string& name); + + const std::string& getModelName() const { + return modelName; + } size_t getIndex() const { return index; @@ -36,13 +54,28 @@ namespace rigging { std::unique_ptr root; std::unordered_map indices; std::vector nodes; + + size_t update( + size_t index, + Rig& rig, + RigNode* node, + glm::mat4 matrix); public: RigConfig(std::unique_ptr root); + + void update(Rig& rig, glm::mat4 matrix); + void setup(const Assets* assets, RigNode* node=nullptr); + + static std::unique_ptr parse( + std::string_view src, + std::string_view file + ); }; struct Rig { RigConfig* config; Pose pose; + Pose calculated; std::vector textures; }; }; From 4a3487f17bed861f4ced95a6b8b56183100a11e7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 1 Jul 2024 16:32:54 +0300 Subject: [PATCH 043/178] add assetssetupfunc --- src/assets/Assets.hpp | 35 +++++++++++++++++++++++++++++++++++ src/engine.cpp | 5 +++++ 2 files changed, 40 insertions(+) diff --git a/src/assets/Assets.hpp b/src/assets/Assets.hpp index fd39e8fe..f94adbd9 100644 --- a/src/assets/Assets.hpp +++ b/src/assets/Assets.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -18,11 +19,17 @@ namespace assetload { using postfunc = std::function; } +template +void assets_setup(const Assets*); + +using assetssetupfunc = std::function; + class Assets { std::vector animations; using assets_map = std::unordered_map>; std::unordered_map assets; + std::vector setupFuncs; public: Assets() {} Assets(const Assets&) = delete; @@ -49,6 +56,34 @@ public: } return static_cast(found->second.get()); } + + template + std::optional getMap() const { + const auto& mapIter = assets.find(typeid(T)); + if (mapIter == assets.end()) { + return std::nullopt; + } + return &mapIter->second; + } + + void setup() { + for (auto& setupFunc : setupFuncs) { + setupFunc(this); + } + } + + void addSetupFunc(assetssetupfunc setupfunc) { + setupFuncs.push_back(setupfunc); + } }; +template +void assets_setup(const Assets* assets) { + if (auto mapPtr = assets->getMap()) { + for (const auto& entry : **mapPtr) { + static_cast(entry.second.get())->setup(assets); + } + } +} + #endif // ASSETS_ASSETS_HPP_ diff --git a/src/engine.cpp b/src/engine.cpp index e24e66cd..9e5c7235 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -23,6 +23,7 @@ #include "graphics/core/ImageData.hpp" #include "graphics/core/Shader.hpp" #include "graphics/ui/GUI.hpp" +#include "objects/rigging.hpp" #include "logic/EngineController.hpp" #include "logic/CommandsInterpreter.hpp" #include "logic/scripting/scripting.hpp" @@ -121,6 +122,7 @@ void Engine::loadControls() { } void Engine::onAssetsLoaded() { + assets->setup(); gui->onAssetsLoad(assets.get()); } @@ -243,9 +245,12 @@ void Engine::loadAssets() { Shader::preprocessor->setPaths(resPaths.get()); auto new_assets = std::make_unique(); + new_assets->addSetupFunc(assets_setup); AssetsLoader loader(new_assets.get(), resPaths.get()); AssetsLoader::addDefaults(loader, content.get()); + // no need + // correct log messages order is more useful bool threading = false; if (threading) { auto task = loader.startTask([=](){}); From 824231bfd6ade114692f2653cc8c816945dab0f1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 1 Jul 2024 17:15:48 +0300 Subject: [PATCH 044/178] refactor: moved funcs to assetload --- src/assets/Assets.hpp | 16 ++++++++-------- src/engine.cpp | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/assets/Assets.hpp b/src/assets/Assets.hpp index f94adbd9..fa497fcb 100644 --- a/src/assets/Assets.hpp +++ b/src/assets/Assets.hpp @@ -17,19 +17,19 @@ class Assets; namespace assetload { /// @brief final work to do in the main thread using postfunc = std::function; + + using setupfunc = std::function; + + template + void assets_setup(const Assets*); } -template -void assets_setup(const Assets*); - -using assetssetupfunc = std::function; - class Assets { std::vector animations; using assets_map = std::unordered_map>; std::unordered_map assets; - std::vector setupFuncs; + std::vector setupFuncs; public: Assets() {} Assets(const Assets&) = delete; @@ -72,13 +72,13 @@ public: } } - void addSetupFunc(assetssetupfunc setupfunc) { + void addSetupFunc(assetload::setupfunc setupfunc) { setupFuncs.push_back(setupfunc); } }; template -void assets_setup(const Assets* assets) { +void assetload::assets_setup(const Assets* assets) { if (auto mapPtr = assets->getMap()) { for (const auto& entry : **mapPtr) { static_cast(entry.second.get())->setup(assets); diff --git a/src/engine.cpp b/src/engine.cpp index 9e5c7235..8033c798 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -245,7 +245,7 @@ void Engine::loadAssets() { Shader::preprocessor->setPaths(resPaths.get()); auto new_assets = std::make_unique(); - new_assets->addSetupFunc(assets_setup); + new_assets->addSetupFunc(assetload::assets_setup); AssetsLoader loader(new_assets.get(), resPaths.get()); AssetsLoader::addDefaults(loader, content.get()); From 8e08f79b545aa4767160e718e3533de30bd8311d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 1 Jul 2024 22:09:52 +0300 Subject: [PATCH 045/178] add modeltree component --- res/modules/internal/stdcomp.lua | 8 ++++++++ src/logic/scripting/lua/libentity.cpp | 3 ++- src/objects/Entities.cpp | 24 ++++++++++++++++++++---- src/objects/Entities.hpp | 6 +++++- src/objects/rigging.hpp | 25 ++++++++++++++++++------- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 2f97e520..eb7a41b6 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -23,6 +23,13 @@ function new_Rigidbody(eid) return setmetatable({eid=eid}, Rigidbody) end +local Modeltree = {__index={ +}} + +function new_Modeltree(eid) + return setmetatable({eid=eid}, Modeltree) +end + -- Entity class local Entity = {__index={ @@ -36,6 +43,7 @@ return { local entity = setmetatable({eid=eid}, Entity) entity.transform = new_Transform(eid) entity.rigidbody = new_Rigidbody(eid) + entity.modeltree = new_Modeltree(eid) entity.data = {} entities[eid] = entity; return entity diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 622c12b6..3cb3de87 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -8,6 +8,7 @@ #include "../../../window/Camera.hpp" #include "../../../frontend/hud.hpp" #include "../../../content/Content.hpp" +#include "../../../engine.hpp" #include @@ -35,7 +36,7 @@ static int l_spawn(lua::State* L) { if (lua::gettop(L) > 2) { args = lua::tovalue(L, 3); } - level->entities->spawn(def, pos, args); + level->entities->spawn(scripting::engine->getAssets(), def, pos, args); return 1; } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 9df28497..18ca39f7 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -9,6 +9,7 @@ #include "../graphics/core/Model.hpp" #include "../maths/FrustumCulling.hpp" #include "../objects/EntityDef.hpp" +#include "../objects/rigging.hpp" #include "../logic/scripting/scripting.hpp" #include @@ -30,7 +31,16 @@ void Entity::destroy() { Entities::Entities(Level* level) : level(level) { } -entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos, dynamic::Value args) { +entityid_t Entities::spawn( + Assets* assets, + EntityDef& def, + glm::vec3 pos, + dynamic::Value args) +{ + auto rig = assets->get(def.rigName); + if (rig == nullptr) { + throw std::runtime_error("rig "+def.rigName+" not found"); + } auto entity = registry.create(); glm::vec3 size(1); auto id = nextID++; @@ -54,9 +64,12 @@ entityid_t Entities::spawn(EntityDef& def, glm::vec3 pos, dynamic::Value args) { } }}); } - auto& scripting = registry.emplace(entity, entity_funcs_set {}, nullptr); + auto& scripting = registry.emplace( + entity, entity_funcs_set {}, nullptr); entities[id] = entity; - scripting.env = scripting::on_entity_spawn(def, id, scripting.funcsset, std::move(args)); + scripting.env = scripting::on_entity_spawn( + def, id, scripting.funcsset, std::move(args)); + registry.emplace(entity, rig->instance()); return id; } @@ -173,7 +186,10 @@ void Entities::renderDebug(LineBatch& batch, const Frustum& frustum) { batch.box(hitbox.position, hitbox.halfsize * 2.0f, glm::vec4(1.0f)); for (auto& trigger : rigidbody.triggers) { - batch.box(trigger.calculated.center(), trigger.calculated.size(), glm::vec4(1.0f, 1.0f, 0.0f, 1.0f)); + batch.box( + trigger.calculated.center(), + trigger.calculated.size(), + glm::vec4(1.0f, 1.0f, 0.0f, 1.0f)); } } } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 0e0982a3..e85c8f03 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -137,7 +137,11 @@ public: void renderDebug(LineBatch& batch, const Frustum& frustum); void render(Assets* assets, ModelBatch& batch, const Frustum& frustum); - entityid_t spawn(EntityDef& def, glm::vec3 pos, dynamic::Value args=dynamic::NONE); + entityid_t spawn( + Assets* assets, + EntityDef& def, + glm::vec3 pos, + dynamic::Value args=dynamic::NONE); std::optional get(entityid_t id) { const auto& found = entities.find(id); diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index ed084f27..7cef4baf 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -17,9 +17,14 @@ namespace model { namespace rigging { struct Rig; + class RigConfig; struct Pose { std::vector matrices; + + Pose(size_t size) : matrices(size) { + matrices.resize(size); + } }; class RigNode { @@ -49,6 +54,13 @@ namespace rigging { return subnodes; } }; + + struct Rig { + RigConfig* config; + Pose pose; + Pose calculated; + std::vector textures; + }; class RigConfig { std::unique_ptr root; @@ -66,18 +78,17 @@ namespace rigging { void update(Rig& rig, glm::mat4 matrix); void setup(const Assets* assets, RigNode* node=nullptr); + Rig instance() { + return Rig { + this, Pose(nodes.size()), Pose(nodes.size()), {} + }; + } + static std::unique_ptr parse( std::string_view src, std::string_view file ); }; - - struct Rig { - RigConfig* config; - Pose pose; - Pose calculated; - std::vector textures; - }; }; #endif // OBJECTS_SKELETON_HPP_ From 56ef207b7db47eee24ea637b8b700537ea7f2546 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 2 Jul 2024 15:04:41 +0300 Subject: [PATCH 046/178] update entities render to use rigs --- src/objects/Entities.cpp | 13 ++++------- src/objects/Entities.hpp | 5 ++++- src/objects/rigging.cpp | 48 +++++++++++++++++++++++++++++++--------- src/objects/rigging.hpp | 21 ++++++++++++++---- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 18ca39f7..d46f3472 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -195,18 +195,13 @@ void Entities::renderDebug(LineBatch& batch, const Frustum& frustum) { } void Entities::render(Assets* assets, ModelBatch& batch, const Frustum& frustum) { - auto view = registry.view(); - auto model = assets->get("cube"); - if (model == nullptr) { - return; - } - for (auto [entity, transform] : view.each()) { + auto view = registry.view(); + for (auto [entity, transform, rig] : view.each()) { const auto& pos = transform.pos; const auto& size = transform.size; if (frustum.isBoxVisible(pos-size, pos+size)) { - batch.pushMatrix(transform.combined); - batch.draw(model); - batch.popMatrix(); + const auto* rigConfig = rig.config; + rigConfig->render(assets, batch, rig, transform.combined); } } } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index e85c8f03..35811875 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -68,8 +68,11 @@ class Assets; class LineBatch; class ModelBatch; class Frustum; -class Rig; class Entities; +namespace riggining { + struct Rig; + class RigConfig; +} class Entity { Entities& entities; diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index 4d08548d..cb96fe71 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -1,6 +1,7 @@ #include "rigging.hpp" #include "../assets/Assets.hpp" +#include "../graphics/render/ModelBatch.hpp" #include "../graphics/core/Model.hpp" #include "../coders/json.hpp" @@ -13,7 +14,7 @@ RigNode::RigNode( std::vector> subnodes) : index(index), name(std::move(name)), - modelName(model), + modelName(std::move(model)), subnodes(std::move(subnodes)) {} @@ -22,28 +23,36 @@ void RigNode::setModel(const Assets* assets, const std::string& name) { model = assets->get(name); } -RigConfig::RigConfig(std::unique_ptr root) : root(std::move(root)) { +static void get_all_nodes(std::vector& nodes, RigNode* node) { + nodes[node->getIndex()] = node; + for (auto& subnode : node->getSubnodes()) { + get_all_nodes(nodes, subnode.get()); + } +} + +RigConfig::RigConfig(std::unique_ptr root, size_t nodesCount) + : root(std::move(root)), nodes(nodesCount) { + get_all_nodes(nodes, this->root.get()); } size_t RigConfig::update( size_t index, Rig& rig, RigNode* node, - glm::mat4 matrix) + glm::mat4 matrix) const { rig.calculated.matrices[index] = matrix * rig.pose.matrices[index]; - index++; for (auto& subnode : node->getSubnodes()) { - index = update(index, rig, subnode.get(), rig.calculated.matrices[index]); + index = update(index+1, rig, subnode.get(), rig.calculated.matrices[index]); } return index; } -void RigConfig::update(Rig& rig, glm::mat4 matrix) { +void RigConfig::update(Rig& rig, glm::mat4 matrix) const { update(0, rig, root.get(), matrix); } -void RigConfig::setup(const Assets* assets, RigNode* node) { +void RigConfig::setup(const Assets* assets, RigNode* node) const { if (node == nullptr) { setup(assets, root.get()); } else { @@ -54,6 +63,25 @@ void RigConfig::setup(const Assets* assets, RigNode* node) { } } +void RigConfig::render( + Assets*, + ModelBatch& batch, + Rig& rig, + const glm::mat4& matrix) const +{ + update(rig, matrix); + for (size_t i = 0; i < nodes.size(); i++) { + auto* node = nodes[i]; + auto model = node->getModel(); + if (model == nullptr) { + continue; + } + batch.pushMatrix(rig.calculated.matrices[i]); + batch.draw(model); + batch.popMatrix(); + } +} + static std::tuple> read_node( dynamic::Map* root, size_t index ) { @@ -72,7 +100,7 @@ static std::tuple> read_node( } } } - return {index, std::make_unique(index, name, model, std::move(subnodes))}; + return {index + count, std::make_unique(index, name, model, std::move(subnodes))}; } std::unique_ptr RigConfig::parse( @@ -84,6 +112,6 @@ std::unique_ptr RigConfig::parse( if (rootNodeMap == nullptr) { throw std::runtime_error("missing 'root' element"); } - auto [count, rootNode] = read_node(root.get(), 0); - return std::make_unique(std::move(rootNode)); + auto [count, rootNode] = read_node(rootNodeMap, 0); + return std::make_unique(std::move(rootNode), count); } diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index 7cef4baf..e84bb42e 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -10,6 +10,7 @@ #include class Assets; +class ModelBatch; namespace model { struct Model; @@ -24,6 +25,9 @@ namespace rigging { Pose(size_t size) : matrices(size) { matrices.resize(size); + for (size_t i = 0; i < size; i++) { + matrices[i] = glm::mat4(1.0f); + } } }; @@ -46,6 +50,10 @@ namespace rigging { return modelName; } + model::Model* getModel() const { + return model; + } + size_t getIndex() const { return index; } @@ -71,12 +79,17 @@ namespace rigging { size_t index, Rig& rig, RigNode* node, - glm::mat4 matrix); + glm::mat4 matrix) const; public: - RigConfig(std::unique_ptr root); + RigConfig(std::unique_ptr root, size_t nodesCount); - void update(Rig& rig, glm::mat4 matrix); - void setup(const Assets* assets, RigNode* node=nullptr); + void update(Rig& rig, glm::mat4 matrix) const; + void setup(const Assets* assets, RigNode* node=nullptr) const; + void render( + Assets* assets, + ModelBatch& batch, + Rig& rig, + const glm::mat4& matrix) const; Rig instance() { return Rig { From 3fe66e134d599e714bda659789c9b5fdb794ded6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 2 Jul 2024 17:06:33 +0300 Subject: [PATCH 047/178] add modeltree:get_model(index) --- res/content/base/scripts/hud.lua | 26 +++++++++++++------------- res/modules/internal/stdcomp.lua | 3 ++- src/logic/scripting/lua/api_lua.hpp | 7 +++++-- src/logic/scripting/lua/libentity.cpp | 20 ++++++++++++++++++-- src/logic/scripting/lua/lua_engine.cpp | 6 ++++-- src/objects/Entities.cpp | 4 ++++ src/objects/Entities.hpp | 5 ++++- src/objects/rigging.hpp | 4 ++++ 8 files changed, 54 insertions(+), 21 deletions(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 8245a22a..22d03672 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -4,20 +4,20 @@ local DROP_INIT_VEL = {0, 3, 0} function on_hud_open() input.add_callback("player.drop", function () for i=1,80 do - local pid = hud.get_player() - local pvel = {player.get_vel(pid)} - local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) - local throw_force = vec3.mul(vec3.add(player.get_dir(pid), - { - (math.random() - 0.5) * 1, - (math.random() - 0.5) * 1, - (math.random() - 0.5) * 1 - }), DROP_FORCE) + local pid = hud.get_player() + local pvel = {player.get_vel(pid)} + local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) + local throw_force = vec3.mul(vec3.add(player.get_dir(pid), + { + (math.random() - 0.5) * 1, + (math.random() - 0.5) * 1, + (math.random() - 0.5) * 1 + }), DROP_FORCE) - local drop = entity.spawn("base:drop", ppos) - drop.rigidbody:set_vel(vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) - drop.transform:set_rot(mat4.rotate(mat4.rotate(mat4.rotate({0, 1, 0}, math.random() * 360), - {1, 0, 0}, math.random() * 360), {0, 0, 1}, math.random() * 360)) + local drop = entities.spawn("base:drop", ppos) + drop.rigidbody:set_vel(vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) + drop.transform:set_rot(mat4.rotate(mat4.rotate(mat4.rotate({0, 1, 0}, math.random() * 360), + {1, 0, 0}, math.random() * 360), {0, 0, 1}, math.random() * 360)) end end) end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index eb7a41b6..0719d932 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -24,6 +24,7 @@ function new_Rigidbody(eid) end local Modeltree = {__index={ + get_model=function(self) return __modeltree.get_model(self.eid) end, }} function new_Modeltree(eid) @@ -33,7 +34,7 @@ end -- Entity class local Entity = {__index={ - despawn=function(self) return entity.despawn(self.eid) end, + despawn=function(self) return entities.despawn(self.eid) end, }} local entities = {} diff --git a/src/logic/scripting/lua/api_lua.hpp b/src/logic/scripting/lua/api_lua.hpp index 5b709c8d..5287813d 100644 --- a/src/logic/scripting/lua/api_lua.hpp +++ b/src/logic/scripting/lua/api_lua.hpp @@ -21,15 +21,18 @@ extern const luaL_Reg jsonlib []; extern const luaL_Reg mat4lib []; extern const luaL_Reg packlib []; extern const luaL_Reg playerlib []; -extern const luaL_Reg rigidbodylib []; extern const luaL_Reg timelib []; extern const luaL_Reg tomllib []; -extern const luaL_Reg transformlib []; extern const luaL_Reg vec2lib []; extern const luaL_Reg vec3lib []; extern const luaL_Reg vec4lib []; extern const luaL_Reg worldlib []; +// Components +extern const luaL_Reg modeltreelib []; +extern const luaL_Reg rigidbodylib []; +extern const luaL_Reg transformlib []; + // Lua Overrides extern int l_print(lua::State* L); diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 3cb3de87..db858742 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -4,6 +4,7 @@ #include "../../../world/Level.hpp" #include "../../../objects/Player.hpp" #include "../../../objects/Entities.hpp" +#include "../../../objects/rigging.hpp" #include "../../../physics/Hitbox.hpp" #include "../../../window/Camera.hpp" #include "../../../frontend/hud.hpp" @@ -110,6 +111,16 @@ static int l_get_size(lua::State* L) { return 0; } +static int l_modeltree_get_model(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + auto& rig = entity->getModeltree(); + auto* rigConfig = rig.config; + auto index = lua::tointeger(L, 2); + return lua::pushstring(L, rigConfig->getNodes()[index]->getModelName()); + } + return 0; +} + const luaL_Reg entitylib [] = { {"exists", lua::wrap}, {"spawn", lua::wrap}, @@ -117,13 +128,18 @@ const luaL_Reg entitylib [] = { {NULL, NULL} }; - const luaL_Reg transformlib [] = { +const luaL_Reg modeltreelib [] = { + {"get_model", lua::wrap}, + {NULL, NULL} +}; + +const luaL_Reg transformlib [] = { {"get_pos", lua::wrap}, {"set_pos", lua::wrap}, {"get_rot", lua::wrap}, {"set_rot", lua::wrap}, {NULL, NULL} - }; +}; const luaL_Reg rigidbodylib [] = { {"is_enabled", lua::wrap}, diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index fab28a7b..d99aa603 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -22,8 +22,8 @@ static void remove_lib_funcs(lua::State* L, const char* libname, const char* fun pushnil(L); setfield(L, funcs[i], -2); } + pop(L); } - pop(L); } static void create_libs(lua::State* L) { @@ -31,7 +31,6 @@ static void create_libs(lua::State* L) { openlib(L, "block", blocklib); openlib(L, "console", consolelib); openlib(L, "core", corelib); - openlib(L, "entity", entitylib); openlib(L, "file", filelib); openlib(L, "gui", guilib); openlib(L, "input", inputlib); @@ -48,7 +47,10 @@ static void create_libs(lua::State* L) { openlib(L, "vec4", vec4lib); openlib(L, "world", worldlib); + openlib(L, "entities", entitylib); + // components + openlib(L, "__modeltree", modeltreelib); openlib(L, "__rigidbody", rigidbodylib); openlib(L, "__transform", transformlib); diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index d46f3472..a62b03d5 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -28,6 +28,10 @@ void Entity::destroy() { } } +rigging::Rig& Entity::getModeltree() const { + return registry.get(entity); +} + Entities::Entities(Level* level) : level(level) { } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 35811875..953470fa 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -69,7 +69,8 @@ class LineBatch; class ModelBatch; class Frustum; class Entities; -namespace riggining { + +namespace rigging { struct Rig; class RigConfig; } @@ -112,6 +113,8 @@ public: return registry.get(entity); } + rigging::Rig& getModeltree() const; + entityid_t getUID() const { return registry.get(entity).uid; } diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index e84bb42e..c1028890 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -101,6 +101,10 @@ namespace rigging { std::string_view src, std::string_view file ); + + const std::vector& getNodes() const { + return nodes; + } }; }; From 0082a3444e1b8052bfb091d06e3fc3ea736b279b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 2 Jul 2024 20:01:29 +0300 Subject: [PATCH 048/178] update component parent environment to the pack environment --- src/content/ContentLoader.cpp | 19 ------------------- src/logic/scripting/scripting.cpp | 2 +- src/objects/Entities.cpp | 31 +++++++++++++++++++------------ src/objects/rigging.hpp | 7 +++++++ 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index c00a0f3e..253434a9 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -380,25 +380,6 @@ void ContentLoader::loadBlockMaterial(BlockMaterial& def, const fs::path& file) root->str("break-sound", def.breakSound); } -template -static void load_defs(ContentLoader* cl, dynamic::List* arr, const ContentPack* pack, ContentUnitBuilder& builder, size_t& counter) { - if (arr == nullptr) { - return; - } - for (size_t i = 0; i < arr->size(); i++) { - std::string name = arr->str(i); - auto colon = name.find(':'); - std::string full = colon == std::string::npos ? pack->id + ":" + name : name; - if (colon != std::string::npos) name[colon] = '/'; - auto& def = builder.create(full); - if (colon != std::string::npos) { - def.scriptName = name.substr(0, colon) + '/' + def.scriptName; - } - cl->*loadfunc(def, full, name); - counter++; - } -} - void ContentLoader::load() { logger.info() << "loading pack [" << pack->id << "]"; diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 5843f6d2..c5c99fbc 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -451,7 +451,7 @@ void scripting::load_entity_component(const scriptenv& penv, const EntityDef& de auto L = lua::get_main_thread(); std::string src = files::read_string(file); logger.info() << "script (component) " << file.u8string(); - lua::loadbuffer(L, 0, src, file.u8string()); + lua::loadbuffer(L, *penv, src, file.u8string()); lua::store_in(L, lua::CHUNKS_TABLE, def.scriptName); } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index a62b03d5..00385120 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -53,20 +53,27 @@ entityid_t Entities::spawn( auto& body = registry.emplace( entity, true, Hitbox {pos, def.hitbox}, std::vector{}); for (auto& box : def.triggers) { - body.triggers.emplace_back(Trigger{true, id, box, AABB{}, {}, {}, - [=](auto entityid, auto index, auto otherid) { - if (auto entity = get(entityid)) { - if (entity->isValid()) { - scripting::on_trigger_enter(*entity, index, otherid); + body.triggers.emplace_back(Trigger{ + true, + id, + box, + AABB{}, + {}, + {}, + [=](auto entityid, auto index, auto otherid) { + if (auto entity = get(entityid)) { + if (entity->isValid()) { + scripting::on_trigger_enter(*entity, index, otherid); + } } - } - }, [=](auto entityid, auto index, auto otherid) { - if (auto entity = get(entityid)) { - if (entity->isValid()) { - scripting::on_trigger_exit(*entity, index, otherid); + }, + [=](auto entityid, auto index, auto otherid) { + if (auto entity = get(entityid)) { + if (entity->isValid()) { + scripting::on_trigger_exit(*entity, index, otherid); + } } - } - }}); + }}); } auto& scripting = registry.emplace( entity, entity_funcs_set {}, nullptr); diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index c1028890..6da4bf97 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -73,6 +73,13 @@ namespace rigging { class RigConfig { std::unique_ptr root; std::unordered_map indices; + + /// Nodes and indices are ordered from root to subnodes. + /// Example: + /// 0 - root + /// 1 --- sub1 + /// 2 ----- subsub1 + /// 3 --- sub2 std::vector nodes; size_t update( From 8a10ed24da1d0d144e8697a5f9edab22919db77a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 2 Jul 2024 20:27:41 +0300 Subject: [PATCH 049/178] optimize models --- res/content/base/models/cube.obj | 71 +++++++++++------------ res/content/base/models/item.obj | 97 ++++++++++++++++---------------- 2 files changed, 81 insertions(+), 87 deletions(-) diff --git a/res/content/base/models/cube.obj b/res/content/base/models/cube.obj index 615773c1..969dad45 100644 --- a/res/content/base/models/cube.obj +++ b/res/content/base/models/cube.obj @@ -1,41 +1,38 @@ -# Blender v2.79 (sub 0) OBJ File: '' -# www.blender.org -mtllib cube.mtl o Cube -v 0.125000 -0.125000 -0.125000 -v 0.125000 -0.125000 0.125000 -v -0.125000 -0.125000 0.125000 -v -0.125000 -0.125000 -0.125000 -v 0.125000 0.125000 -0.125000 -v 0.125000 0.125000 0.125000 -v -0.125000 0.125000 0.125000 -v -0.125000 0.125000 -0.125000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 1.0000 0.0000 -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 +v 0.125 -0.125 -0.125 +v 0.125 -0.125 0.125 +v -0.125 -0.125 0.125 +v -0.125 -0.125 -0.125 +v 0.125 0.125 -0.125 +v 0.125 0.125 0.125 +v -0.125 0.125 0.125 +v -0.125 0.125 -0.125 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vn 0.0 -1.0 0.0 +vn 0.0 1.0 0.0 +vn 1.0 -0.0 0.0 +vn -0.0 -0.0 1.0 +vn -1.0 -0.0 -0.0 +vn 0.0 0.0 -1.0 usemtl $0 s off f 1/1/1 2/2/1 3/3/1 4/4/1 diff --git a/res/content/base/models/item.obj b/res/content/base/models/item.obj index ec28ab68..58702e79 100644 --- a/res/content/base/models/item.obj +++ b/res/content/base/models/item.obj @@ -1,58 +1,55 @@ -# Blender v2.79 (sub 0) OBJ File: '' -# www.blender.org -mtllib item.mtl o Cube v -0.282501 -0.015663 -0.282501 -v -0.282501 -0.015663 0.282500 -v 0.282500 -0.015663 0.282501 -v 0.282501 -0.015663 -0.282500 -v 0.282501 0.021634 -0.282500 -v 0.282500 0.021634 0.282501 -v -0.282501 0.021634 0.282500 +v -0.282501 -0.015663 0.2825 +v 0.2825 -0.015663 0.282501 +v 0.282501 -0.015663 -0.2825 +v 0.282501 0.021634 -0.2825 +v 0.2825 0.021634 0.282501 +v -0.282501 0.021634 0.2825 v -0.282501 0.021634 -0.282501 v -0.282501 0.021634 -0.282501 -v -0.282501 0.021634 0.282500 -v 0.282500 0.021634 0.282501 -v 0.282501 0.021634 -0.282500 -v 0.282501 -0.015663 -0.282500 -v 0.282500 -0.015663 0.282501 -v -0.282501 -0.015663 0.282500 +v -0.282501 0.021634 0.2825 +v 0.2825 0.021634 0.282501 +v 0.282501 0.021634 -0.2825 +v 0.282501 -0.015663 -0.2825 +v 0.2825 -0.015663 0.282501 +v -0.282501 -0.015663 0.2825 v -0.282501 -0.015663 -0.282501 -v 0.282501 0.002840 -0.282500 -v 0.282500 0.002840 0.282501 -v -0.282501 0.002840 0.282500 -v -0.282501 0.002840 -0.282501 -v -0.282501 0.002840 -0.282501 -v -0.282501 0.002840 0.282500 -v 0.282500 0.002840 0.282501 -v 0.282501 0.002840 -0.282500 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 1.000000 0.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 1.000000 0.000000 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -usemtl items/bazalt_breaker +v 0.282501 0.0284 -0.2825 +v 0.2825 0.0284 0.282501 +v -0.282501 0.0284 0.2825 +v -0.282501 0.0284 -0.282501 +v -0.282501 0.0284 -0.282501 +v -0.282501 0.0284 0.2825 +v 0.2825 0.0284 0.282501 +v 0.282501 0.0284 -0.2825 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 0.0 1.0 +vt 1.0 1.0 +vt 1.0 0.0 +vt 0.0 0.0 +vt 0.0 1.0 +vt 1.0 1.0 +vt 1.0 0.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 0.0 1.0 +vt 1.0 1.0 +vt 1.0 0.0 +vn 0.0 1.0 0.0 +vn 0.0 -1.0 0.0 +usemtl $0 s off f 4/1/1 1/2/1 2/3/1 3/4/1 f 5/5/1 8/6/1 7/7/1 6/8/1 From 42ea88501d6281e91d79e83e6822681e5c85d9cd Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 2 Jul 2024 22:13:16 +0300 Subject: [PATCH 050/178] add modeltree:get_matrix, :set_matrix --- res/content/base/scripts/components/drop.lua | 14 +++++++-- res/content/base/scripts/hud.lua | 2 -- res/modules/internal/stdcomp.lua | 4 ++- src/logic/scripting/lua/libentity.cpp | 31 +++++++++++++++++++- src/objects/Entities.cpp | 2 +- src/objects/rigging.cpp | 5 ++-- src/objects/rigging.hpp | 13 ++++---- 7 files changed, 53 insertions(+), 18 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 3ce24f95..287312d2 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -5,8 +5,14 @@ local rig = entity.modeltree inair = true ready = false + +local rotation = mat4.rotate({0, 1, 0}, math.random() * 360) +mat4.rotate(rotation, {1, 0, 0}, math.random() * 360, rotation) +mat4.rotate(rotation, {0, 0, 1}, math.random() * 360, rotation) +rig:set_matrix(0, rotation) + function on_grounded(force) - tsf:set_rot(mat4.rotate({0, 1, 0}, math.random()*360)) + rig:set_matrix(0, mat4.rotate({0, 1, 0}, math.random()*360)) inair = false ready = true end @@ -25,7 +31,9 @@ end function on_update() if inair then local dt = time.delta(); - tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 1, 0}, 240*dt)) - tsf:set_rot(mat4.rotate(tsf:get_rot(), {0, 0, 1}, 240*dt)) + local matrix = rig:get_matrix(0) + mat4.rotate(matrix, {0, 1, 0}, 240*dt, matrix) + mat4.rotate(matrix, {0, 0, 1}, 240*dt, matrix) + rig:set_matrix(0, matrix) end end diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 22d03672..4ad429b5 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -16,8 +16,6 @@ function on_hud_open() local drop = entities.spawn("base:drop", ppos) drop.rigidbody:set_vel(vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) - drop.transform:set_rot(mat4.rotate(mat4.rotate(mat4.rotate({0, 1, 0}, math.random() * 360), - {1, 0, 0}, math.random() * 360), {0, 0, 1}, math.random() * 360)) end end) end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 0719d932..b6e6f600 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -24,7 +24,9 @@ function new_Rigidbody(eid) end local Modeltree = {__index={ - get_model=function(self) return __modeltree.get_model(self.eid) end, + get_model=function(self, i) return __modeltree.get_model(self.eid, i) end, + get_matrix=function(self, i) return __modeltree.get_matrix(self.eid, i) end, + set_matrix=function(self, i, m) return __modeltree.set_matrix(self.eid, i, m) end, }} function new_Modeltree(eid) diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index db858742..8f1dbf6a 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -111,16 +111,43 @@ static int l_get_size(lua::State* L) { return 0; } +static int index_range_check(const rigging::Rig& rig, lua::Integer index) { + if (static_cast(index) >= rig.pose.matrices.size()) { + throw std::runtime_error("index out of range [0, " + + std::to_string(rig.pose.matrices.size()) + + "]"); + } + return static_cast(index); +} + static int l_modeltree_get_model(lua::State* L) { if (auto entity = get_entity(L, 1)) { auto& rig = entity->getModeltree(); auto* rigConfig = rig.config; - auto index = lua::tointeger(L, 2); + auto index = index_range_check(rig, lua::tointeger(L, 2)); return lua::pushstring(L, rigConfig->getNodes()[index]->getModelName()); } return 0; } +static int l_modeltree_get_matrix(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + auto& rig = entity->getModeltree(); + auto index = index_range_check(rig, lua::tointeger(L, 2)); + return lua::pushmat4(L, rig.pose.matrices[index]); + } + return 0; +} + +static int l_modeltree_set_matrix(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + auto& rig = entity->getModeltree(); + auto index = index_range_check(rig, lua::tointeger(L, 2)); + rig.pose.matrices[index] = lua::tomat4(L, 3); + } + return 0; +} + const luaL_Reg entitylib [] = { {"exists", lua::wrap}, {"spawn", lua::wrap}, @@ -130,6 +157,8 @@ const luaL_Reg entitylib [] = { const luaL_Reg modeltreelib [] = { {"get_model", lua::wrap}, + {"get_matrix", lua::wrap}, + {"set_matrix", lua::wrap}, {NULL, NULL} }; diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 00385120..6e024427 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -78,9 +78,9 @@ entityid_t Entities::spawn( auto& scripting = registry.emplace( entity, entity_funcs_set {}, nullptr); entities[id] = entity; + registry.emplace(entity, rig->instance()); scripting.env = scripting::on_entity_spawn( def, id, scripting.funcsset, std::move(args)); - registry.emplace(entity, rig->instance()); return id; } diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index cb96fe71..04a90177 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -42,10 +42,11 @@ size_t RigConfig::update( glm::mat4 matrix) const { rig.calculated.matrices[index] = matrix * rig.pose.matrices[index]; + size_t count = 1; for (auto& subnode : node->getSubnodes()) { - index = update(index+1, rig, subnode.get(), rig.calculated.matrices[index]); + count += update(index+count, rig, subnode.get(), rig.calculated.matrices[index]); } - return index; + return count; } void RigConfig::update(Rig& rig, glm::mat4 matrix) const { diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index 6da4bf97..e79bcf01 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -1,5 +1,5 @@ -#ifndef OBJECTS_SKELETON_HPP_ -#define OBJECTS_SKELETON_HPP_ +#ifndef OBJECTS_RIGGING_HPP_ +#define OBJECTS_RIGGING_HPP_ #include "../typedefs.hpp" @@ -23,11 +23,8 @@ namespace rigging { struct Pose { std::vector matrices; - Pose(size_t size) : matrices(size) { - matrices.resize(size); - for (size_t i = 0; i < size; i++) { - matrices[i] = glm::mat4(1.0f); - } + Pose(size_t size) { + matrices.resize(size, glm::mat4(1.0f)); } }; @@ -115,4 +112,4 @@ namespace rigging { }; }; -#endif // OBJECTS_SKELETON_HPP_ +#endif // OBJECTS_RIGGING_HPP_ From 89afcd15dbaa244c2af7716bc9612840b7bc44e4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 2 Jul 2024 22:41:13 +0300 Subject: [PATCH 051/178] add pickup sound --- res/content/base/preload.json | 3 ++- res/content/base/scripts/components/drop.lua | 1 + res/content/base/sounds/events/pickup.ogg | Bin 0 -> 7628 bytes 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 res/content/base/sounds/events/pickup.ogg diff --git a/res/content/base/preload.json b/res/content/base/preload.json index 364813ec..6e9aa592 100644 --- a/res/content/base/preload.json +++ b/res/content/base/preload.json @@ -1,7 +1,8 @@ { "sounds": [ "blocks/door_open", - "blocks/door_close" + "blocks/door_close", + "events/pickup" ], "models": [ "cube", diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 287312d2..8b85b871 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -25,6 +25,7 @@ function on_trigger_enter(index, oid) if ready and oid == 0 then entity:despawn() inventory.add(player.get_inventory(oid), item.index("base:stone.item"), 1) + audio.play_sound_2d("events/pickup", 0.5, 0.8+math.random()*0.4, "regular") end end diff --git a/res/content/base/sounds/events/pickup.ogg b/res/content/base/sounds/events/pickup.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3ec977416a54b131563e8f8ade86396f72c7a3a4 GIT binary patch literal 7628 zcmai22|UzY_y3K3&oUS#4cW$0#y&!bFt!Y14cW71_q5ougpg$tLs`cbk}Q#^F!r4x zl%hzK78Py&cX*!Xeg5zN|9Rj0x$fNGJ@=k-&pF?7@43u8JuM&_=+8n=%O*+fo;$u2 z4ikcfoeOgD3Z@RgbgQX9poGJAf9}J~s4M?2)Rk06qp-A$44#9xh>y}H(AtZGpTvO2GzZ#^X8!rUWLD7=TX(h{s-oqGA zghX0UA;!y8wH(QqZ2khn{N#(ctAANTnUDW4N{or!mL39z(J~N@hvTS?OQLWB0yI|y zgL;L_^MhEVDhe;N$oC>+jpbKMvrN@iD@xMT-byx%>afZ-jAM<_Q&z6E4;dUT1rK9Z z^8aj@clAJmz34CqxN+(*QQ0S=%5s7Lt39=lP&7~z($9b!-h~g`6&xB9HTxuE&Z9J@ zpl4xef(Iqk!8*)+IxKWLEW$P?-u`}s?frQBnRth9@y>{ZKkHV+!Z&K&RUHX~3J+tl zmr%tb`->Mb#k6q=)ijVB)g(yfOc7LOiD8+Ccdb`m)7jfiegpL~1NCgXQy>_aLM??} z#IpZWJ#4ex|9jOs+bacW0bBM23ibqw>fuCtf@BzXE!+zMpK9S`x`Pz;gB5#%)j`z{ z(d{D`4{aLn`^yPbw?mK?TCh7%un$-RCp!_OWF4$A9c(fUOhL8Ce=ae*cmawC-}K1# zj%HFwciuHiG+>J;VmiULCkaeQEP90`juJl)VK|7d3oGGy6OWTD^CVg-bMkgQ=sPU1 z1bm6=&+RVE9VG@28?q5ed%g4Ad5krc<6ul+C7**V;0)$@jT0FwpW1-6wxh)5iWWHN zB@yx@8e1&)`27isO2_=+$C#I3Mbd1ZPYbgH=xw{@zaL_zj{Q4)w1D57XAtC@myr=^ z3@&itGT|(tkZT-Sh3H;XsZeU#No-~8DV%@=Ddh65=12&NW zd2djDK!(~>cMhwq)pc^7U_%2G%P0X9r#3F%3a-T%_>dYYcG4sQ4vQk~MHFx<(k)$^ zL0~sX5^{q2QRN^i{^__6q9a@f$No`AJ_?$1i-9^OFKeNofw#n4hxysw2%T$=cbExX zn2uPOPIcl>_;+Ca9XSvPnz-GVB)FuYd-7vVb(r@Y{8!`z!h13V`!Yn0>P1b)WrjW} zntfIr6{;B&W7c9>9dpTN6Mg}Fa%a<^}euxR)H(}u5AnZU6}2bn`q zG`bhvg$Nop>?_nAMl;_e^kO7PS>uK%*=&RYO010Abt%7O+_0~dfG|qFS<3C2R09@4 zjNp&8Xf&M{rUi!}7d9LVDxQEFMlGk~`q8fiaac@wzQr(x>0n$xn&Dc>miT9U_^BrMIlf5i?9c@T6I<{} z0o2gx>$=t55{!t~f)>Ki|TGL-&msfjx zt!aa`Q)aC-psKd^cKte)+FG+l4qR)MyHti6D7*c(wX(IjQm;p zxU*^+$&(0nT2+%*b$hMeU%In;O~)J`;c(r3LB+wA-+w_R&3-zyxaw`I)Id8Bgq|m# z6MP^i=rE@Y2si6%SR-6}zcG*a%#j0ss4aaBExE(S+;a_J14hLLPrp`?ury7yDhy%} zUV&S1N_8VcIB{>0rIu(0;b2p2w;4U7KW9LfEB5f&j^cdg4_F}DS}`{DYv~LiVU~#lO+=mlaYW`A659SjMq5? zz$!O36N|06o{1aG&!V!5O~V?ZnliD*U{_e|-FTdxFPf5%^Hl=70<1EzzOrOHd*jAX zPCM4!UDY&N`FPimfp9Sr!U%h}kMh-@_^5#f`r-ckz}bQ(S7O!lmwB&jiAkXYEojgmD+ZDifCiR@nQtlx2GZ z0ugt$ad|e_SLy4dT{TsP5x60OueE%!0;f(iEu|RJcLa1S@oroJY^x_N}#7Hsg z3}PfIgN$`hDEy!{lUU<028HUTV3@>6d`42T-Bvy*6wpEzp6wnYSU=tv2;4r@!I;!a_uQ1P5tLopJ_a9IRF zKIc11un`0s+B-+iu(`0I6ObX6@={!J##o8U7+}$wPyhu|_n@73O~Z^9Q%yWY-bf5U z!K0=t$4(l8*1?9>ch3As%!Z?+H!>%I17>X1^B@l2d5F`}uG@-AAlR)V0W^G-!Z-n}$aW{NHQhEowZbHdOSRH80CD3o z(FY3%K0_@KG*8b6)zKc%QpOuNqWxS z=Rb1xe`W9gsb}v~10eU$2GZ(aVT5)V4_N7|qV}`OP<7(B(he&Ncr%KTC^&B*MU9EnFi90Pqiuj9 zQS7eDf{??4PnQ&>1RR*sJ>yc1E*-~#_(Zr?g8;Jg0bBQxMKw}fQW}B%!3jZexvE65 zV})M$2SCvVb%6=jOYc1yd$H?lVUTR=>{^@pFu(y{6jIS5tcwMxqGCii4!B`&EH3@; zF;2CWJ!k6*_|JkZ4{Rt#OZQ`3zv-1zw2%w(2bZPph<8GoX?wlmlSieo32=NXEnhJE17Y5 zJgB-cY!EytkxY;rr?5hd77UK)1%l$}P*7prqfzu}I=WZf@+@pDJ#oR~UbGNrTrXQj zq7552PgP8@iyCBe`b;llG+SzF!&TNd@{i~p=0lNjNIK!fZWug0I+n-(k41K~`;VE` z^hg|gFJKrX1VNeXND&btCXM6TzI4tEu1xMM9s+`#muN+G z-Qr5SUeSr|lBo?7)812sZnwYtLZ(wv-y>6B$W$?_F!Az3ib`Vxg9Cj%W75*HM-^2^zt9!7Lzk!>P4jc7VaVl>Jpoo+kXxT^ls7?> z%=YmE`9`XU&Rfbs_x5xidNrka)hYV(k8=)nO%6Z4cK#c2G`Ev0(Nw?D3xD2jdmN@E zaQ2R-X|Ca~rR;?pN_I}f=7oYmMn|*dqIVy=syN>9{ZaW^)B2Fe@ZGy~*iG})v;wb_ zEI&dxe45I%TDFD-+srog97=I7-JY*zs7F=iyzZC{58`zc3m!r?oH^v^m6;ja{cy!t zq@*hGtY76QZ<3k6y9(k#);fQ?LGh7opHou%zZh23h;n=+AELCKJmvJgrhLeeC~H3U zIk?%R`Po}h`^3fhwkq*}sP*y%7N}iWkWRdTq3>wtjIc&?5)-sEV{MpXYB($c^?w&# zTDxdwy-J~M&_5L8*86*k@Do|vO5TClN)*^rN4{dXf8MJ7v^*OAJccea;NY{BgZle; z99|1%UXtz*qJN{yaO1b80J`z&2hUJbu^srck|vRbi`PC%KdY9o%by!-)*6@+y}3GH z98Up903tWR|aF`&O2z_;gPPgXSMi+lfvHh_TT0% zE6iWzooyOQIrsVU975t23-nv1A;tFW<(E9`r^CY{+)uH<8{XNFjC4_}5ahJeuKsX) zbw@UXt6ivhx=gyWpn1*hSbto4vXlxTLnBX#g@JitbAx&Ae#kc=iOkFcNsdw9>OT}) z*#~TiB3I^n>GD^vrr^*AL>u`Myk&p$Qgf$_zmSdoAz>ca!hCC+ z>YXEFx#?3z8+Kys8I!Yv22WoaeB!f`i5MsED~=ink=k#KTa&AjcT7JWUD^ga+@(b^ zFzl>MfBN&wn8orM_@C4*6}I?9;h0aXK$WiISnX3v{f2#ZS4gzbfseyEnH$mh#}_s) zow1dD`Tn?9b4p-qft4%D-zm!2 zZ2aK!>I`H~-{t4rQ5K@F_{OsX?my^!wOQTP)jEr>ioL|svg-cF0AA~13v%e)_s^dG zxL(Qpac+;;f!@Qn>60j57rAc))=ipsjf6&d*UiNm(_E?3U*}E{Z0+IBL8(?~-cutt zJ$CsJm|^>ki5AjSVarHKH#(fM@QCAMr^?$xE@(+rTx@_C0i1GWfbxOle6MlqGtxWk z$B760{4&bV`S0349kJ85rtRj-8#25XvwWDfkvr1_Zm`j)?{JY(bS#$MDb~t=*iwFJ zIK?S&bzWKkw)L*f$jK3b)#Ixixi)lxDdHeq1l+tecd1CHa&DG`Wl>wHs;+=XWO@`(2*)LgK8c#^k>iFB9wDYmmOb4bKs(!o4XVc5FdHrGHWaxAf&hADTcM(}HfnLO%#ZT_2~?N|R7)~|!>IhP*} zbSRB7o~BXR-Y9OqHPW0a9laoSKf?iKsHa*R)3g8loTTn{t#er3TCZ(IR)j*_WyZ6Q zGOq6AUlGUrisXsbu;&%1Yl=@IeMaw>_T`VFy#&)6bDewTu|qw1kN)jIg>A^vI}9IUa$?Bnt@6>J*W}HQKM`>sj|4ROU^8WrkGHtv4IEo( zD~zOp4C=4N(p=2=cGGpRMf32hskT-4dHKt4@cNTWv~FK6 zpseRj*-LAG;k18ceEfBxfXx3M<%r2r$6}|=k09Rvj?#KU*~vZJadW!Tp#D6QSuJaC zN#BVmyZVO)#F&&Y74ei;)?crfMwzSH!40x|)9t>D=s3B4KWTHsK58pc7n7DB{bMcL z_Szpuk3_VhB+fSGBM$V3D*0k}T#RS#RmsP6gwVDtTf$P&tgoo?dY4_wVKk=7=5F;z z56G4d`Vn~X`-|JnO{NE?*Pj2(dhlS!x-VkQEkd(X>p@Ml^oKi!yu$299{-k7w;kqH zce1(0=Eyf^AC>cD=W)1nLVP-hMB09dQ&Npa6XdZEC!OxTw9{rKo!6mxNKh7(-m&z} z_{y<(DLuv#*WvPJEZ8l*bYtA9i%~eNQzv@)+1C+;BkdD@wrh`z>Kvnle6^Z7YD5>3 z|F{^)eLs*%SKy!@pWKU!=Q4MJq-$vEp&+2Vt@M_x{&9e)bv(CMttg%<@W%$WE|O0@K@+oXr-gY^ZD{E z^~fmHp|-Ed+gaaNo?Hqyjd^2rHeSNgVDe>M^N$I~#K~&2JJX@1#GmR%)f5~8QaC@c zF3iNA;bY|^X{`j&yo{DU^# zcS$y>Jo=Cq9zP-NKjb!KPMYCT=*YuCI#%U4u={^<^l=z^Kh;X}#`${Mi1qe~@C_5(G6QTX zEy<~VJctkWs4OZr^zm%%{aX_LObN9r&cCluE5xfh+^8Sh4410Hr%TFNbzG1?t$NtX_ zPTENpf0Gq+g9urOiEl*iBps1i9HIr_d9I?^NB^|2f&a4Lb{9_ka+l~uUw70~DO)ut zqQvv(mXfKNeY5*KOLo`oGLG5Sd(RGjSCPz7^Ci({%^MteSJ-%ZFwp0T*5Yz)3QX$F zeDKAUR!g%jaU{{U<^72YzlD1NPC`@S4ef&tlfDCH^{wxx9Ta8VjK{ChJB>rfeqRo;F26W+e84)>{!Op9q4BKGSZ_s*qJ{c-NY^_qP` zTN`gSH@zl)`+V;CId#-{G33*Ff0?iSP){^}d548%-W}174&0P2tT2-6M091j>-E)* zJ3@u3hA80VCE}A~+?W1jadGU!jqd%8 ze#OuW$D20> Date: Tue, 2 Jul 2024 23:36:38 +0300 Subject: [PATCH 052/178] implement actual items dropping --- res/content/base/scripts/components/drop.lua | 3 +- res/content/base/scripts/hud.lua | 29 +++++++++++--------- src/items/ItemStack.cpp | 3 ++ src/logic/scripting/lua/libinventory.cpp | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 8b85b871..6093a747 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -5,6 +5,7 @@ local rig = entity.modeltree inair = true ready = false +local item = ARGS.item local rotation = mat4.rotate({0, 1, 0}, math.random() * 360) mat4.rotate(rotation, {1, 0, 0}, math.random() * 360, rotation) @@ -24,7 +25,7 @@ end function on_trigger_enter(index, oid) if ready and oid == 0 then entity:despawn() - inventory.add(player.get_inventory(oid), item.index("base:stone.item"), 1) + inventory.add(player.get_inventory(oid), item.id, item.count) audio.play_sound_2d("events/pickup", 0.5, 0.8+math.random()*0.4, "regular") end end diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 4ad429b5..4a3af9cb 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -3,19 +3,22 @@ local DROP_INIT_VEL = {0, 3, 0} function on_hud_open() input.add_callback("player.drop", function () - for i=1,80 do - local pid = hud.get_player() - local pvel = {player.get_vel(pid)} - local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) - local throw_force = vec3.mul(vec3.add(player.get_dir(pid), - { - (math.random() - 0.5) * 1, - (math.random() - 0.5) * 1, - (math.random() - 0.5) * 1 - }), DROP_FORCE) - - local drop = entities.spawn("base:drop", ppos) - drop.rigidbody:set_vel(vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) + local pid = hud.get_player() + local invid, slot = player.get_inventory(pid) + local itemid, itemcount = inventory.get(invid, slot) + if itemid == 0 then + return end + inventory.set(invid, slot, itemid, itemcount-1) + + local pvel = {player.get_vel(pid)} + local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) + local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) + + local drop = entities.spawn("base:drop", ppos, {item={ + id=itemid, + count=1 + }}) + drop.rigidbody:set_vel(vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) end) end diff --git a/src/items/ItemStack.cpp b/src/items/ItemStack.cpp index d60246c3..4c715064 100644 --- a/src/items/ItemStack.cpp +++ b/src/items/ItemStack.cpp @@ -12,6 +12,9 @@ ItemStack::ItemStack(itemid_t item, itemcount_t count) : item(item), count(count void ItemStack::set(const ItemStack& item) { this->item = item.item; this->count = item.count; + if (count == 0) { + this->item = 0; + } } bool ItemStack::accepts(const ItemStack& other) const { diff --git a/src/logic/scripting/lua/libinventory.cpp b/src/logic/scripting/lua/libinventory.cpp index 717583b6..67f4e6f1 100644 --- a/src/logic/scripting/lua/libinventory.cpp +++ b/src/logic/scripting/lua/libinventory.cpp @@ -32,7 +32,7 @@ static std::shared_ptr get_inventory(int64_t id, int arg) { } static void validate_slotid(int slotid, Inventory* inv) { - if (slotid < 0 || uint64_t(slotid) >= inv->size()) { + if (static_cast(slotid) >= inv->size()) { throw std::runtime_error("slot index is out of range [0..inventory.size(invid)]"); } } From 8add39e506595dfeaa580cacbaa0a4fe72d56ba9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 2 Jul 2024 23:54:38 +0300 Subject: [PATCH 053/178] add entity trigger type parameter --- res/content/base/entities/drop.json | 2 +- res/scripts/stdlib.lua | 2 +- src/content/ContentLoader.cpp | 15 +++++++++++---- src/objects/Entities.cpp | 2 +- src/objects/EntityDef.hpp | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json index cf9add8e..6f0e680a 100644 --- a/res/content/base/entities/drop.json +++ b/res/content/base/entities/drop.json @@ -1,6 +1,6 @@ { "hitbox": [0.2, 0.125, 0.2], "triggers": [ - [-0.2, -0.2, -0.2, 0.2, 0.2, 0.2] + ["aabb", -0.2, -0.2, -0.2, 0.2, 0.2, 0.2] ] } diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index ea49f0cb..88dd54f4 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -304,7 +304,7 @@ function file.readlines(path) end stdcomp = require "core:internal/stdcomp" -entity.get = stdcomp.get_Entity +entities.get = stdcomp.get_Entity -- Deprecated functions block_index = block.index diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 253434a9..80fbd9a4 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -12,6 +12,7 @@ #include "../logic/scripting/scripting.hpp" #include "../typedefs.hpp" #include "../util/listutil.hpp" +#include "../util/stringutil.hpp" #include "../voxels/Block.hpp" #include @@ -317,10 +318,16 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs if (auto triggersarr = root->list("triggers")) { for (size_t i = 0; i < triggersarr->size(); i++) { if (auto triggerarr = triggersarr->list(i)) { - def.triggers.push_back({ - {triggerarr->num(0), triggerarr->num(1), triggerarr->num(2)}, - {triggerarr->num(3), triggerarr->num(4), triggerarr->num(5)} - }); + auto triggerType = triggerarr->str(0); + if (triggerType == "aabb") { + def.boxTriggers.push_back({ + {triggerarr->num(1), triggerarr->num(2), triggerarr->num(3)}, + {triggerarr->num(4), triggerarr->num(5), triggerarr->num(6)} + }); + } else { + logger.error() << name << ": trigger #" << i << " - unknown type " + << util::quote(triggerType); + } } } } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 6e024427..0152063d 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -52,7 +52,7 @@ entityid_t Entities::spawn( registry.emplace(entity, pos, size, glm::mat3(1.0f)); auto& body = registry.emplace( entity, true, Hitbox {pos, def.hitbox}, std::vector{}); - for (auto& box : def.triggers) { + for (auto& box : def.boxTriggers) { body.triggers.emplace_back(Trigger{ true, id, diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index 5c4293c0..f4bf20d2 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -18,7 +18,7 @@ struct EntityDef { std::string scriptName = name.substr(name.find(':')+1); glm::vec3 hitbox {0.5f}; - std::vector triggers {}; + std::vector boxTriggers {}; std::string rigName = name.substr(name.find(":")+1); struct { From 39d850a48c0d985842049c3fb7d4706e29d83c26 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 03:33:39 +0300 Subject: [PATCH 054/178] add modeltree:set_texture --- res/content/base/scripts/components/drop.lua | 6 ++- res/modules/internal/stdcomp.lua | 1 + src/graphics/render/ModelBatch.cpp | 43 +++++++++++++++++--- src/graphics/render/ModelBatch.hpp | 19 +++++++-- src/logic/scripting/lua/libentity.cpp | 9 ++++ src/objects/rigging.cpp | 2 +- src/objects/rigging.hpp | 2 +- 7 files changed, 68 insertions(+), 14 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 6093a747..97167877 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -5,12 +5,14 @@ local rig = entity.modeltree inair = true ready = false -local item = ARGS.item +local dropitem = ARGS.item local rotation = mat4.rotate({0, 1, 0}, math.random() * 360) mat4.rotate(rotation, {1, 0, 0}, math.random() * 360, rotation) mat4.rotate(rotation, {0, 0, 1}, math.random() * 360, rotation) rig:set_matrix(0, rotation) +local icon = item.icon(dropitem.id) +rig:set_texture("$0", icon:gsub("block%-previews", "blocks"):gsub("base%:", "")) function on_grounded(force) rig:set_matrix(0, mat4.rotate({0, 1, 0}, math.random()*360)) @@ -25,7 +27,7 @@ end function on_trigger_enter(index, oid) if ready and oid == 0 then entity:despawn() - inventory.add(player.get_inventory(oid), item.id, item.count) + inventory.add(player.get_inventory(oid), dropitem.id, dropitem.count) audio.play_sound_2d("events/pickup", 0.5, 0.8+math.random()*0.4, "regular") end end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index b6e6f600..0e9e3baf 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -27,6 +27,7 @@ local Modeltree = {__index={ get_model=function(self, i) return __modeltree.get_model(self.eid, i) end, get_matrix=function(self, i) return __modeltree.get_matrix(self.eid, i) end, set_matrix=function(self, i, m) return __modeltree.set_matrix(self.eid, i, m) end, + set_texture=function(self, s, s2) return __modeltree.set_texture(self.eid, s, s2) end, }} function new_Modeltree(eid) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 00eb95a5..704e6be0 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -2,6 +2,7 @@ #include "../core/Mesh.hpp" #include "../core/Model.hpp" +#include "../core/Atlas.hpp" #include "../core/Texture.hpp" #include "../../assets/Assets.hpp" #include "../../window/Window.hpp" @@ -53,7 +54,9 @@ ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks) ModelBatch::~ModelBatch() { } -void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation) { +void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, + const glm::mat3& rotation, + const texture_names_map* varTextures) { glm::vec3 gpos = matrix * glm::vec4(glm::vec3(), 1.0f); light_t light = chunks->getLight(floor(gpos.x), floor(gpos.y), floor(gpos.z)); glm::vec4 lights ( @@ -62,7 +65,7 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const gl Lightmap::extract(light, 2) / 15.0f, Lightmap::extract(light, 3) / 15.0f ); - setTexture(assets->get(mesh.texture)); + setTexture(mesh.texture, varTextures); size_t vcount = mesh.vertices.size(); const auto& vertexData = mesh.vertices.data(); for (size_t i = 0; i < vcount / 3; i++) { @@ -70,7 +73,7 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const gl flush(); } for (size_t j = 0; j < 3; j++) { - const auto& vert = vertexData[i * 3 + j]; + const auto vert = vertexData[i * 3 + j]; auto norm = rotation * vert.normal; float d = glm::dot(norm, SUN_VECTOR); d = 0.8f + d * 0.2f; @@ -81,9 +84,10 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const gl } } -void ModelBatch::draw(const model::Model* model) { +void ModelBatch::draw(const model::Model* model, + const texture_names_map* varTextures) { for (const auto& mesh : model->meshes) { - entries.push_back({combined, rotation, &mesh}); + entries.push_back({combined, rotation, &mesh, varTextures}); } } @@ -94,7 +98,7 @@ void ModelBatch::render() { } ); for (auto& entry : entries) { - draw(*entry.mesh, entry.matrix, entry.rotation); + draw(*entry.mesh, entry.matrix, entry.rotation, entry.varTextures); } flush(); entries.clear(); @@ -114,6 +118,32 @@ void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) { plane(pos-X*size, Z*size, Y*size, -X, lights); } +void ModelBatch::setTexture(const std::string& name, + const texture_names_map* varTextures) { + if (name.at(0) == '$') { + const auto& found = varTextures->find(name); + if (found == varTextures->end()) { + return setTexture(nullptr); + } else { + return setTexture(found->second, varTextures); + } + } + size_t sep = name.find(':'); + if (sep == std::string::npos) { + setTexture(assets->get(name)); + } else { + auto atlas = assets->get(name.substr(0, sep)); + if (atlas == nullptr) { + setTexture(nullptr); + } else { + setTexture(atlas->getTexture()); + if (auto reg = atlas->getIf(name.substr(sep+1))) { + region = *reg; + } + } + } +} + void ModelBatch::setTexture(Texture* texture) { if (texture == nullptr) { texture = blank.get(); @@ -122,6 +152,7 @@ void ModelBatch::setTexture(Texture* texture) { flush(); } this->texture = texture; + region = UVRegion {0.0f, 0.0f, 1.0f, 1.0f}; } void ModelBatch::flush() { diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index ba6f1eed..7f3c7e91 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -1,9 +1,12 @@ #ifndef GRAPHICS_RENDER_MODEL_BATCH_HPP_ #define GRAPHICS_RENDER_MODEL_BATCH_HPP_ +#include "../../maths/UVRegion.hpp" + #include #include #include +#include class Mesh; class Texture; @@ -15,6 +18,8 @@ namespace model { struct Model; } +using texture_names_map = std::unordered_map; + class ModelBatch { std::unique_ptr const buffer; size_t const capacity; @@ -30,6 +35,7 @@ class ModelBatch { Assets* assets; Chunks* chunks; Texture* texture = nullptr; + UVRegion region {0.0f, 0.0f, 1.0f, 1.0f}; static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; @@ -40,8 +46,8 @@ class ModelBatch { buffer[index++] = pos.x; buffer[index++] = pos.y; buffer[index++] = pos.z; - buffer[index++] = uv.x; - buffer[index++] = uv.y; + buffer[index++] = uv.x * region.getWidth() + region.u1; + buffer[index++] = uv.y * region.getHeight() + region.v1; union { float floating; @@ -72,8 +78,11 @@ class ModelBatch { vertex(pos-right+up, {0,1}, color); } - void draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation); + void draw(const model::Mesh& mesh, const glm::mat4& matrix, + const glm::mat3& rotation, const texture_names_map* varTextures); void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights); + void setTexture(const std::string& name, + const texture_names_map* varTextures); void setTexture(Texture* texture); void flush(); @@ -81,6 +90,7 @@ class ModelBatch { glm::mat4 matrix; glm::mat3 rotation; const model::Mesh* mesh; + const texture_names_map* varTextures; }; std::vector entries; public: @@ -93,7 +103,8 @@ public: void pushMatrix(glm::mat4 matrix); void popMatrix(); - void draw(const model::Model* model); + void draw(const model::Model* model, + const texture_names_map* varTextures); void render(); }; diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 8f1dbf6a..5d55bd6a 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -148,6 +148,14 @@ static int l_modeltree_set_matrix(lua::State* L) { return 0; } +static int l_modeltree_set_texture(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + auto& rig = entity->getModeltree(); + rig.textures[lua::require_string(L, 2)] = lua::require_string(L, 3); + } + return 0; +} + const luaL_Reg entitylib [] = { {"exists", lua::wrap}, {"spawn", lua::wrap}, @@ -159,6 +167,7 @@ const luaL_Reg modeltreelib [] = { {"get_model", lua::wrap}, {"get_matrix", lua::wrap}, {"set_matrix", lua::wrap}, + {"set_texture", lua::wrap}, {NULL, NULL} }; diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index 04a90177..baadc8bf 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -78,7 +78,7 @@ void RigConfig::render( continue; } batch.pushMatrix(rig.calculated.matrices[i]); - batch.draw(model); + batch.draw(model, &rig.textures); batch.popMatrix(); } } diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index e79bcf01..797ec20e 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -64,7 +64,7 @@ namespace rigging { RigConfig* config; Pose pose; Pose calculated; - std::vector textures; + std::unordered_map textures; }; class RigConfig { From 8302bfe98e62a75914b13825d748c26cd5787203 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 04:11:57 +0300 Subject: [PATCH 055/178] fix msvc build --- src/graphics/render/ModelBatch.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index 7f3c7e91..576ed878 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include From 1c4e13dc67aab2b58d9829dc1da98ee1ca5f9b5b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 05:15:15 +0300 Subject: [PATCH 056/178] add block.get_textures --- res/content/base/scripts/components/drop.lua | 10 +++++++++- src/graphics/render/ModelBatch.cpp | 2 ++ src/logic/scripting/lua/libblock.cpp | 13 +++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 97167877..b55ff80b 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -12,7 +12,15 @@ mat4.rotate(rotation, {1, 0, 0}, math.random() * 360, rotation) mat4.rotate(rotation, {0, 0, 1}, math.random() * 360, rotation) rig:set_matrix(0, rotation) local icon = item.icon(dropitem.id) -rig:set_texture("$0", icon:gsub("block%-previews", "blocks"):gsub("base%:", "")) +if icon:find("^block%-previews%:") then + local bid = block.index(icon:sub(16)) + local textures = block.get_textures(bid) + for i,t in ipairs(textures) do + rig:set_texture("$"..tostring(i-1), "blocks:"..textures[i]) + end +else + rig:set_texture("$0", icon) +end function on_grounded(force) rig:set_matrix(0, mat4.rotate({0, 1, 0}, math.random()*360)) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 704e6be0..10e63d48 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -139,6 +139,8 @@ void ModelBatch::setTexture(const std::string& name, setTexture(atlas->getTexture()); if (auto reg = atlas->getIf(name.substr(sep+1))) { region = *reg; + } else { + setTexture("blocks:notfound", varTextures); } } } diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 4f2b3902..c9efe92e 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -259,6 +259,18 @@ static int l_caption(lua::State* L) { return 0; } +static int l_get_textures(lua::State* L) { + if (auto def = require_block(L)) { + lua::createtable(L, 6, 0); + for (size_t i = 0; i < 6; i++) { + lua::pushstring(L, def->textureFaces[i]); + lua::rawseti(L, i+1); + } + return 1; + } + return 0; +} + const luaL_Reg blocklib [] = { {"index", lua::wrap}, {"name", lua::wrap}, @@ -282,5 +294,6 @@ const luaL_Reg blocklib [] = { {"get_size", lua::wrap}, {"is_segment", lua::wrap}, {"seek_origin", lua::wrap}, + {"get_textures", lua::wrap}, {NULL, NULL} }; From 48b5be6bc9e8124432c22498f47f721bc9d9b4f5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 16:34:09 +0300 Subject: [PATCH 057/178] add drop-item model, new block functions --- .../base/models/{cube.obj => drop-block.obj} | 21 +++++++----- .../base/models/{item.obj => drop-item.obj} | 0 res/content/base/preload.json | 7 ++-- res/content/base/rigs/drop-item.json | 5 +++ res/content/base/rigs/drop.json | 2 +- res/content/base/scripts/components/drop.lua | 32 ++++++++++++------- res/modules/internal/stdcomp.lua | 1 + src/logic/scripting/lua/libblock.cpp | 14 ++++++++ src/logic/scripting/lua/libentity.cpp | 14 ++++++++ src/objects/Entities.cpp | 7 ++++ src/objects/Entities.hpp | 2 ++ 11 files changed, 81 insertions(+), 24 deletions(-) rename res/content/base/models/{cube.obj => drop-block.obj} (75%) rename res/content/base/models/{item.obj => drop-item.obj} (100%) create mode 100644 res/content/base/rigs/drop-item.json diff --git a/res/content/base/models/cube.obj b/res/content/base/models/drop-block.obj similarity index 75% rename from res/content/base/models/cube.obj rename to res/content/base/models/drop-block.obj index 969dad45..be4cf551 100644 --- a/res/content/base/models/cube.obj +++ b/res/content/base/models/drop-block.obj @@ -17,27 +17,32 @@ vt 1.0 1.0 vt 0.0 1.0 vt 1.0 0.0 vt 1.0 1.0 -vt 0.0 1.0 vt 0.0 0.0 vt 1.0 0.0 vt 0.0 1.0 vt 0.0 0.0 +vt 0.0 1.0 vt 1.0 0.0 vt 1.0 1.0 -vt 1.0 0.0 vt 1.0 1.0 vt 0.0 1.0 +vt 0.0 0.0 vn 0.0 -1.0 0.0 vn 0.0 1.0 0.0 vn 1.0 -0.0 0.0 -vn -0.0 -0.0 1.0 vn -1.0 -0.0 -0.0 vn 0.0 0.0 -1.0 -usemtl $0 +vn -0.0 -0.0 1.0 +usemtl $2 s off f 1/1/1 2/2/1 3/3/1 4/4/1 +usemtl $3 f 5/5/2 8/6/2 7/7/2 6/8/2 -f 1/1/3 5/9/3 6/10/3 2/11/3 -f 2/12/4 6/13/4 7/7/4 3/14/4 -f 3/15/5 7/16/5 8/17/5 4/4/5 -f 5/5/6 1/18/6 4/19/6 8/20/6 +usemtl $0 +f 1/9/3 5/10/3 6/8/3 2/11/3 +usemtl $1 +f 3/12/4 7/7/4 8/13/4 4/14/4 +usemtl $4 +f 5/15/5 1/1/5 4/16/5 8/17/5 +usemtl $5 +f 2/2/6 6/18/6 7/19/6 3/20/6 diff --git a/res/content/base/models/item.obj b/res/content/base/models/drop-item.obj similarity index 100% rename from res/content/base/models/item.obj rename to res/content/base/models/drop-item.obj diff --git a/res/content/base/preload.json b/res/content/base/preload.json index 6e9aa592..c8283103 100644 --- a/res/content/base/preload.json +++ b/res/content/base/preload.json @@ -5,10 +5,11 @@ "events/pickup" ], "models": [ - "cube", - "item" + "drop-block", + "drop-item" ], "rigs": [ - "drop" + "drop", + "drop-item" ] } diff --git a/res/content/base/rigs/drop-item.json b/res/content/base/rigs/drop-item.json new file mode 100644 index 00000000..18afe6a2 --- /dev/null +++ b/res/content/base/rigs/drop-item.json @@ -0,0 +1,5 @@ +{ + "root": { + "model": "drop-item" + } +} diff --git a/res/content/base/rigs/drop.json b/res/content/base/rigs/drop.json index 675759f7..530b400d 100644 --- a/res/content/base/rigs/drop.json +++ b/res/content/base/rigs/drop.json @@ -1,5 +1,5 @@ { "root": { - "model": "cube" + "model": "drop-block" } } diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index b55ff80b..8d579cf2 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -7,19 +7,27 @@ ready = false local dropitem = ARGS.item -local rotation = mat4.rotate({0, 1, 0}, math.random() * 360) -mat4.rotate(rotation, {1, 0, 0}, math.random() * 360, rotation) -mat4.rotate(rotation, {0, 0, 1}, math.random() * 360, rotation) -rig:set_matrix(0, rotation) -local icon = item.icon(dropitem.id) -if icon:find("^block%-previews%:") then - local bid = block.index(icon:sub(16)) - local textures = block.get_textures(bid) - for i,t in ipairs(textures) do - rig:set_texture("$"..tostring(i-1), "blocks:"..textures[i]) +do -- setup visuals + local rotation = mat4.rotate({0, 1, 0}, math.random() * 360) + mat4.rotate(rotation, {1, 0, 0}, math.random() * 360, rotation) + mat4.rotate(rotation, {0, 0, 1}, math.random() * 360, rotation) + rig:set_matrix(0, rotation) + local icon = item.icon(dropitem.id) + if icon:find("^block%-previews%:") then + local bid = block.index(icon:sub(16)) + if block.get_model(bid) == "X" then + entity:set_rig("drop-item") + rig:set_texture("$0", icon) + else + local textures = block.get_textures(bid) + for i,t in ipairs(textures) do + rig:set_texture("$"..tostring(i-1), "blocks:"..textures[i]) + end + end + else + entity:set_rig("drop-item") + rig:set_texture("$0", icon) end -else - rig:set_texture("$0", icon) end function on_grounded(force) diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 0e9e3baf..985604ee 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -38,6 +38,7 @@ end local Entity = {__index={ despawn=function(self) return entities.despawn(self.eid) end, + set_rig=function(self, s) return entities.set_rig(self.eid, s) end, }} local entities = {} diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index c9efe92e..5e70ba65 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -271,6 +271,19 @@ static int l_get_textures(lua::State* L) { return 0; } +static int l_get_model(lua::State* L) { + if (auto def = require_block(L)) { + switch (def->model) { + case BlockModel::block: return lua::pushstring(L, "block"); + case BlockModel::aabb: return lua::pushstring(L, "aabb"); + case BlockModel::xsprite: return lua::pushstring(L, "X"); + case BlockModel::custom: return lua::pushstring(L, "custom"); + case BlockModel::none: return lua::pushstring(L, "none"); + } + return 0; + } +} + const luaL_Reg blocklib [] = { {"index", lua::wrap}, {"name", lua::wrap}, @@ -295,5 +308,6 @@ const luaL_Reg blocklib [] = { {"is_segment", lua::wrap}, {"seek_origin", lua::wrap}, {"get_textures", lua::wrap}, + {"get_model", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 5d55bd6a..337d53ac 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -48,6 +48,19 @@ static int l_despawn(lua::State* L) { return 0; } +static int l_set_rig(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + auto assets = scripting::engine->getAssets(); + std::string rigName = lua::require_string(L, 2); + auto rigConfig = assets->get(rigName); + if (rigConfig == nullptr) { + throw std::runtime_error("rig not found '"+rigName+"'"); + } + entity->setRig(rigConfig); + } + return 0; +} + static int l_get_pos(lua::State* L) { if (auto entity = get_entity(L, 1)) { return lua::pushvec3_arr(L, entity->getTransform().pos); @@ -160,6 +173,7 @@ const luaL_Reg entitylib [] = { {"exists", lua::wrap}, {"spawn", lua::wrap}, {"despawn", lua::wrap}, + {"set_rig", lua::wrap}, {NULL, NULL} }; diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 0152063d..b1d1356a 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -32,6 +32,13 @@ rigging::Rig& Entity::getModeltree() const { return registry.get(entity); } +void Entity::setRig(rigging::RigConfig* rigConfig) { + auto& rig = registry.get(entity); + rig.config = rigConfig; + rig.pose.matrices.resize(rigConfig->getNodes().size(), glm::mat4(1.0f)); + rig.calculated.matrices.resize(rigConfig->getNodes().size(), glm::mat4(1.0f)); +} + Entities::Entities(Level* level) : level(level) { } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 953470fa..9b484fe1 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -115,6 +115,8 @@ public: rigging::Rig& getModeltree() const; + void setRig(rigging::RigConfig* rigConfig); + entityid_t getUID() const { return registry.get(entity).uid; } From 7c5f8107de13391b3bf21c211b3acd57e10e0751 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 17:46:03 +0300 Subject: [PATCH 058/178] update drop-item model --- res/content/base/models/drop-item.obj | 118 ++++++++++++++----- res/content/base/scripts/components/drop.lua | 2 + res/modules/internal/stdcomp.lua | 1 + src/logic/scripting/lua/libentity.cpp | 10 +- 4 files changed, 98 insertions(+), 33 deletions(-) diff --git a/res/content/base/models/drop-item.obj b/res/content/base/models/drop-item.obj index 58702e79..2bb32447 100644 --- a/res/content/base/models/drop-item.obj +++ b/res/content/base/models/drop-item.obj @@ -1,28 +1,52 @@ o Cube -v -0.282501 -0.015663 -0.282501 -v -0.282501 -0.015663 0.2825 -v 0.2825 -0.015663 0.282501 -v 0.282501 -0.015663 -0.2825 -v 0.282501 0.021634 -0.2825 -v 0.2825 0.021634 0.282501 -v -0.282501 0.021634 0.2825 -v -0.282501 0.021634 -0.282501 -v -0.282501 0.021634 -0.282501 -v -0.282501 0.021634 0.2825 -v 0.2825 0.021634 0.282501 -v 0.282501 0.021634 -0.2825 -v 0.282501 -0.015663 -0.2825 -v 0.2825 -0.015663 0.282501 -v -0.282501 -0.015663 0.2825 -v -0.282501 -0.015663 -0.282501 -v 0.282501 0.0284 -0.2825 -v 0.2825 0.0284 0.282501 -v -0.282501 0.0284 0.2825 -v -0.282501 0.0284 -0.282501 -v -0.282501 0.0284 -0.282501 -v -0.282501 0.0284 0.2825 -v 0.2825 0.0284 0.282501 -v 0.282501 0.0284 -0.2825 +v 0.282501 -0.01971 -0.28250 +v -0.282501 -0.01971 -0.282501 +v -0.282501 -0.01971 0.28250 +v 0.28250 -0.01971 0.282501 +v 0.282501 0.05986 -0.28250 +v -0.282501 0.05986 -0.282501 +v -0.282501 0.05986 0.28250 +v 0.28250 0.05986 0.282501 +v 0.282501 0.05986 -0.28250 +v 0.28250 0.05986 0.282501 +v -0.282501 0.05986 0.28250 +v -0.282501 0.05986 -0.282501 +v 0.282501 -0.01971 -0.28250 +v 0.28250 -0.01971 0.282501 +v -0.282501 -0.01971 0.28250 +v -0.282501 -0.01971 -0.282501 +v 0.282501 0.05986 -0.28250 +v -0.282501 0.05986 -0.282501 +v -0.282501 0.05986 0.28250 +v 0.28250 0.05986 0.282501 +v 0.282501 0.05986 -0.28250 +v 0.28250 0.05986 0.282501 +v -0.282501 0.05986 0.28250 +v -0.282501 0.05986 -0.282501 +v 0.282501 0.01156 -0.28250 +v -0.282501 0.01156 -0.282501 +v -0.282501 0.01156 0.28250 +v 0.28250 0.01156 0.282501 +v 0.282501 0.04422 -0.28250 +v -0.282501 0.04422 -0.282501 +v -0.282501 0.04422 0.28250 +v 0.28250 0.04422 0.282501 +v 0.282501 0.04422 -0.28250 +v 0.28250 0.04422 0.282501 +v -0.282501 0.04422 0.28250 +v -0.282501 0.04422 -0.282501 +v 0.282501 0.01156 -0.28250 +v 0.28250 0.01156 0.282501 +v -0.282501 0.01156 0.28250 +v -0.282501 0.01156 -0.282501 +v 0.282501 0.04422 -0.28250 +v -0.282501 0.04422 -0.282501 +v -0.282501 0.04422 0.28250 +v 0.28250 0.04422 0.282501 +v 0.282501 0.04422 -0.28250 +v 0.28250 0.04422 0.282501 +v -0.282501 0.04422 0.28250 +v -0.282501 0.04422 -0.282501 vt 0.0 0.0 vt 1.0 0.0 vt 1.0 1.0 @@ -47,13 +71,43 @@ vt 0.0 0.0 vt 0.0 1.0 vt 1.0 1.0 vt 1.0 0.0 -vn 0.0 1.0 0.0 -vn 0.0 -1.0 0.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 0.0 1.0 +vt 1.0 1.0 +vt 1.0 0.0 +vt 0.0 0.0 +vt 0.0 1.0 +vt 1.0 1.0 +vt 1.0 0.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +vt 0.0 0.0 +vt 0.0 1.0 +vt 1.0 1.0 +vt 1.0 0.0 +vn -0.0 1.0 0.0 +vn 0.0 -1.0 -0.0 usemtl $0 -s off -f 4/1/1 1/2/1 2/3/1 3/4/1 -f 5/5/1 8/6/1 7/7/1 6/8/1 -f 12/9/2 11/10/2 10/11/2 9/12/2 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/1 6/6/1 7/7/1 8/8/1 +f 9/9/2 10/10/2 11/11/2 12/12/2 f 13/13/2 14/14/2 15/15/2 16/16/2 -f 17/17/1 20/18/1 19/19/1 18/20/1 -f 24/21/2 23/22/2 22/23/2 21/24/2 +f 17/17/1 18/18/1 19/19/1 20/20/1 +f 21/21/2 22/22/2 23/23/2 24/24/2 +f 25/25/1 26/26/1 27/27/1 28/28/1 +f 29/29/1 30/30/1 31/31/1 32/32/1 +f 33/33/2 34/34/2 35/35/2 36/36/2 +f 37/37/2 38/38/2 39/39/2 40/40/2 +f 41/41/1 42/42/1 43/43/1 44/44/1 +f 45/45/2 46/46/2 47/47/2 48/48/2 diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 8d579cf2..fe67ad70 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -17,6 +17,7 @@ do -- setup visuals local bid = block.index(icon:sub(16)) if block.get_model(bid) == "X" then entity:set_rig("drop-item") + body:set_size(vec3.mul(body:get_size(), {1.0, 0.3, 1.0})) rig:set_texture("$0", icon) else local textures = block.get_textures(bid) @@ -26,6 +27,7 @@ do -- setup visuals end else entity:set_rig("drop-item") + body:set_size(vec3.mul(body:get_size(), {1.0, 0.3, 1.0})) rig:set_texture("$0", icon) end end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 985604ee..a7b4f13d 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -17,6 +17,7 @@ local Rigidbody = {__index={ get_vel=function(self) return __rigidbody.get_vel(self.eid) end, set_vel=function(self, v) return __rigidbody.set_vel(self.eid, v) end, get_size=function(self) return __rigidbody.get_size(self.eid) end, + set_size=function(self, v) return __rigidbody.set_size(self.eid, v) end, }} function new_Rigidbody(eid) diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 337d53ac..68eec78c 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -119,7 +119,14 @@ static int l_set_enabled(lua::State* L) { static int l_get_size(lua::State* L) { if (auto entity = get_entity(L, 1)) { - return lua::pushvec3(L, entity->getRigidbody().hitbox.halfsize * 2.0f); + return lua::pushvec3_arr(L, entity->getRigidbody().hitbox.halfsize * 2.0f); + } + return 0; +} + +static int l_set_size(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + entity->getRigidbody().hitbox.halfsize = lua::tovec3(L, 2) * 0.5f; } return 0; } @@ -199,5 +206,6 @@ const luaL_Reg rigidbodylib [] = { {"get_vel", lua::wrap}, {"set_vel", lua::wrap}, {"get_size", lua::wrap}, + {"set_size", lua::wrap}, {NULL, NULL} }; From e5f2a3e87d43f2d738d6535732071e95810a2be4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 17:50:25 +0300 Subject: [PATCH 059/178] update drop-item.obj --- res/content/base/models/drop-item.obj | 96 +++++++++++++-------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/res/content/base/models/drop-item.obj b/res/content/base/models/drop-item.obj index 2bb32447..dc77a3e9 100644 --- a/res/content/base/models/drop-item.obj +++ b/res/content/base/models/drop-item.obj @@ -1,52 +1,52 @@ o Cube -v 0.282501 -0.01971 -0.28250 -v -0.282501 -0.01971 -0.282501 -v -0.282501 -0.01971 0.28250 -v 0.28250 -0.01971 0.282501 -v 0.282501 0.05986 -0.28250 -v -0.282501 0.05986 -0.282501 -v -0.282501 0.05986 0.28250 -v 0.28250 0.05986 0.282501 -v 0.282501 0.05986 -0.28250 -v 0.28250 0.05986 0.282501 -v -0.282501 0.05986 0.28250 -v -0.282501 0.05986 -0.282501 -v 0.282501 -0.01971 -0.28250 -v 0.28250 -0.01971 0.282501 -v -0.282501 -0.01971 0.28250 -v -0.282501 -0.01971 -0.282501 -v 0.282501 0.05986 -0.28250 -v -0.282501 0.05986 -0.282501 -v -0.282501 0.05986 0.28250 -v 0.28250 0.05986 0.282501 -v 0.282501 0.05986 -0.28250 -v 0.28250 0.05986 0.282501 -v -0.282501 0.05986 0.28250 -v -0.282501 0.05986 -0.282501 -v 0.282501 0.01156 -0.28250 -v -0.282501 0.01156 -0.282501 -v -0.282501 0.01156 0.28250 -v 0.28250 0.01156 0.282501 -v 0.282501 0.04422 -0.28250 -v -0.282501 0.04422 -0.282501 -v -0.282501 0.04422 0.28250 -v 0.28250 0.04422 0.282501 -v 0.282501 0.04422 -0.28250 -v 0.28250 0.04422 0.282501 -v -0.282501 0.04422 0.28250 -v -0.282501 0.04422 -0.282501 -v 0.282501 0.01156 -0.28250 -v 0.28250 0.01156 0.282501 -v -0.282501 0.01156 0.28250 -v -0.282501 0.01156 -0.282501 -v 0.282501 0.04422 -0.28250 -v -0.282501 0.04422 -0.282501 -v -0.282501 0.04422 0.28250 -v 0.28250 0.04422 0.282501 -v 0.282501 0.04422 -0.28250 -v 0.28250 0.04422 0.282501 -v -0.282501 0.04422 0.28250 -v -0.282501 0.04422 -0.282501 +v 0.282501 -0.014771 -0.28250 +v -0.282501 -0.014771 -0.282501 +v -0.282501 -0.014771 0.28250 +v 0.28250 -0.014771 0.282501 +v 0.282501 0.015019 -0.28250 +v -0.282501 0.015019 -0.282501 +v -0.282501 0.015019 0.28250 +v 0.28250 0.015019 0.282501 +v 0.282501 0.015019 -0.28250 +v 0.28250 0.015019 0.282501 +v -0.282501 0.015019 0.28250 +v -0.282501 0.015019 -0.282501 +v 0.282501 -0.014771 -0.28250 +v 0.28250 -0.014771 0.282501 +v -0.282501 -0.014771 0.28250 +v -0.282501 -0.014771 -0.282501 +v 0.282501 0.015019 -0.28250 +v -0.282501 0.015019 -0.282501 +v -0.282501 0.015019 0.28250 +v 0.28250 0.015019 0.282501 +v 0.282501 0.015019 -0.28250 +v 0.28250 0.015019 0.282501 +v -0.282501 0.015019 0.28250 +v -0.282501 0.015019 -0.282501 +v 0.282501 -0.05218 -0.28250 +v -0.282501 -0.05218 -0.282501 +v -0.282501 -0.05218 0.28250 +v 0.28250 -0.05218 0.282501 +v 0.282501 0.05046 -0.28250 +v -0.282501 0.05046 -0.282501 +v -0.282501 0.05046 0.28250 +v 0.28250 0.05046 0.282501 +v 0.282501 0.05046 -0.28250 +v 0.28250 0.05046 0.282501 +v -0.282501 0.05046 0.28250 +v -0.282501 0.05046 -0.282501 +v 0.282501 -0.05218 -0.28250 +v 0.28250 -0.05218 0.282501 +v -0.282501 -0.05218 0.28250 +v -0.282501 -0.05218 -0.282501 +v 0.282501 0.05046 -0.28250 +v -0.282501 0.05046 -0.282501 +v -0.282501 0.05046 0.28250 +v 0.28250 0.05046 0.282501 +v 0.282501 0.05046 -0.28250 +v 0.28250 0.05046 0.282501 +v -0.282501 0.05046 0.28250 +v -0.282501 0.05046 -0.282501 vt 0.0 0.0 vt 1.0 0.0 vt 1.0 1.0 From fa450c1c15b4517f4ca0db13946f8cecb4c6350c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 18:27:30 +0300 Subject: [PATCH 060/178] fix drop-item.obj --- res/content/base/models/drop-item.obj | 196 +++++++++++++------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/res/content/base/models/drop-item.obj b/res/content/base/models/drop-item.obj index dc77a3e9..a12cca01 100644 --- a/res/content/base/models/drop-item.obj +++ b/res/content/base/models/drop-item.obj @@ -1,102 +1,102 @@ o Cube -v 0.282501 -0.014771 -0.28250 -v -0.282501 -0.014771 -0.282501 -v -0.282501 -0.014771 0.28250 -v 0.28250 -0.014771 0.282501 -v 0.282501 0.015019 -0.28250 -v -0.282501 0.015019 -0.282501 -v -0.282501 0.015019 0.28250 -v 0.28250 0.015019 0.282501 -v 0.282501 0.015019 -0.28250 -v 0.28250 0.015019 0.282501 -v -0.282501 0.015019 0.28250 -v -0.282501 0.015019 -0.282501 -v 0.282501 -0.014771 -0.28250 -v 0.28250 -0.014771 0.282501 -v -0.282501 -0.014771 0.28250 -v -0.282501 -0.014771 -0.282501 -v 0.282501 0.015019 -0.28250 -v -0.282501 0.015019 -0.282501 -v -0.282501 0.015019 0.28250 -v 0.28250 0.015019 0.282501 -v 0.282501 0.015019 -0.28250 -v 0.28250 0.015019 0.282501 -v -0.282501 0.015019 0.28250 -v -0.282501 0.015019 -0.282501 -v 0.282501 -0.05218 -0.28250 -v -0.282501 -0.05218 -0.282501 -v -0.282501 -0.05218 0.28250 -v 0.28250 -0.05218 0.282501 -v 0.282501 0.05046 -0.28250 -v -0.282501 0.05046 -0.282501 -v -0.282501 0.05046 0.28250 -v 0.28250 0.05046 0.282501 -v 0.282501 0.05046 -0.28250 -v 0.28250 0.05046 0.282501 -v -0.282501 0.05046 0.28250 -v -0.282501 0.05046 -0.282501 -v 0.282501 -0.05218 -0.28250 -v 0.28250 -0.05218 0.282501 -v -0.282501 -0.05218 0.28250 -v -0.282501 -0.05218 -0.282501 -v 0.282501 0.05046 -0.28250 -v -0.282501 0.05046 -0.282501 -v -0.282501 0.05046 0.28250 -v 0.28250 0.05046 0.282501 -v 0.282501 0.05046 -0.28250 -v 0.28250 0.05046 0.282501 -v -0.282501 0.05046 0.28250 -v -0.282501 0.05046 -0.282501 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 0.0 1.0 -vt 1.0 1.0 -vt 1.0 0.0 -vt 0.0 0.0 -vt 0.0 1.0 -vt 1.0 1.0 -vt 1.0 0.0 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 0.0 1.0 -vt 1.0 1.0 -vt 1.0 0.0 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 0.0 1.0 -vt 1.0 1.0 -vt 1.0 0.0 -vt 0.0 0.0 -vt 0.0 1.0 -vt 1.0 1.0 -vt 1.0 0.0 -vt 0.0 0.0 -vt 1.0 0.0 -vt 1.0 1.0 -vt 0.0 1.0 -vt 0.0 0.0 -vt 0.0 1.0 -vt 1.0 1.0 -vt 1.0 0.0 -vn -0.0 1.0 0.0 -vn 0.0 -1.0 -0.0 +v 0.282501 -0.000054 -0.282500 +v -0.282501 -0.000054 -0.282501 +v -0.282501 -0.000054 0.282500 +v 0.282500 -0.000054 0.282501 +v 0.282501 0.012502 -0.282500 +v -0.282501 0.012502 -0.282501 +v -0.282501 0.012502 0.282500 +v 0.282500 0.012502 0.282501 +v 0.282501 0.012502 -0.282500 +v 0.282500 0.012502 0.282501 +v -0.282501 0.012502 0.282500 +v -0.282501 0.012502 -0.282501 +v 0.282501 -0.000054 -0.282500 +v 0.282500 -0.000054 0.282501 +v -0.282501 -0.000054 0.282500 +v -0.282501 -0.000054 -0.282501 +v 0.282501 0.012502 -0.282500 +v -0.282501 0.012502 -0.282501 +v -0.282501 0.012502 0.282500 +v 0.282500 0.012502 0.282501 +v 0.282501 0.012502 -0.282500 +v 0.282500 0.012502 0.282501 +v -0.282501 0.012502 0.282500 +v -0.282501 0.012502 -0.282501 +v 0.282501 -0.015821 -0.282500 +v -0.282501 -0.015821 -0.282501 +v -0.282501 -0.015821 0.282500 +v 0.282500 -0.015821 0.282501 +v 0.282501 0.027439 -0.282500 +v -0.282501 0.027439 -0.282501 +v -0.282501 0.027439 0.282500 +v 0.282500 0.027439 0.282501 +v 0.282501 0.027439 -0.282500 +v 0.282500 0.027439 0.282501 +v -0.282501 0.027439 0.282500 +v -0.282501 0.027439 -0.282501 +v 0.282501 -0.015821 -0.282500 +v 0.282500 -0.015821 0.282501 +v -0.282501 -0.015821 0.282500 +v -0.282501 -0.015821 -0.282501 +v 0.282501 0.027439 -0.282500 +v -0.282501 0.027439 -0.282501 +v -0.282501 0.027439 0.282500 +v 0.282500 0.027439 0.282501 +v 0.282501 0.027439 -0.282500 +v 0.282500 0.027439 0.282501 +v -0.282501 0.027439 0.282500 +v -0.282501 0.027439 -0.282501 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vn -0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 -0.0000 usemtl $0 s 1 f 1/1/1 2/2/1 3/3/1 4/4/1 From 4b084dffad163ef5ac67e738c87dba554a10daa8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 19:21:05 +0300 Subject: [PATCH 061/178] add aabb drop models support --- res/content/base/scripts/components/drop.lua | 32 ++++++++++++++------ src/logic/scripting/lua/libblock.cpp | 18 ++++++++++- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index fe67ad70..e6466b2a 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -6,20 +6,25 @@ inair = true ready = false local dropitem = ARGS.item +local scale = {1, 1, 1} +local rotation = mat4.rotate({ + math.random(), math.random(), math.random() +}, 360) do -- setup visuals - local rotation = mat4.rotate({0, 1, 0}, math.random() * 360) - mat4.rotate(rotation, {1, 0, 0}, math.random() * 360, rotation) - mat4.rotate(rotation, {0, 0, 1}, math.random() * 360, rotation) - rig:set_matrix(0, rotation) + local matrix = mat4.idt() local icon = item.icon(dropitem.id) if icon:find("^block%-previews%:") then local bid = block.index(icon:sub(16)) - if block.get_model(bid) == "X" then + local model = block.get_model(bid) + if model == "X" then entity:set_rig("drop-item") body:set_size(vec3.mul(body:get_size(), {1.0, 0.3, 1.0})) rig:set_texture("$0", icon) else + if model == "aabb" then + scale = block.get_hitbox(bid, 0)[2] + end local textures = block.get_textures(bid) for i,t in ipairs(textures) do rig:set_texture("$"..tostring(i-1), "blocks:"..textures[i]) @@ -30,10 +35,15 @@ do -- setup visuals body:set_size(vec3.mul(body:get_size(), {1.0, 0.3, 1.0})) rig:set_texture("$0", icon) end + mat4.mul(matrix, rotation, matrix) + mat4.scale(matrix, scale, matrix) + rig:set_matrix(0, matrix) end function on_grounded(force) - rig:set_matrix(0, mat4.rotate({0, 1, 0}, math.random()*360)) + local matrix = mat4.rotate({0, 1, 0}, math.random()*360) + mat4.scale(matrix, scale, matrix) + rig:set_matrix(0, matrix) inair = false ready = true end @@ -53,9 +63,13 @@ end function on_update() if inair then local dt = time.delta(); - local matrix = rig:get_matrix(0) - mat4.rotate(matrix, {0, 1, 0}, 240*dt, matrix) - mat4.rotate(matrix, {0, 0, 1}, 240*dt, matrix) + + mat4.rotate(rotation, {0, 1, 0}, 240*dt, rotation) + mat4.rotate(rotation, {0, 0, 1}, 240*dt, rotation) + + local matrix = mat4.idt() + mat4.mul(matrix, rotation, matrix) + mat4.scale(matrix, scale, matrix) rig:set_matrix(0, matrix) end end diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 5e70ba65..1527babb 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -280,8 +280,23 @@ static int l_get_model(lua::State* L) { case BlockModel::custom: return lua::pushstring(L, "custom"); case BlockModel::none: return lua::pushstring(L, "none"); } - return 0; } + return 0; +} + +static int l_get_hitbox(lua::State* L) { + if (auto def = require_block(L)) { + auto& hitbox = def->rt.hitboxes[0].at(lua::tointeger(L, 2)); + lua::createtable(L, 2, 0); + + lua::pushvec3_arr(L, hitbox.min()); + lua::rawseti(L, 1); + + lua::pushvec3_arr(L, hitbox.size()); + lua::rawseti(L, 2); + return 1; + } + return 0; } const luaL_Reg blocklib [] = { @@ -309,5 +324,6 @@ const luaL_Reg blocklib [] = { {"seek_origin", lua::wrap}, {"get_textures", lua::wrap}, {"get_model", lua::wrap}, + {"get_hitbox", lua::wrap}, {NULL, NULL} }; From e6c3775286e2c28ad8a7df20ff8c305a493eed06 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 21:09:38 +0300 Subject: [PATCH 062/178] improve drop visuals --- res/content/base/scripts/components/drop.lua | 15 +++++++++++---- src/logic/scripting/lua/libblock.cpp | 10 +++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index e6466b2a..3adc5760 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -16,14 +16,17 @@ do -- setup visuals local icon = item.icon(dropitem.id) if icon:find("^block%-previews%:") then local bid = block.index(icon:sub(16)) - local model = block.get_model(bid) + model = block.get_model(bid) if model == "X" then entity:set_rig("drop-item") body:set_size(vec3.mul(body:get_size(), {1.0, 0.3, 1.0})) rig:set_texture("$0", icon) else if model == "aabb" then - scale = block.get_hitbox(bid, 0)[2] + local rot = block.get_rotation_profile(bid) == "pipe" and 4 or 0 + scale = block.get_hitbox(bid, rot)[2] + body:set_size(vec3.mul(body:get_size(), {1.0, 0.7, 1.0})) + vec3.mul(scale, 1.5, scale) end local textures = block.get_textures(bid) for i,t in ipairs(textures) do @@ -41,7 +44,11 @@ do -- setup visuals end function on_grounded(force) - local matrix = mat4.rotate({0, 1, 0}, math.random()*360) + local matrix = mat4.idt() + mat4.rotate(matrix, {0, 1, 0}, math.random()*360, matrix) + if model == "aabb" then + mat4.rotate(matrix, {1, 0, 0}, 90, matrix) + end mat4.scale(matrix, scale, matrix) rig:set_matrix(0, matrix) inair = false @@ -66,7 +73,7 @@ function on_update() mat4.rotate(rotation, {0, 1, 0}, 240*dt, rotation) mat4.rotate(rotation, {0, 0, 1}, 240*dt, rotation) - + local matrix = mat4.idt() mat4.mul(matrix, rotation, matrix) mat4.scale(matrix, scale, matrix) diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 1527babb..ce54b258 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -286,7 +286,7 @@ static int l_get_model(lua::State* L) { static int l_get_hitbox(lua::State* L) { if (auto def = require_block(L)) { - auto& hitbox = def->rt.hitboxes[0].at(lua::tointeger(L, 2)); + auto& hitbox = def->rt.hitboxes[lua::tointeger(L, 2)].at(0); lua::createtable(L, 2, 0); lua::pushvec3_arr(L, hitbox.min()); @@ -299,6 +299,13 @@ static int l_get_hitbox(lua::State* L) { return 0; } +static int l_get_rotation_profile(lua::State* L) { + if (auto def = require_block(L)) { + return lua::pushstring(L, def->rotations.name); + } + return 0; +} + const luaL_Reg blocklib [] = { {"index", lua::wrap}, {"name", lua::wrap}, @@ -325,5 +332,6 @@ const luaL_Reg blocklib [] = { {"get_textures", lua::wrap}, {"get_model", lua::wrap}, {"get_hitbox", lua::wrap}, + {"get_rotation_profile", lua::wrap}, {NULL, NULL} }; From 736e5b95b6240af9196b66b053c2558d1dbdd26b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 4 Jul 2024 06:09:29 +0300 Subject: [PATCH 063/178] add radial triggers --- res/content/base/entities/drop.json | 3 +- res/content/base/scripts/components/drop.lua | 18 ++++- res/content/base/scripts/hud.lua | 1 - src/content/ContentLoader.cpp | 6 +- src/maths/aabb.hpp | 2 +- src/objects/Entities.cpp | 75 +++++++++++++------- src/objects/EntityDef.hpp | 3 +- src/physics/Hitbox.hpp | 25 +++++-- src/physics/PhysicsSolver.cpp | 28 ++++++-- 9 files changed, 117 insertions(+), 44 deletions(-) diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json index 6f0e680a..e158ddcb 100644 --- a/res/content/base/entities/drop.json +++ b/res/content/base/entities/drop.json @@ -1,6 +1,7 @@ { "hitbox": [0.2, 0.125, 0.2], "triggers": [ - ["aabb", -0.2, -0.2, -0.2, 0.2, 0.2, 0.2] + ["aabb", -0.2, -0.2, -0.2, 0.2, 0.2, 0.2], + ["radius", 1.6] ] } diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 3adc5760..a68fb463 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -4,6 +4,7 @@ local rig = entity.modeltree inair = true ready = false +target = -1 local dropitem = ARGS.item local scale = {1, 1, 1} @@ -60,11 +61,20 @@ function on_fall() end function on_trigger_enter(index, oid) - if ready and oid == 0 then + if ready and oid == 0 and index == 0 then entity:despawn() inventory.add(player.get_inventory(oid), dropitem.id, dropitem.count) audio.play_sound_2d("events/pickup", 0.5, 0.8+math.random()*0.4, "regular") end + if index == 1 and ready and oid == 0 then + target = oid + end +end + +function on_trigger_exit(index, oid) + if oid == target and index == 1 then + target = -1 + end end function on_update() @@ -79,4 +89,10 @@ function on_update() mat4.scale(matrix, scale, matrix) rig:set_matrix(0, matrix) end + if target ~= -1 then + local dir = vec3.sub({player.get_pos(target)}, tsf:get_pos()) + vec3.normalize(dir, dir) + vec3.mul(dir, 10.0, dir) + body:set_vel(dir) + end end diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 4a3af9cb..553e9945 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -14,7 +14,6 @@ function on_hud_open() local pvel = {player.get_vel(pid)} local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) - local drop = entities.spawn("base:drop", ppos, {item={ id=itemid, count=1 diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 80fbd9a4..f363702a 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -320,10 +320,12 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs if (auto triggerarr = triggersarr->list(i)) { auto triggerType = triggerarr->str(0); if (triggerType == "aabb") { - def.boxTriggers.push_back({ + def.boxTriggers.push_back({i, { {triggerarr->num(1), triggerarr->num(2), triggerarr->num(3)}, {triggerarr->num(4), triggerarr->num(5), triggerarr->num(6)} - }); + }}); + } else if (triggerType == "radius") { + def.radialTriggers.push_back({i, triggerarr->num(1)}); } else { logger.error() << name << ": trigger #" << i << " - unknown type " << util::quote(triggerType); diff --git a/src/maths/aabb.hpp b/src/maths/aabb.hpp index 7859ef65..38c829ce 100644 --- a/src/maths/aabb.hpp +++ b/src/maths/aabb.hpp @@ -8,7 +8,7 @@ struct AABB { glm::vec3 a {0.0f}; glm::vec3 b {1.0f, 1.0f, 1.0f}; - AABB() {} + AABB() = default; AABB(glm::vec3 size) : a(0.0f), b(size) { } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index b1d1356a..058e3ec4 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -42,6 +42,17 @@ void Entity::setRig(rigging::RigConfig* rigConfig) { Entities::Entities(Level* level) : level(level) { } +template +static triggercallback create_trigger_callback(Entities* entities) { + return [=](auto entityid, auto index, auto otherid) { + if (auto entity = entities->get(entityid)) { + if (entity->isValid()) { + callback(*entity, index, otherid); + } + } + }; +} + entityid_t Entities::spawn( Assets* assets, EntityDef& def, @@ -59,28 +70,25 @@ entityid_t Entities::spawn( registry.emplace(entity, pos, size, glm::mat3(1.0f)); auto& body = registry.emplace( entity, true, Hitbox {pos, def.hitbox}, std::vector{}); - for (auto& box : def.boxTriggers) { - body.triggers.emplace_back(Trigger{ - true, - id, - box, - AABB{}, - {}, - {}, - [=](auto entityid, auto index, auto otherid) { - if (auto entity = get(entityid)) { - if (entity->isValid()) { - scripting::on_trigger_enter(*entity, index, otherid); - } - } - }, - [=](auto entityid, auto index, auto otherid) { - if (auto entity = get(entityid)) { - if (entity->isValid()) { - scripting::on_trigger_exit(*entity, index, otherid); - } - } - }}); + + body.triggers.resize(def.radialTriggers.size() + def.boxTriggers.size()); + for (auto& [i, box] : def.boxTriggers) { + TriggerParams params {}; + params.aabb = box; + body.triggers[i] = Trigger { + true, TriggerType::AABB, i, id, params, params, {}, {}, + create_trigger_callback(this), + create_trigger_callback(this) + }; + } + for (auto& [i, radius] : def.radialTriggers) { + TriggerParams params {}; + params.radial = glm::vec4(radius); + body.triggers[i] = Trigger { + true, TriggerType::RADIUS, i, id, params, params, {}, {}, + create_trigger_callback(this), + create_trigger_callback(this) + }; } auto& scripting = registry.emplace( entity, entity_funcs_set {}, nullptr); @@ -135,8 +143,21 @@ void Entities::preparePhysics() { } trigger.prevEntered = trigger.nextEntered; trigger.nextEntered.clear(); - trigger.calculated = trigger.aabb; - trigger.calculated.transform(transform.combined); + + switch (trigger.type) { + case TriggerType::AABB: + trigger.calculated.aabb = trigger.params.aabb; + trigger.calculated.aabb.transform(transform.combined); + break; + case TriggerType::RADIUS: + trigger.calculated.radial = glm::vec4( + rigidbody.hitbox.position.x, + rigidbody.hitbox.position.y, + rigidbody.hitbox.position.z, + trigger.params.radial.w* + trigger.params.radial.w); + break; + } triggers.push_back(&trigger); } } @@ -204,9 +225,11 @@ void Entities::renderDebug(LineBatch& batch, const Frustum& frustum) { batch.box(hitbox.position, hitbox.halfsize * 2.0f, glm::vec4(1.0f)); for (auto& trigger : rigidbody.triggers) { + if (trigger.type != TriggerType::AABB) + continue; batch.box( - trigger.calculated.center(), - trigger.calculated.size(), + trigger.calculated.aabb.center(), + trigger.calculated.aabb.size(), glm::vec4(1.0f, 1.0f, 0.0f, 1.0f)); } } diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index f4bf20d2..a1044387 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -18,7 +18,8 @@ struct EntityDef { std::string scriptName = name.substr(name.find(':')+1); glm::vec3 hitbox {0.5f}; - std::vector boxTriggers {}; + std::vector> boxTriggers {}; + std::vector> radialTriggers {}; std::string rigName = name.substr(name.find(":")+1); struct { diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index 5090d7dc..5c0f9933 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -8,15 +8,32 @@ #include #include +enum class TriggerType { + AABB, + RADIUS, +}; + +union TriggerParams { + AABB aabb; + glm::vec4 radial; // x,y,z calculated entity coords + w - radius + + constexpr TriggerParams() : aabb() { + } +}; + +using triggercallback = std::function; + struct Trigger { bool enabled = true; + TriggerType type; + size_t index; entityid_t entity; - AABB aabb; - AABB calculated; + TriggerParams params; + TriggerParams calculated; std::set prevEntered; std::set nextEntered; - std::function enterCallback; - std::function exitCallback; + triggercallback enterCallback; + triggercallback exitCallback; }; struct Hitbox { diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 96f66ba2..3057d587 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -7,13 +7,15 @@ #include "../voxels/voxel.hpp" #include +#define GLM_ENABLE_EXPERIMENTAL +#include const float E = 0.03f; const float MAX_FIX = 0.1f; PhysicsSolver::PhysicsSolver(glm::vec3 gravity) : gravity(gravity) { } -#include "../util/timeutil.hpp" + void PhysicsSolver::step( Chunks* chunks, Hitbox* hitbox, @@ -85,15 +87,27 @@ void PhysicsSolver::step( aabb.a = hitbox->position - hitbox->halfsize; aabb.b = hitbox->position + hitbox->halfsize; for (size_t i = 0; i < triggers.size(); i++) { - auto& trigger = triggers[i]; - if (trigger->entity == entity) { + auto& trigger = *triggers[i]; + if (trigger.entity == entity) { continue; } - if (aabb.intersect(trigger->calculated)) { - if (trigger->prevEntered.find(entity) == trigger->prevEntered.end()) { - trigger->enterCallback(trigger->entity, i, entity); + + bool triggered = false; + switch (trigger.type) { + case TriggerType::AABB: + triggered = aabb.intersect(trigger.calculated.aabb); + break; + case TriggerType::RADIUS: + triggered = glm::distance2( + hitbox->position, glm::vec3(trigger.calculated.radial)) + < trigger.calculated.radial.w; + break; + } + if (triggered) { + if (trigger.prevEntered.find(entity) == trigger.prevEntered.end()) { + trigger.enterCallback(trigger.entity, trigger.index, entity); } - trigger->nextEntered.insert(entity); + trigger.nextEntered.insert(entity); } } } From a6aa42a5211ec504623dc475b973549652685da1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 4 Jul 2024 06:18:11 +0300 Subject: [PATCH 064/178] add transform:get_size(), :set_size(...) --- res/modules/internal/stdcomp.lua | 2 ++ src/logic/scripting/lua/libentity.cpp | 2 ++ src/objects/Entities.hpp | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index a7b4f13d..71976711 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -3,6 +3,8 @@ local Transform = {__index={ get_pos=function(self) return __transform.get_pos(self.eid) end, set_pos=function(self, v) return __transform.set_pos(self.eid, v) end, + get_size=function(self) return __transform.get_size(self.eid) end, + set_size=function(self, v) return __transform.set_size(self.eid, v) end, get_rot=function(self) return __transform.get_rot(self.eid) end, set_rot=function(self, m) return __transform.set_rot(self.eid, m) end, }} diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 68eec78c..224c112f 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -195,6 +195,8 @@ const luaL_Reg modeltreelib [] = { const luaL_Reg transformlib [] = { {"get_pos", lua::wrap}, {"set_pos", lua::wrap}, + {"get_size", lua::wrap}, + {"set_size", lua::wrap}, {"get_rot", lua::wrap}, {"set_rot", lua::wrap}, {NULL, NULL} diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 9b484fe1..58ceb7f5 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -44,6 +44,13 @@ struct Transform { dirty = true; } + inline void setSize(glm::vec3 v) { + if (glm::distance2(size, v) >= 0.0000001f) { + dirty = true; + } + size = v; + } + inline void setPos(glm::vec3 v) { if (glm::distance2(pos, v) >= 0.00001f) { dirty = true; From 8f379f2ee7d029ccec42d88e1ade7ccbbc7fa78a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 4 Jul 2024 19:47:52 +0300 Subject: [PATCH 065/178] feat: multiple components per entity support --- res/content/base/entities/drop.json | 3 + res/modules/internal/stdcomp.lua | 15 ++-- src/content/ContentLoader.cpp | 15 ++-- src/logic/scripting/scripting.cpp | 107 +++++++++++++++++----------- src/logic/scripting/scripting.hpp | 10 +-- src/objects/Entities.cpp | 11 +-- src/objects/Entities.hpp | 21 +++++- src/objects/EntityDef.hpp | 3 +- 8 files changed, 120 insertions(+), 65 deletions(-) diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json index e158ddcb..0be03b85 100644 --- a/res/content/base/entities/drop.json +++ b/res/content/base/entities/drop.json @@ -1,4 +1,7 @@ { + "components": [ + "drop" + ], "hitbox": [0.2, 0.125, 0.2], "triggers": [ ["aabb", -0.2, -0.2, -0.2, 0.2, 0.2, 0.2], diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 71976711..a87b0a6e 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -53,6 +53,7 @@ return { entity.rigidbody = new_Rigidbody(eid) entity.modeltree = new_Modeltree(eid) entity.data = {} + entity.components = {} entities[eid] = entity; return entity end, @@ -62,17 +63,19 @@ return { remove_Entity = function(eid) local entity = entities[eid] if entity then - entity.env = nil + entity.components = nil entities[eid] = nil; end end, update = function() for id,entity in pairs(entities) do - local callback = entity.env.on_update - if callback then - local result, err = pcall(callback) - if err then - print(err) + for _, component in pairs(entity.components) do + local callback = component.on_update + if callback then + local result, err = pcall(callback) + if err then + print(err) + end end end end diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index f363702a..ab23be7c 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -311,7 +311,11 @@ void ContentLoader::loadItem(ItemDef& def, const std::string& name, const fs::pa void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs::path& file) { auto root = files::read_json(file); - root->str("script-name", def.scriptName); + if (auto componentsarr = root->list("components")) { + for (size_t i = 0; i < componentsarr->size(); i++) { + def.components.push_back(componentsarr->str(i)); + } + } if (auto boxarr = root->list("hitbox")) { def.hitbox = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2)); } @@ -341,9 +345,11 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const st auto configFile = folder/fs::path("entities/"+name+".json"); if (fs::exists(configFile)) loadEntity(def, full, configFile); - auto scriptfile = folder/fs::path("scripts/components/"+def.scriptName+".lua"); - if (fs::is_regular_file(scriptfile)) { - scripting::load_entity_component(env, def, scriptfile); + for (auto& componentName : def.components) { + auto scriptfile = folder/fs::path("scripts/components/"+componentName+".lua"); + if (fs::is_regular_file(scriptfile)) { + scripting::load_entity_component(env, componentName, scriptfile); + } } } @@ -437,7 +443,6 @@ void ContentLoader::load() { std::string full = colon == std::string::npos ? pack->id + ":" + name : name; if (colon != std::string::npos) name[colon] = '/'; auto& def = builder.entities.create(full); - if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName; loadEntity(def, full, name); stats->totalEntities++; } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index c5c99fbc..b6d0ec9e 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -101,7 +101,9 @@ scriptenv scripting::create_doc_environment(const scriptenv& parent, const std:: } [[nodiscard]] -static scriptenv create_entity_environment(const scriptenv& parent, int entityIdx) { +static scriptenv create_component_environment(const scriptenv& parent, + int entityIdx, + const std::string& name) { auto L = lua::get_main_thread(); int id = lua::create_environment(L, *parent); @@ -115,7 +117,12 @@ static scriptenv create_entity_environment(const scriptenv& parent, int entityId lua::pushvalue(L, -2); lua::setfield(L, "entity"); - lua::setfield(L, "env"); + lua::pop(L); + if (lua::getfield(L, "components")) { + lua::pushenv(L, id); + lua::setfield(L, name); + lua::pop(L); + } lua::pop(L); return std::shared_ptr(new int(id), [=](int* id) { @@ -256,10 +263,10 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, }); } -scriptenv scripting::on_entity_spawn( +void scripting::on_entity_spawn( const EntityDef& def, entityid_t eid, - entity_funcs_set& funcsset, + const std::vector>& components, dynamic::Value args ) { auto L = lua::get_main_thread(); @@ -268,22 +275,30 @@ scriptenv scripting::on_entity_spawn( lua::pushinteger(L, eid); lua::call(L, 1); } - auto entityenv = create_entity_environment(get_root_environment(), -1); - lua::get_from(L, lua::CHUNKS_TABLE, def.scriptName, true); - lua::pushenv(L, *entityenv); - lua::pushvalue(L, args); - lua::setfield(L, "ARGS"); - lua::setfenv(L); - lua::call_nothrow(L, 0, 0); + for (size_t i = 0; i < components.size()-1; i++) { + lua::pushvalue(L, -1); + } + for (auto& component : components) { + auto compenv = create_component_environment( + get_root_environment(), -1, component->name); + lua::get_from(L, lua::CHUNKS_TABLE, component->name, true); + lua::pushenv(L, *compenv); + lua::pushvalue(L, args); + lua::setfield(L, "ARGS"); + lua::setfenv(L); + lua::call_nothrow(L, 0, 0); - lua::pushenv(L, *entityenv); - funcsset.on_grounded = lua::hasfield(L, "on_grounded"); - funcsset.on_fall = lua::hasfield(L, "on_fall"); - funcsset.on_despawn = lua::hasfield(L, "on_despawn"); - funcsset.on_trigger_enter = lua::hasfield(L, "on_trigger_enter"); - funcsset.on_trigger_exit = lua::hasfield(L, "on_trigger_exit"); - lua::pop(L, 2); - return entityenv; + lua::pushenv(L, *compenv); + auto& funcsset = component->funcsset; + funcsset.on_grounded = lua::hasfield(L, "on_grounded"); + funcsset.on_fall = lua::hasfield(L, "on_fall"); + funcsset.on_despawn = lua::hasfield(L, "on_despawn"); + funcsset.on_trigger_enter = lua::hasfield(L, "on_trigger_enter"); + funcsset.on_trigger_exit = lua::hasfield(L, "on_trigger_exit"); + lua::pop(L, 2); + + component->env = compenv; + } } static bool process_entity_callback( @@ -306,8 +321,10 @@ static bool process_entity_callback( bool scripting::on_entity_despawn(const EntityDef& def, const Entity& entity) { const auto& script = entity.getScripting(); - if (script.funcsset.on_despawn) { - process_entity_callback(script.env, "on_despawn", nullptr); + for (auto& component : script.components) { + if (component->funcsset.on_despawn) { + process_entity_callback(component->env, "on_despawn", nullptr); + } } auto L = lua::get_main_thread(); lua::get_from(L, "stdcomp", "remove_Entity", true); @@ -318,42 +335,50 @@ bool scripting::on_entity_despawn(const EntityDef& def, const Entity& entity) { bool scripting::on_entity_grounded(const Entity& entity, float force) { const auto& script = entity.getScripting(); - if (script.funcsset.on_grounded) { - return process_entity_callback(script.env, "on_grounded", [force](auto L){ - return lua::pushnumber(L, force); - }); + for (auto& component : script.components) { + if (component->funcsset.on_grounded) { + process_entity_callback(component->env, "on_grounded", [force](auto L){ + return lua::pushnumber(L, force); + }); + } } return true; } bool scripting::on_entity_fall(const Entity& entity) { const auto& script = entity.getScripting(); - if (script.funcsset.on_fall) { - return process_entity_callback(script.env, "on_fall", nullptr); + for (auto& component : script.components) { + if (component->funcsset.on_fall) { + process_entity_callback(component->env, "on_fall", nullptr); + } } return true; } void scripting::on_trigger_enter(const Entity& entity, size_t index, entityid_t oid) { const auto& script = entity.getScripting(); - if (script.funcsset.on_trigger_enter) { - process_entity_callback(script.env, "on_trigger_enter", [index, oid](auto L) { - lua::pushinteger(L, index); - lua::pushinteger(L, oid); - return 2; - }); + for (auto& component : script.components) { + if (component->funcsset.on_trigger_enter) { + process_entity_callback(component->env, "on_trigger_enter", [index, oid](auto L) { + lua::pushinteger(L, index); + lua::pushinteger(L, oid); + return 2; + }); + } } } void scripting::on_trigger_exit(const Entity& entity, size_t index, entityid_t oid) { const auto& script = entity.getScripting(); - if (script.funcsset.on_trigger_exit) { - process_entity_callback(script.env, "on_trigger_exit", [index, oid](auto L) { - lua::pushinteger(L, index); - lua::pushinteger(L, oid); - return 2; - }); + for (auto& component : script.components) { + if (component->funcsset.on_trigger_exit) { + process_entity_callback(component->env, "on_trigger_exit", [index, oid](auto L) { + lua::pushinteger(L, index); + lua::pushinteger(L, oid); + return 2; + }); + } } } @@ -447,12 +472,12 @@ void scripting::load_item_script(const scriptenv& senv, const std::string& prefi funcsset.on_block_break_by = register_event(env, "on_block_break_by", prefix+".blockbreakby"); } -void scripting::load_entity_component(const scriptenv& penv, const EntityDef& def, const fs::path& file) { +void scripting::load_entity_component(const scriptenv& penv, const std::string& name, const fs::path& file) { auto L = lua::get_main_thread(); std::string src = files::read_string(file); logger.info() << "script (component) " << file.u8string(); lua::loadbuffer(L, *penv, src, file.u8string()); - lua::store_in(L, lua::CHUNKS_TABLE, def.scriptName); + lua::store_in(L, lua::CHUNKS_TABLE, name); } void scripting::load_world_script(const scriptenv& senv, const std::string& prefix, const fs::path& file) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 72900a37..9bdf7367 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -27,7 +27,7 @@ class Inventory; class UiDocument; struct block_funcs_set; struct item_funcs_set; -struct entity_funcs_set; +struct UserComponent; struct uidocscript; class BlocksController; class LevelController; @@ -76,10 +76,10 @@ namespace scripting { /// @return true if prevents default action bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); - scriptenv on_entity_spawn( - const EntityDef& def, + void on_entity_spawn( + const EntityDef& def, entityid_t eid, - entity_funcs_set&, + const std::vector>& components, dynamic::Value args ); bool on_entity_despawn(const EntityDef& def, const Entity& entity); @@ -124,7 +124,7 @@ namespace scripting { void load_entity_component( const scriptenv& env, - const EntityDef& def, + const std::string& name, const fs::path& file); /// @brief Load package-specific world script diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 058e3ec4..3e3f9afe 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -90,12 +90,15 @@ entityid_t Entities::spawn( create_trigger_callback(this) }; } - auto& scripting = registry.emplace( - entity, entity_funcs_set {}, nullptr); + auto& scripting = registry.emplace(entity); entities[id] = entity; registry.emplace(entity, rig->instance()); - scripting.env = scripting::on_entity_spawn( - def, id, scripting.funcsset, std::move(args)); + for (auto& componentName : def.components) { + auto component = std::make_unique( + componentName, entity_funcs_set {}, nullptr); + scripting.components.emplace_back(std::move(component)); + } + scripting::on_entity_spawn(def, id, scripting.components, std::move(args)); return id; } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 58ceb7f5..1aca686b 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -6,6 +6,7 @@ #include "../data/dynamic.hpp" #include +#include #include #include #define GLM_ENABLE_EXPERIMENTAL @@ -65,9 +66,23 @@ struct Rigidbody { std::vector triggers; }; -struct Scripting { +struct UserComponent { + std::string name; entity_funcs_set funcsset; scriptenv env; + + UserComponent(const std::string& name, entity_funcs_set funcsset, scriptenv env) + : name(name), funcsset(funcsset), env(env) {} +}; + +struct ScriptComponents { + std::vector> components; + + ScriptComponents() = default; + + ScriptComponents(ScriptComponents&& other) + : components(std::move(other.components)) { + } }; class Level; @@ -116,8 +131,8 @@ public: return registry.get(entity); } - Scripting& getScripting() const { - return registry.get(entity); + ScriptComponents& getScripting() const { + return registry.get(entity); } rigging::Rig& getModeltree() const; diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index a1044387..d8b87b87 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -15,8 +15,9 @@ namespace rigging { struct EntityDef { /// @brief Entity string id (with prefix included) std::string const name; + + std::vector components; - std::string scriptName = name.substr(name.find(':')+1); glm::vec3 hitbox {0.5f}; std::vector> boxTriggers {}; std::vector> radialTriggers {}; From 019a88ef846cdd751e4e3800e6dff8d99d5115ea Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 4 Jul 2024 20:54:45 +0300 Subject: [PATCH 066/178] add entity:get_component(...) --- res/content/base/scripts/hud.lua | 3 ++- res/modules/internal/stdcomp.lua | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 553e9945..0505d941 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -18,6 +18,7 @@ function on_hud_open() id=itemid, count=1 }}) - drop.rigidbody:set_vel(vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL))) + local velocity = vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL)) + drop.get_component("rigidbody"):set_vel(velocity) end) end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index a87b0a6e..75e72306 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -9,7 +9,7 @@ local Transform = {__index={ set_rot=function(self, m) return __transform.set_rot(self.eid, m) end, }} -function new_Transform(eid) +local function new_Transform(eid) return setmetatable({eid=eid}, Transform) end @@ -22,7 +22,7 @@ local Rigidbody = {__index={ set_size=function(self, v) return __rigidbody.set_size(self.eid, v) end, }} -function new_Rigidbody(eid) +local function new_Rigidbody(eid) return setmetatable({eid=eid}, Rigidbody) end @@ -33,7 +33,7 @@ local Modeltree = {__index={ set_texture=function(self, s, s2) return __modeltree.set_texture(self.eid, s, s2) end, }} -function new_Modeltree(eid) +local function new_Modeltree(eid) return setmetatable({eid=eid}, Modeltree) end @@ -42,6 +42,7 @@ end local Entity = {__index={ despawn=function(self) return entities.despawn(self.eid) end, set_rig=function(self, s) return entities.set_rig(self.eid, s) end, + get_component=function(self, name) return self.components[name] end, }} local entities = {} @@ -52,7 +53,6 @@ return { entity.transform = new_Transform(eid) entity.rigidbody = new_Rigidbody(eid) entity.modeltree = new_Modeltree(eid) - entity.data = {} entity.components = {} entities[eid] = entity; return entity From f0270d33914627c6e86222b3c5b664f227bc046b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 5 Jul 2024 05:16:31 +0300 Subject: [PATCH 067/178] feat: saving entities (WIP) --- res/content/base/entities/drop.json | 4 +- res/content/base/scripts/hud.lua | 2 +- res/modules/internal/stdcomp.lua | 1 + src/assets/assetload_funcs.cpp | 2 +- src/coders/binary_json.cpp | 7 +++ src/coders/binary_json.hpp | 7 +-- src/content/ContentLoader.cpp | 4 +- src/data/dynamic.hpp | 27 ++-------- src/data/dynamic_fwd.hpp | 31 +++++++++++ src/data/dynamic_util.hpp | 30 +++++++++++ src/files/WorldRegions.cpp | 49 +++++++++++------- src/files/WorldRegions.hpp | 5 +- src/logic/scripting/scripting.cpp | 11 ++++ src/logic/scripting/scripting.hpp | 1 + src/maths/aabb.hpp | 2 +- src/objects/Entities.cpp | 73 ++++++++++++++++++++++++-- src/objects/Entities.hpp | 4 ++ src/objects/EntityDef.hpp | 12 ++++- src/objects/rigging.cpp | 9 ++-- src/objects/rigging.hpp | 11 +++- src/voxels/Chunks.cpp | 79 +++++++++++++++++++---------- src/voxels/Chunks.hpp | 9 ++-- src/world/Level.cpp | 2 +- src/world/World.cpp | 9 +--- 24 files changed, 290 insertions(+), 101 deletions(-) create mode 100644 src/data/dynamic_fwd.hpp create mode 100644 src/data/dynamic_util.hpp diff --git a/res/content/base/entities/drop.json b/res/content/base/entities/drop.json index 0be03b85..9bf3dac7 100644 --- a/res/content/base/entities/drop.json +++ b/res/content/base/entities/drop.json @@ -6,5 +6,7 @@ "triggers": [ ["aabb", -0.2, -0.2, -0.2, 0.2, 0.2, 0.2], ["radius", 1.6] - ] + ], + "save-rig-textures": true, + "save-rig-pose": true } diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 0505d941..010fec67 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -19,6 +19,6 @@ function on_hud_open() count=1 }}) local velocity = vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL)) - drop.get_component("rigidbody"):set_vel(velocity) + drop.rigidbody:set_vel(velocity) end) end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index 75e72306..de9f9a09 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -74,6 +74,7 @@ return { if callback then local result, err = pcall(callback) if err then + --// TODO: replace with error logging print(err) end end diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 690422cb..bb5c0b6d 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -238,7 +238,7 @@ assetload::postfunc assetload::rig( auto path = paths->find(file+".json"); auto text = files::read_string(path); try { - auto rig = rigging::RigConfig::parse(text, path.u8string()).release(); + auto rig = rigging::RigConfig::parse(text, path.u8string(), name).release(); return [=](Assets* assets) { // TODO: add models loading assets->store(std::unique_ptr(rig), name); diff --git a/src/coders/binary_json.cpp b/src/coders/binary_json.cpp index 8c3236e8..f1f87af6 100644 --- a/src/coders/binary_json.cpp +++ b/src/coders/binary_json.cpp @@ -83,6 +83,13 @@ std::vector json::to_binary(const Map* obj, bool compress) { return builder.build(); } +std::vector json::to_binary(const Value& value, bool compress) { + if (auto map = std::get_if(&value)) { + return to_binary(map->get(), compress); + } + throw std::runtime_error("map is only supported as the root element"); +} + static Value value_from_binary(ByteReader& reader) { ubyte typecode = reader.get(); switch (typecode) { diff --git a/src/coders/binary_json.hpp b/src/coders/binary_json.hpp index c79a7d4d..0cb9945b 100644 --- a/src/coders/binary_json.hpp +++ b/src/coders/binary_json.hpp @@ -1,7 +1,7 @@ #ifndef CODERS_BINARY_JSON_HPP_ #define CODERS_BINARY_JSON_HPP_ -#include "../typedefs.hpp" +#include "../data/dynamic_fwd.hpp" #include #include @@ -26,8 +26,9 @@ namespace json { inline constexpr int BJSON_TYPE_NULL = 0xC; inline constexpr int BJSON_TYPE_CDOCUMENT = 0x1F; - extern std::vector to_binary(const dynamic::Map* obj, bool compress=false); - extern std::shared_ptr from_binary(const ubyte* src, size_t size); + std::vector to_binary(const dynamic::Map* obj, bool compress=false); + std::vector to_binary(const dynamic::Value& obj, bool compress=false); + std::shared_ptr from_binary(const ubyte* src, size_t size); } #endif // CODERS_BINARY_JSON_HPP_ diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index ab23be7c..d62277c7 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -337,7 +337,9 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs } } } - std::cout << "loading entity " << name << " from " << file.u8string() << std::endl; + root->flag("save", def.save.enabled); + root->flag("save-rig-pose", def.save.rig.pose); + root->flag("save-rig-textures", def.save.rig.textures); } void ContentLoader::loadEntity(EntityDef& def, const std::string& full, const std::string& name) { diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index 5dc5dbed..1153697f 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -1,42 +1,22 @@ #ifndef DATA_DYNAMIC_HPP_ #define DATA_DYNAMIC_HPP_ -#include "../typedefs.hpp" +#include "dynamic_fwd.hpp" #include #include #include #include #include -#include + #include #include namespace dynamic { - class Map; - class List; - enum class Type { none=0, map, list, string, number, boolean, integer }; - using Map_sptr = std::shared_ptr; - using List_sptr = std::shared_ptr; - - struct none {}; - - inline constexpr none NONE = {}; - - using Value = std::variant< - none, - Map_sptr, - List_sptr, - std::string, - number_t, - bool, - integer_t - >; - const std::string& type_name(const Value& value); List_sptr create_list(std::initializer_list values={}); Map_sptr create_map(std::initializer_list> entries={}); @@ -153,6 +133,9 @@ namespace dynamic { Map& put(std::string key, int64_t value) { return put(key, Value(static_cast(value))); } + Map& put(std::string key, uint64_t value) { + return put(key, Value(static_cast(value))); + } Map& put(std::string key, float value) { return put(key, Value(static_cast(value))); } diff --git a/src/data/dynamic_fwd.hpp b/src/data/dynamic_fwd.hpp new file mode 100644 index 00000000..ee5f552f --- /dev/null +++ b/src/data/dynamic_fwd.hpp @@ -0,0 +1,31 @@ +#ifndef DATA_DYNAMIC_FWD_HPP_ +#define DATA_DYNAMIC_FWD_HPP_ + +#include "../typedefs.hpp" + +#include +#include + +namespace dynamic { + class Map; + class List; + + using Map_sptr = std::shared_ptr; + using List_sptr = std::shared_ptr; + + struct none {}; + + inline constexpr none NONE = {}; + + using Value = std::variant< + none, + Map_sptr, + List_sptr, + std::string, + number_t, + bool, + integer_t + >; +} + +#endif // DATA_DYNAMIC_FWD_HPP_ diff --git a/src/data/dynamic_util.hpp b/src/data/dynamic_util.hpp new file mode 100644 index 00000000..3a10a123 --- /dev/null +++ b/src/data/dynamic_util.hpp @@ -0,0 +1,30 @@ +#ifndef DATA_DYNAMIC_UTIL_HPP_ +#define DATA_DYNAMIC_UTIL_HPP_ + +#include "dynamic.hpp" + +#include + +namespace dynamic { + template + inline dynamic::List_sptr to_value(glm::vec vec) { + auto list = dynamic::create_list(); + for (size_t i = 0; i < n; i++) { + list->put(vec[i]); + } + return list; + } + + template + inline dynamic::List_sptr to_value(glm::mat mat) { + auto list = dynamic::create_list(); + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < m; j++) { + list->put(mat[i][j]); + } + } + return list; + } +} + +#endif // DATA_DYNAMIC_UTIL_HPP_ diff --git a/src/files/WorldRegions.cpp b/src/files/WorldRegions.cpp index 44aa8449..9bec7921 100644 --- a/src/files/WorldRegions.cpp +++ b/src/files/WorldRegions.cpp @@ -9,6 +9,7 @@ #include #include +#include #define REGION_FORMAT_MAGIC ".VOXREG" @@ -36,17 +37,17 @@ std::unique_ptr regfile::read(int index, uint32_t& length) { uint32_t offset; file.seekg(table_offset + index * 4); - file.read((char*)(&offset), 4); - offset = dataio::read_int32_big((const ubyte*)(&offset), 0); + file.read(reinterpret_cast(&offset), 4); + offset = dataio::read_int32_big(reinterpret_cast(&offset), 0); if (offset == 0){ return nullptr; } file.seekg(offset); - file.read((char*)(&offset), 4); - length = dataio::read_int32_big((const ubyte*)(&offset), 0); + file.read(reinterpret_cast(&offset), 4); + length = dataio::read_int32_big(reinterpret_cast(&offset), 0); auto data = std::make_unique(length); - file.read((char*)data.get(), length); + file.read(reinterpret_cast(data.get()), length); return data; } @@ -88,12 +89,13 @@ uint WorldRegion::getChunkDataSize(uint x, uint z) { } WorldRegions::WorldRegions(const fs::path& directory) : directory(directory) { - for (uint i = 0; i < sizeof(layers)/sizeof(RegionsLayer); i++) { + for (size_t i = 0; i < sizeof(layers)/sizeof(RegionsLayer); i++) { layers[i].layer = i; } layers[REGION_LAYER_VOXELS].folder = directory/fs::path("regions"); layers[REGION_LAYER_LIGHTS].folder = directory/fs::path("lights"); layers[REGION_LAYER_INVENTORIES].folder = directory/fs::path("inventories"); + layers[REGION_LAYER_ENTITIES].folder = directory/fs::path("entities"); } WorldRegions::~WorldRegions() { @@ -123,7 +125,7 @@ WorldRegion* WorldRegions::getOrCreateRegion(int x, int z, int layer) { std::unique_ptr WorldRegions::compress(const ubyte* src, size_t srclen, size_t& len) { auto buffer = bufferPool.get(); - ubyte* bytes = buffer.get(); + auto bytes = buffer.get(); len = extrle::encode(src, srclen, bytes); auto data = std::make_unique(len); @@ -150,7 +152,7 @@ inline void calc_reg_coords( std::unique_ptr WorldRegions::readChunkData( int x, int z, uint32_t& length, regfile* rfile -){ +) { int regionX, regionZ, localX, localZ; calc_reg_coords(x, z, regionX, regionZ, localX, localZ); int chunkIndex = localZ * REGION_SIZE + localX; @@ -171,10 +173,7 @@ void WorldRegions::fetchChunks(WorldRegion* region, int x, int z, regfile* file) } } -ubyte* WorldRegions::getData( - int x, int z, int layer, - uint32_t& size -) { +ubyte* WorldRegions::getData(int x, int z, int layer, uint32_t& size) { if (generatorTestMode) { return nullptr; } @@ -301,7 +300,7 @@ void WorldRegions::writeRegion(int x, int z, int layer, WorldRegion* entry){ offset += 4 + compressedSize; file.write(intbuf, 4); - file.write((const char*)chunk, compressedSize); + file.write(reinterpret_cast(chunk), compressedSize); } } for (size_t i = 0; i < REGION_CHUNKS_COUNT; i++) { @@ -313,8 +312,9 @@ void WorldRegions::writeRegion(int x, int z, int layer, WorldRegion* entry){ void WorldRegions::writeRegions(int layer) { for (auto& it : layers[layer].regions){ WorldRegion* region = it.second.get(); - if (region->getChunks() == nullptr || !region->isUnsaved()) + if (region->getChunks() == nullptr || !region->isUnsaved()) { continue; + } glm::ivec2 key = it.first; writeRegion(key[0], key[1], layer, region); } @@ -354,7 +354,7 @@ static std::unique_ptr write_inventories(Chunk* chunk, uint& datasize) } /// @brief Store chunk data (voxels and lights) in region (existing or new) -void WorldRegions::put(Chunk* chunk){ +void WorldRegions::put(Chunk* chunk, std::vector entitiesData){ assert(chunk != nullptr); if (!chunk->flags.lighted) { return; @@ -376,12 +376,21 @@ void WorldRegions::put(Chunk* chunk){ chunk->lightmap.encode(), LIGHTMAP_DATA_LEN, true); } // Writing block inventories - if (!chunk->inventories.empty()){ + if (!chunk->inventories.empty()) { uint datasize; auto data = write_inventories(chunk, datasize); put(chunk->x, chunk->z, REGION_LAYER_INVENTORIES, std::move(data), datasize, false); } + // Writing entities + if (!entitiesData.empty()) { + auto data = std::make_unique(entitiesData.size()); + for (size_t i = 0; i < entitiesData.size(); i++) { + data[i] = entitiesData[i]; + } + put(chunk->x, chunk->z, REGION_LAYER_ENTITIES, + std::move(data), entitiesData.size(), false); + } } std::unique_ptr WorldRegions::getChunk(int x, int z){ @@ -398,8 +407,9 @@ std::unique_ptr WorldRegions::getChunk(int x, int z){ std::unique_ptr WorldRegions::getLights(int x, int z) { uint32_t size; auto* bytes = getData(x, z, REGION_LAYER_LIGHTS, size); - if (bytes == nullptr) + if (bytes == nullptr) { return nullptr; + } auto data = decompress(bytes, size, LIGHTMAP_DATA_LEN); return Lightmap::decode(data.get()); } @@ -412,7 +422,7 @@ chunk_inventories_map WorldRegions::fetchInventories(int x, int z) { return meta; } ByteReader reader(data, bytesSize); - int count = reader.getInt32(); + auto count = reader.getInt32(); for (int i = 0; i < count; i++) { uint index = reader.getInt32(); uint size = reader.getInt32(); @@ -439,8 +449,9 @@ void WorldRegions::processRegionVoxels(int x, int z, const regionproc& func) { int gz = cz + z * REGION_SIZE; uint32_t length; auto data = readChunkData(gx, gz, length, regfile.get()); - if (data == nullptr) + if (data == nullptr) { continue; + } data = decompress(data.get(), length, CHUNK_DATA_LEN); if (func(data.get())) { put(gx, gz, REGION_LAYER_VOXELS, std::move(data), CHUNK_DATA_LEN, true); diff --git a/src/files/WorldRegions.hpp b/src/files/WorldRegions.hpp index 7ad16037..f96477de 100644 --- a/src/files/WorldRegions.hpp +++ b/src/files/WorldRegions.hpp @@ -24,6 +24,7 @@ inline constexpr uint REGION_HEADER_SIZE = 10; inline constexpr uint REGION_LAYER_VOXELS = 0; inline constexpr uint REGION_LAYER_LIGHTS = 1; inline constexpr uint REGION_LAYER_INVENTORIES = 2; +inline constexpr uint REGION_LAYER_ENTITIES = 3; inline constexpr uint REGION_SIZE_BIT = 5; inline constexpr uint REGION_SIZE = (1 << (REGION_SIZE_BIT)); @@ -119,7 +120,7 @@ class WorldRegions { std::unordered_map> openRegFiles; std::mutex regFilesMutex; std::condition_variable regFilesCv; - RegionsLayer layers[3] {}; + RegionsLayer layers[4] {}; util::BufferPool bufferPool { std::max(CHUNK_DATA_LEN, LIGHTMAP_DATA_LEN) * 2 }; @@ -170,7 +171,7 @@ public: ~WorldRegions(); /// @brief Put all chunk data to regions - void put(Chunk* chunk); + void put(Chunk* chunk, std::vector entitiesData); /// @brief Store data in specified region /// @param x chunk.x diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index b6d0ec9e..9d9a8146 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -295,6 +295,7 @@ void scripting::on_entity_spawn( funcsset.on_despawn = lua::hasfield(L, "on_despawn"); funcsset.on_trigger_enter = lua::hasfield(L, "on_trigger_enter"); funcsset.on_trigger_exit = lua::hasfield(L, "on_trigger_exit"); + funcsset.on_save = lua::hasfield(L, "on_save"); lua::pop(L, 2); component->env = compenv; @@ -355,6 +356,16 @@ bool scripting::on_entity_fall(const Entity& entity) { return true; } +bool scripting::on_entity_save(const Entity& entity) { + const auto& script = entity.getScripting(); + for (auto& component : script.components) { + if (component->funcsset.on_save) { + process_entity_callback(component->env, "on_save", nullptr); + } + } + return true; +} + void scripting::on_trigger_enter(const Entity& entity, size_t index, entityid_t oid) { const auto& script = entity.getScripting(); for (auto& component : script.components) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 9bdf7367..cb063acc 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -85,6 +85,7 @@ namespace scripting { bool on_entity_despawn(const EntityDef& def, const Entity& entity); bool on_entity_grounded(const Entity& entity, float force); bool on_entity_fall(const Entity& entity); + bool on_entity_save(const Entity& entity); void on_entities_update(); void on_trigger_enter(const Entity& entity, size_t index, entityid_t oid); void on_trigger_exit(const Entity& entity, size_t index, entityid_t oid); diff --git a/src/maths/aabb.hpp b/src/maths/aabb.hpp index 38c829ce..67a3f05d 100644 --- a/src/maths/aabb.hpp +++ b/src/maths/aabb.hpp @@ -13,7 +13,7 @@ struct AABB { AABB(glm::vec3 size) : a(0.0f), b(size) { } - AABB(glm::vec3 pos, glm::vec3 size) : a(pos), b(size) { + AABB(glm::vec3 a, glm::vec3 b) : a(a), b(b) { } /// @brief Get AABB point with minimal x,y,z diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 3e3f9afe..2b18a46b 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -1,5 +1,6 @@ #include "Entities.hpp" +#include "../data/dynamic_util.hpp" #include "../assets/Assets.hpp" #include "../world/Level.hpp" #include "../physics/Hitbox.hpp" @@ -78,8 +79,7 @@ entityid_t Entities::spawn( body.triggers[i] = Trigger { true, TriggerType::AABB, i, id, params, params, {}, {}, create_trigger_callback(this), - create_trigger_callback(this) - }; + create_trigger_callback(this)}; } for (auto& [i, radius] : def.radialTriggers) { TriggerParams params {}; @@ -87,11 +87,11 @@ entityid_t Entities::spawn( body.triggers[i] = Trigger { true, TriggerType::RADIUS, i, id, params, params, {}, {}, create_trigger_callback(this), - create_trigger_callback(this) - }; + create_trigger_callback(this)}; } auto& scripting = registry.emplace(entity); entities[id] = entity; + uids[entity] = id; registry.emplace(entity, rig->instance()); for (auto& componentName : def.components) { auto component = std::make_unique( @@ -112,11 +112,59 @@ void Entities::despawn(entityid_t id) { } } +dynamic::Value Entities::serialize(const Entity& entity) { + auto root = dynamic::create_map(); + auto& eid = entity.getID(); + auto& def = eid.def; + root->put("def", def.name); + root->put("uid", eid.uid); + { + auto& transform = entity.getTransform(); + auto& tsfmap = root->putMap("transform"); + tsfmap.put("pos", dynamic::to_value(transform.pos)); + if (transform.size != glm::vec3(1.0f)) { + tsfmap.put("size", dynamic::to_value(transform.size)); + } + tsfmap.put("rot", dynamic::to_value(transform.rot)); + } + { + auto& rigidbody = entity.getRigidbody(); + auto& bodymap = root->putMap("rigidbody"); + if (!rigidbody.enabled) { + bodymap.put("enabled", rigidbody.enabled); + } + bodymap.put("vel", dynamic::to_value(rigidbody.hitbox.velocity)); + bodymap.put("damping", rigidbody.hitbox.linearDamping); + } + auto& rig = entity.getModeltree(); + if (rig.config->getName() != def.rigName) { + root->put("rig", rig.config->getName()); + } + + if (def.save.rig.pose || def.save.rig.textures) { + auto& rigmap = root->putMap("rig"); + if (def.save.rig.textures) { + auto& map = rigmap.putMap("textures"); + for (auto& entry : rig.textures) { + map.put(entry.first, entry.second); + } + } + if (def.save.rig.pose) { + auto& list = rigmap.putList("pose"); + for (auto& mat : rig.pose.matrices) { + list.put(dynamic::to_value(mat)); + } + } + } + return root; +} + void Entities::clean() { for (auto it = entities.begin(); it != entities.end();) { if (!registry.get(it->second).destroyFlag) { ++it; } else { + uids.erase(it->second); registry.destroy(it->second); it = entities.erase(it); } @@ -249,3 +297,20 @@ void Entities::render(Assets* assets, ModelBatch& batch, const Frustum& frustum) } } } + +std::vector Entities::getAllInside(AABB aabb) { + std::vector collected; + auto view = registry.view(); + for (auto [entity, transform] : view.each()) { + if (aabb.contains(transform.pos)) { + const auto& found = uids.find(entity); + if (found == uids.end()) { + continue; + } + if (auto entity = get(found->second)) { + collected.push_back(*entity); + } + } + } + return collected; +} diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 1aca686b..3c0c3c95 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -21,6 +21,7 @@ struct entity_funcs_set { bool on_fall : 1; bool on_trigger_enter : 1; bool on_trigger_exit : 1; + bool on_save : 1; }; struct EntityDef; @@ -154,6 +155,7 @@ class Entities { entt::registry registry; Level* level; std::unordered_map entities; + std::unordered_map uids; entityid_t nextID = 1; void preparePhysics(); @@ -181,7 +183,9 @@ public: return std::nullopt; } + std::vector getAllInside(AABB aabb); void despawn(entityid_t id); + dynamic::Value serialize(const Entity& entity); inline size_t size() const { return entities.size(); diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index d8b87b87..1abfca14 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -15,14 +15,22 @@ namespace rigging { struct EntityDef { /// @brief Entity string id (with prefix included) std::string const name; - + std::vector components; glm::vec3 hitbox {0.5f}; std::vector> boxTriggers {}; std::vector> radialTriggers {}; std::string rigName = name.substr(name.find(":")+1); - + + struct { + bool enabled = true; + struct { + bool textures = false; + bool pose = false; + } rig; + } save {}; + struct { entityid_t id; rigging::RigConfig* rig; diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index baadc8bf..275577aa 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -30,8 +30,8 @@ static void get_all_nodes(std::vector& nodes, RigNode* node) { } } -RigConfig::RigConfig(std::unique_ptr root, size_t nodesCount) - : root(std::move(root)), nodes(nodesCount) { +RigConfig::RigConfig(const std::string& name, std::unique_ptr root, size_t nodesCount) + : name(name), root(std::move(root)), nodes(nodesCount) { get_all_nodes(nodes, this->root.get()); } @@ -106,7 +106,8 @@ static std::tuple> read_node( std::unique_ptr RigConfig::parse( std::string_view src, - std::string_view file + std::string_view file, + std::string_view name ) { auto root = json::parse(file, src); auto rootNodeMap = root->map("root"); @@ -114,5 +115,5 @@ std::unique_ptr RigConfig::parse( throw std::runtime_error("missing 'root' element"); } auto [count, rootNode] = read_node(rootNodeMap, 0); - return std::make_unique(std::move(rootNode), count); + return std::make_unique(std::string(name), std::move(rootNode), count); } diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index 797ec20e..6ab1b8f3 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -68,6 +68,7 @@ namespace rigging { }; class RigConfig { + std::string name; std::unique_ptr root; std::unordered_map indices; @@ -85,7 +86,8 @@ namespace rigging { RigNode* node, glm::mat4 matrix) const; public: - RigConfig(std::unique_ptr root, size_t nodesCount); + RigConfig(const std::string& name, std::unique_ptr root, + size_t nodesCount); void update(Rig& rig, glm::mat4 matrix) const; void setup(const Assets* assets, RigNode* node=nullptr) const; @@ -103,12 +105,17 @@ namespace rigging { static std::unique_ptr parse( std::string_view src, - std::string_view file + std::string_view file, + std::string_view name ); const std::vector& getNodes() const { return nodes; } + + const std::string& getName() const { + return name; + } }; }; diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 9edc4e16..2b02b974 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -7,10 +7,14 @@ #include "../lighting/Lightmap.hpp" #include "../files/WorldFiles.hpp" #include "../world/LevelEvents.hpp" +#include "../world/Level.hpp" +#include "../objects/Entities.hpp" #include "../graphics/core/Mesh.hpp" #include "../maths/voxmaths.hpp" #include "../maths/aabb.hpp" #include "../maths/rays.hpp" +#include "../coders/byte_utils.hpp" +#include "../coders/json.hpp" #include #include @@ -18,17 +22,16 @@ #include Chunks::Chunks( - uint32_t w, uint32_t d, - int32_t ox, int32_t oz, - WorldFiles* wfile, - LevelEvents* events, - const Content* content -) : indices(content->getIndices()), + uint32_t w, uint32_t d, + int32_t ox, int32_t oz, + WorldFiles* wfile, + Level* level +) : level(level), + indices(level->content->getIndices()), chunks(w*d), chunksSecond(w*d), w(w), d(d), ox(ox), oz(oz), - worldFiles(wfile), - events(events) + worldFiles(wfile) { volume = static_cast(w)*static_cast(d); chunksCount = 0; @@ -424,13 +427,13 @@ voxel* Chunks::rayCast( int steppedIndex = -1; - while (t <= maxDist){ + while (t <= maxDist) { voxel* voxel = get(ix, iy, iz); if (voxel == nullptr){ return nullptr; } const auto def = indices->blocks.get(voxel->id); - if (def->selectable){ + if (def->selectable) { end.x = px + t * dx; end.y = py + t * dy; end.z = pz + t * dz; @@ -517,9 +520,9 @@ voxel* Chunks::rayCast( } glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDist) { - float px = start.x; - float py = start.y; - float pz = start.z; + const float px = start.x; + const float py = start.y; + const float pz = start.z; float dx = dir.x; float dy = dir.y; @@ -620,7 +623,6 @@ void Chunks::setCenter(int32_t x, int32_t z) { } void Chunks::translate(int32_t dx, int32_t dz) { - auto& regions = worldFiles->getRegions(); for (uint i = 0; i < volume; i++){ chunksSecond[i] = nullptr; } @@ -631,9 +633,9 @@ void Chunks::translate(int32_t dx, int32_t dz) { int nz = z - dz; if (chunk == nullptr) continue; - if (nx < 0 || nz < 0 || nx >= int(w) || nz >= int(d)) { - events->trigger(EVT_CHUNK_HIDDEN, chunk.get()); - regions.put(chunk.get()); + if (nx < 0 || nz < 0 || nx >= static_cast(w) || nz >= static_cast(d)) { + level->events->trigger(EVT_CHUNK_HIDDEN, chunk.get()); + save(chunk.get()); chunksCount--; continue; } @@ -662,8 +664,8 @@ void Chunks::resize(uint32_t newW, uint32_t newD) { const int newVolume = newW * newD; std::vector> newChunks(newVolume); std::vector> newChunksSecond(newVolume); - for (int z = 0; z < int(d) && z < int(newD); z++) { - for (int x = 0; x < int(w) && x < int(newW); x++) { + for (int z = 0; z < static_cast(d) && z < static_cast(newD); z++) { + for (int x = 0; x < static_cast(w) && x < static_cast(newW); x++) { newChunks[z * newW + x] = chunks[z * w + x]; } } @@ -684,21 +686,46 @@ bool Chunks::putChunk(const std::shared_ptr& chunk) { int z = chunk->z; x -= ox; z -= oz; - if (x < 0 || z < 0 || x >= int(w) || z >= int(d)) + if (x < 0 || z < 0 || x >= static_cast(w) || z >= static_cast(d)) { return false; + } chunks[z * w + x] = chunk; chunksCount++; return true; } -void Chunks::saveAndClear(){ - auto& regions = worldFiles->getRegions(); +void Chunks::saveAndClear() { for (size_t i = 0; i < volume; i++){ - Chunk* chunk = chunks[i].get(); + auto chunk = chunks[i].get(); chunks[i] = nullptr; - if (chunk) { - regions.put(chunk); - } + save(chunk); } chunksCount = 0; } + +void Chunks::save(Chunk* chunk) { + if (chunk != nullptr) { + AABB aabb ( + glm::vec3(chunk->x * CHUNK_W, -16, chunk->z * CHUNK_D), + glm::vec3((chunk->x+1) * CHUNK_W, CHUNK_H+32, (chunk->z + 1) * CHUNK_D) + ); + auto entities = level->entities->getAllInside(aabb); + auto root = dynamic::create_map(); + auto& list = root->putList("data"); + for (auto& entity : entities) { + list.put(level->entities->serialize(entity)); + } + if (!entities.empty()) { + chunk->flags.unsaved = true; + } + worldFiles->getRegions().put(chunk, json::to_binary(root, true)); + } +} + +void Chunks::saveAll() { + for (size_t i = 0; i < volume; i++) { + if (auto& chunk = chunks[i]) { + save(chunk.get()); + } + } +} diff --git a/src/voxels/Chunks.hpp b/src/voxels/Chunks.hpp index fb8185d4..860d3da0 100644 --- a/src/voxels/Chunks.hpp +++ b/src/voxels/Chunks.hpp @@ -18,9 +18,11 @@ class Chunk; class WorldFiles; class LevelEvents; class Block; +class Level; -/* Player-centred chunks matrix */ +/// Player-centred chunks matrix class Chunks { + Level* level; const ContentIndices* const indices; void eraseSegments(const Block* def, blockstate state, int x, int y, int z); @@ -35,10 +37,9 @@ public: uint32_t w, d; int32_t ox, oz; WorldFiles* worldFiles; - LevelEvents* events; Chunks(uint32_t w, uint32_t d, int32_t ox, int32_t oz, - WorldFiles* worldFiles, LevelEvents* events, const Content* content); + WorldFiles* worldFiles, Level* level); ~Chunks() = default; bool putChunk(const std::shared_ptr& chunk); @@ -95,6 +96,8 @@ public: void resize(uint32_t newW, uint32_t newD); void saveAndClear(); + void save(Chunk* chunk); + void saveAll(); }; #endif // VOXELS_CHUNKS_HPP_ diff --git a/src/world/Level.cpp b/src/world/Level.cpp index 84b10742..e057708d 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -38,7 +38,7 @@ Level::Level( settings.chunks.padding.get() ) * 2; chunks = std::make_unique( - matrixSize, matrixSize, 0, 0, this->world->wfile.get(), events.get(), content + matrixSize, matrixSize, 0, 0, this->world->wfile.get(), this ); lighting = std::make_unique(content, chunks.get()); diff --git a/src/world/World.cpp b/src/world/World.cpp index 3e92ccb6..e16b5e6e 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -51,14 +51,7 @@ void World::updateTimers(float delta) { void World::write(Level* level) { const Content* content = level->content; - Chunks* chunks = level->chunks.get(); - auto& regions = wfile->getRegions(); - - for (size_t i = 0; i < chunks->volume; i++) { - if (auto chunk = chunks->chunks[i]) { - regions.put(chunk.get()); - } - } + level->chunks->saveAll(); wfile->write(this, content); auto playerFile = dynamic::Map(); From e301dbe164dc7fcf0146ce8013974fb2e153463f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 5 Jul 2024 05:27:00 +0300 Subject: [PATCH 068/178] fix msvc build --- src/data/dynamic_fwd.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/data/dynamic_fwd.hpp b/src/data/dynamic_fwd.hpp index ee5f552f..1a398edd 100644 --- a/src/data/dynamic_fwd.hpp +++ b/src/data/dynamic_fwd.hpp @@ -4,6 +4,7 @@ #include "../typedefs.hpp" #include +#include #include namespace dynamic { From 08cc78289dfa33f505ad6099f33cc416e08601a6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 5 Jul 2024 18:35:46 +0300 Subject: [PATCH 069/178] add entity on_save event and SAVED_DATA variable --- res/content/base/scripts/components/drop.lua | 5 +++++ src/logic/scripting/scripting.cpp | 19 ++++++++++++++++--- src/logic/scripting/scripting.hpp | 1 + src/objects/Entities.cpp | 13 ++++++++++++- src/objects/Entities.hpp | 1 + src/voxels/Chunks.cpp | 1 + 6 files changed, 36 insertions(+), 4 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index a68fb463..f22e1ad2 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -12,6 +12,11 @@ local rotation = mat4.rotate({ math.random(), math.random(), math.random() }, 360) +function on_save() + SAVED_DATA.test = 5 + print("SAVE ENTITY") +end + do -- setup visuals local matrix = mat4.idt() local icon = item.icon(dropitem.id) diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 9d9a8146..8c5c16d3 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -263,6 +263,15 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, }); } +dynamic::Value scripting::get_component_value(const scriptenv& env, const std::string& name) { + auto L = lua::get_main_thread(); + lua::pushenv(L, *env); + if (lua::getfield(L, name)) { + return lua::tovalue(L, -1); + } + return dynamic::NONE; +} + void scripting::on_entity_spawn( const EntityDef& def, entityid_t eid, @@ -279,12 +288,17 @@ void scripting::on_entity_spawn( lua::pushvalue(L, -1); } for (auto& component : components) { - auto compenv = create_component_environment( - get_root_environment(), -1, component->name); + auto compenv = create_component_environment(get_root_environment(), -1, + component->name); lua::get_from(L, lua::CHUNKS_TABLE, component->name, true); lua::pushenv(L, *compenv); + lua::pushvalue(L, args); lua::setfield(L, "ARGS"); + + lua::createtable(L, 0, 0); + lua::setfield(L, "SAVED_DATA"); + lua::setfenv(L); lua::call_nothrow(L, 0, 0); @@ -379,7 +393,6 @@ void scripting::on_trigger_enter(const Entity& entity, size_t index, entityid_t } } - void scripting::on_trigger_exit(const Entity& entity, size_t index, entityid_t oid) { const auto& script = entity.getScripting(); for (auto& component : script.components) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index cb063acc..328068f2 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -76,6 +76,7 @@ namespace scripting { /// @return true if prevents default action bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); + dynamic::Value get_component_value(const scriptenv& env, const std::string& name); void on_entity_spawn( const EntityDef& def, entityid_t eid, diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 2b18a46b..38d21585 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -112,6 +112,10 @@ void Entities::despawn(entityid_t id) { } } +void Entities::onSave(const Entity& entity) { + scripting::on_entity_save(entity); +} + dynamic::Value Entities::serialize(const Entity& entity) { auto root = dynamic::create_map(); auto& eid = entity.getID(); @@ -140,7 +144,6 @@ dynamic::Value Entities::serialize(const Entity& entity) { if (rig.config->getName() != def.rigName) { root->put("rig", rig.config->getName()); } - if (def.save.rig.pose || def.save.rig.textures) { auto& rigmap = root->putMap("rig"); if (def.save.rig.textures) { @@ -156,6 +159,14 @@ dynamic::Value Entities::serialize(const Entity& entity) { } } } + auto& scripts = entity.getScripting(); + if (!scripts.components.empty()) { + auto& compsMap = root->putMap("comps"); + for (auto& comp : scripts.components) { + auto data = scripting::get_component_value(comp->env, "SAVED_DATA"); + compsMap.put(comp->name, data); + } + } return root; } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 3c0c3c95..51bfe0db 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -183,6 +183,7 @@ public: return std::nullopt; } + void onSave(const Entity& entity); std::vector getAllInside(AABB aabb); void despawn(entityid_t id); dynamic::Value serialize(const Entity& entity); diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 2b02b974..ca35c798 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -713,6 +713,7 @@ void Chunks::save(Chunk* chunk) { auto root = dynamic::create_map(); auto& list = root->putList("data"); for (auto& entity : entities) { + level->entities->onSave(entity); list.put(level->entities->serialize(entity)); } if (!entities.empty()) { From c8666910ce23bb02c82bacabec5fd7c3d502179d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 5 Jul 2024 22:51:03 +0300 Subject: [PATCH 070/178] feat: loading entities (WIP) --- res/content/base/scripts/components/drop.lua | 12 +++- src/content/ContentLoader.cpp | 2 +- src/data/dynamic.cpp | 8 +-- src/data/dynamic.hpp | 4 +- src/data/dynamic_util.hpp | 9 +++ src/files/WorldRegions.cpp | 9 +++ src/files/WorldRegions.hpp | 2 + src/logic/scripting/lua/libentity.cpp | 5 +- src/logic/scripting/scripting.cpp | 13 +++- src/logic/scripting/scripting.hpp | 3 +- src/objects/Entities.cpp | 62 +++++++++++++++++--- src/objects/Entities.hpp | 8 ++- src/objects/Player.cpp | 17 +++--- src/objects/rigging.cpp | 6 +- src/voxels/ChunksStorage.cpp | 5 ++ src/world/World.cpp | 2 +- 16 files changed, 129 insertions(+), 38 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index f22e1ad2..1b67eeaf 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -6,15 +6,21 @@ inair = true ready = false target = -1 -local dropitem = ARGS.item +ARGS = ARGS or {} +local dropitem = ARGS.item or {} +if SAVED_DATA.item then + dropitem.id = item.index(SAVED_DATA.item) + dropitem.count = SAVED_DATA.count +end + local scale = {1, 1, 1} local rotation = mat4.rotate({ math.random(), math.random(), math.random() }, 360) function on_save() - SAVED_DATA.test = 5 - print("SAVE ENTITY") + SAVED_DATA.item = item.name(dropitem.id) + SAVED_DATA.count = dropitem.count end do -- setup visuals diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index d62277c7..37b96946 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -144,7 +144,7 @@ void ContentLoader::loadBlock(Block& def, const std::string& name, const fs::pat else if (model == "custom") { def.model = BlockModel::custom; if (root->has("model-primitives")) { - loadCustomBlockModel(def, root->map("model-primitives")); + loadCustomBlockModel(def, root->map("model-primitives").get()); } else { logger.error() << name << ": no 'model-primitives' found"; } diff --git a/src/data/dynamic.cpp b/src/data/dynamic.cpp index 0cc88103..a7e78a44 100644 --- a/src/data/dynamic.cpp +++ b/src/data/dynamic.cpp @@ -55,9 +55,9 @@ integer_t List::integer(size_t index) const { } } -Map* List::map(size_t index) const { +const Map_sptr& List::map(size_t index) const { if (auto* val = std::get_if(&values[index])) { - return val->get(); + return *val; } else { throw std::runtime_error("type error"); } @@ -192,11 +192,11 @@ void Map::num(const std::string& key, uint& dst) const { dst = get(key, static_cast(dst)); } -Map* Map::map(const std::string& key) const { +Map_sptr Map::map(const std::string& key) const { auto found = values.find(key); if (found != values.end()) { if (auto* val = std::get_if(&found->second)) { - return val->get(); + return *val; } } return nullptr; diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index 1153697f..902a5adc 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -47,7 +47,7 @@ namespace dynamic { std::string str(size_t index) const; number_t num(size_t index) const; integer_t integer(size_t index) const; - Map* map(size_t index) const; + const Map_sptr& map(size_t index) const; List* list(size_t index) const; bool flag(size_t index) const; @@ -114,7 +114,7 @@ namespace dynamic { void num(const std::string& key, uint64_t& dst) const; void num(const std::string& key, ubyte& dst) const; void num(const std::string& key, double& dst) const; - Map* map(const std::string& key) const; + Map_sptr map(const std::string& key) const; List* list(const std::string& key) const; void flag(const std::string& key, bool& dst) const; diff --git a/src/data/dynamic_util.hpp b/src/data/dynamic_util.hpp index 3a10a123..d9e5566e 100644 --- a/src/data/dynamic_util.hpp +++ b/src/data/dynamic_util.hpp @@ -25,6 +25,15 @@ namespace dynamic { } return list; } + + template + void get_vec(const dynamic::Map_sptr& root, const std::string& name, glm::vec& vec) { + if (const auto& list = root->list(name)) { + for (size_t i = 0; i < n; i++) { + vec[i] = list->num(i); + } + } + } } #endif // DATA_DYNAMIC_UTIL_HPP_ diff --git a/src/files/WorldRegions.cpp b/src/files/WorldRegions.cpp index 9bec7921..6d2485d7 100644 --- a/src/files/WorldRegions.cpp +++ b/src/files/WorldRegions.cpp @@ -435,6 +435,15 @@ chunk_inventories_map WorldRegions::fetchInventories(int x, int z) { return meta; } + dynamic::Map_sptr WorldRegions::fetchEntities(int x, int z) { + uint32_t bytesSize; + const ubyte* data = getData(x, z, REGION_LAYER_ENTITIES, bytesSize); + if (data == nullptr) { + return nullptr; + } + return json::from_binary(data, bytesSize); + } + void WorldRegions::processRegionVoxels(int x, int z, const regionproc& func) { if (getRegion(x, z, REGION_LAYER_VOXELS)) { throw std::runtime_error("not implemented for in-memory regions"); diff --git a/src/files/WorldRegions.hpp b/src/files/WorldRegions.hpp index f96477de..f681794d 100644 --- a/src/files/WorldRegions.hpp +++ b/src/files/WorldRegions.hpp @@ -5,6 +5,7 @@ #include "../typedefs.hpp" #include "../util/BufferPool.hpp" #include "../voxels/Chunk.hpp" +#include "../data/dynamic_fwd.hpp" #include #include @@ -185,6 +186,7 @@ public: std::unique_ptr getChunk(int x, int z); std::unique_ptr getLights(int x, int z); chunk_inventories_map fetchInventories(int x, int z); + dynamic::Map_sptr fetchEntities(int x, int z); void processRegionVoxels(int x, int z, const regionproc& func); diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 224c112f..c271062a 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -37,7 +37,10 @@ static int l_spawn(lua::State* L) { if (lua::gettop(L) > 2) { args = lua::tovalue(L, 3); } - level->entities->spawn(scripting::engine->getAssets(), def, pos, args); + Transform transform { + pos, glm::vec3(1.0f), glm::mat3(1.0f), {}, true + }; + level->entities->spawn(scripting::engine->getAssets(), def, transform, args); return 1; } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 8c5c16d3..2e6e76d6 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -276,7 +276,8 @@ void scripting::on_entity_spawn( const EntityDef& def, entityid_t eid, const std::vector>& components, - dynamic::Value args + dynamic::Value args, + dynamic::Map_sptr saved ) { auto L = lua::get_main_thread(); lua::requireglobal(L, STDCOMP); @@ -296,7 +297,15 @@ void scripting::on_entity_spawn( lua::pushvalue(L, args); lua::setfield(L, "ARGS"); - lua::createtable(L, 0, 0); + if (saved == nullptr) { + lua::createtable(L, 0, 0); + } else { + if (auto datamap = saved->map(component->name)) { + lua::pushvalue(L, datamap); + } else { + lua::createtable(L, 0, 0); + } + } lua::setfield(L, "SAVED_DATA"); lua::setfenv(L); diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 328068f2..ad0471fe 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -81,7 +81,8 @@ namespace scripting { const EntityDef& def, entityid_t eid, const std::vector>& components, - dynamic::Value args + dynamic::Value args, + dynamic::Map_sptr saved ); bool on_entity_despawn(const EntityDef& def, const Entity& entity); bool on_entity_grounded(const Entity& entity, float force); diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 38d21585..f514d6cc 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -1,8 +1,10 @@ #include "Entities.hpp" +#include "../debug/Logger.hpp" #include "../data/dynamic_util.hpp" #include "../assets/Assets.hpp" #include "../world/Level.hpp" +#include "../content/Content.hpp" #include "../physics/Hitbox.hpp" #include "../physics/PhysicsSolver.hpp" #include "../graphics/render/ModelBatch.hpp" @@ -12,9 +14,12 @@ #include "../objects/EntityDef.hpp" #include "../objects/rigging.hpp" #include "../logic/scripting/scripting.hpp" +#include "../engine.hpp" #include +static debug::Logger logger("entities"); + void Transform::refresh() { combined = glm::mat4(1.0f); combined = glm::translate(combined, pos); @@ -57,20 +62,26 @@ static triggercallback create_trigger_callback(Entities* entities) { entityid_t Entities::spawn( Assets* assets, EntityDef& def, - glm::vec3 pos, - dynamic::Value args) + Transform transform, + dynamic::Value args, + dynamic::Map_sptr saved, + entityid_t uid) { auto rig = assets->get(def.rigName); if (rig == nullptr) { throw std::runtime_error("rig "+def.rigName+" not found"); } auto entity = registry.create(); - glm::vec3 size(1); - auto id = nextID++; + entityid_t id; + if (uid == 0) { + id = nextID++; + } else { + id = uid; + } registry.emplace(entity, static_cast(id), def); - registry.emplace(entity, pos, size, glm::mat3(1.0f)); + registry.emplace(entity, transform); auto& body = registry.emplace( - entity, true, Hitbox {pos, def.hitbox}, std::vector{}); + entity, true, Hitbox {transform.pos, def.hitbox}, std::vector{}); body.triggers.resize(def.radialTriggers.size() + def.boxTriggers.size()); for (auto& [i, box] : def.boxTriggers) { @@ -98,7 +109,8 @@ entityid_t Entities::spawn( componentName, entity_funcs_set {}, nullptr); scripting.components.emplace_back(std::move(component)); } - scripting::on_entity_spawn(def, id, scripting.components, std::move(args)); + scripting::on_entity_spawn( + def, id, scripting.components, std::move(args), std::move(saved)); return id; } @@ -112,6 +124,37 @@ void Entities::despawn(entityid_t id) { } } +void Entities::loadEntity(const dynamic::Map_sptr& map) { + entityid_t uid = 0; + std::string defname; + map->num("uid", uid); + map->str("def", defname); + if (uid == 0) { + throw std::runtime_error("could not read entity - invalid UID"); + } + auto& def = level->content->entities.require(defname); + Transform transform { + glm::vec3(), glm::vec3(1.0f), glm::mat3(1.0f), {}, true + }; + if (auto tsfmap = map->map("transform")) { + dynamic::get_vec(tsfmap, "pos", transform.pos); + } + dynamic::Map_sptr savedMap = map->map("comps"); + auto assets = scripting::engine->getAssets(); + spawn(assets, def, transform, dynamic::NONE, savedMap, uid); +} + +void Entities::loadEntities(dynamic::Map_sptr root) { + auto list = root->list("data"); + for (size_t i = 0; i < list->size(); i++) { + try { + loadEntity(list->map(i)); + } catch (const std::runtime_error& err) { + logger.error() << "could not read entity: " << err.what(); + } + } +} + void Entities::onSave(const Entity& entity) { scripting::on_entity_save(entity); } @@ -129,7 +172,9 @@ dynamic::Value Entities::serialize(const Entity& entity) { if (transform.size != glm::vec3(1.0f)) { tsfmap.put("size", dynamic::to_value(transform.size)); } - tsfmap.put("rot", dynamic::to_value(transform.rot)); + if (transform.rot != glm::mat3(1.0f)) { + tsfmap.put("rot", dynamic::to_value(transform.rot)); + } } { auto& rigidbody = entity.getRigidbody(); @@ -166,6 +211,7 @@ dynamic::Value Entities::serialize(const Entity& entity) { auto data = scripting::get_component_value(comp->env, "SAVED_DATA"); compsMap.put(comp->name, data); } + std::cout << root << std::endl; } return root; } diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 51bfe0db..8492186c 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -172,8 +172,10 @@ public: entityid_t spawn( Assets* assets, EntityDef& def, - glm::vec3 pos, - dynamic::Value args=dynamic::NONE); + Transform transform, + dynamic::Value args=dynamic::NONE, + dynamic::Map_sptr saved=nullptr, + entityid_t uid=0); std::optional get(entityid_t id) { const auto& found = entities.find(id); @@ -183,6 +185,8 @@ public: return std::nullopt; } + void loadEntities(dynamic::Map_sptr map); + void loadEntity(const dynamic::Map_sptr& map); void onSave(const Entity& entity); std::vector getAllInside(AABB aabb); void despawn(entityid_t id); diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 91301c52..1cb1614a 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -251,10 +251,9 @@ void Player::deserialize(dynamic::Map *src) { src->flag("flight", flight); src->flag("noclip", noclip); setChosenSlot(src->get("chosen-slot", getChosenSlot())); - - auto invmap = src->map("inventory"); - if (invmap) { - getInventory()->deserialize(invmap); + + if (auto invmap = src->map("inventory")) { + getInventory()->deserialize(invmap.get()); } } @@ -264,16 +263,14 @@ void Player::convert(dynamic::Map* data, const ContentLUT* lut) { if (players) { for (uint i = 0; i < players->size(); i++) { auto playerData = players->map(i); - auto inventory = playerData->map("inventory"); - if (inventory) { - Inventory::convert(inventory, lut); + if (auto inventory = playerData->map("inventory")) { + Inventory::convert(inventory.get(), lut); } } } else { - auto inventory = data->map("inventory"); - if (inventory) { - Inventory::convert(inventory, lut); + if (auto inventory = data->map("inventory")) { + Inventory::convert(inventory.get(), lut); } } } diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index 275577aa..fc21cb41 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -94,8 +94,8 @@ static std::tuple> read_node( size_t count = 1; if (auto nodesList = root->list("nodes")) { for (size_t i = 0; i < nodesList->size(); i++) { - if (auto map = nodesList->map(i)) { - auto [subcount, subNode] = read_node(map, index+count); + if (const auto& map = nodesList->map(i)) { + auto [subcount, subNode] = read_node(map.get(), index+count); subcount += count; subnodes.push_back(std::move(subNode)); } @@ -114,6 +114,6 @@ std::unique_ptr RigConfig::parse( if (rootNodeMap == nullptr) { throw std::runtime_error("missing 'root' element"); } - auto [count, rootNode] = read_node(rootNodeMap, 0); + auto [count, rootNode] = read_node(rootNodeMap.get(), 0); return std::make_unique(std::string(name), std::move(rootNode), count); } diff --git a/src/voxels/ChunksStorage.cpp b/src/voxels/ChunksStorage.cpp index 73b690af..bac62015 100644 --- a/src/voxels/ChunksStorage.cpp +++ b/src/voxels/ChunksStorage.cpp @@ -5,6 +5,7 @@ #include "Block.hpp" #include "../content/Content.hpp" #include "../files/WorldFiles.hpp" +#include "../objects/Entities.hpp" #include "../world/Level.hpp" #include "../world/World.hpp" #include "../maths/voxmaths.hpp" @@ -63,6 +64,10 @@ std::shared_ptr ChunksStorage::create(int x, int z) { auto invs = regions.fetchInventories(chunk->x, chunk->z); chunk->setBlockInventories(std::move(invs)); + if (auto map = regions.fetchEntities(chunk->x, chunk->z)) { + level->entities->loadEntities(std::move(map)); + } + chunk->flags.loaded = true; for(auto& entry : chunk->inventories) { level->inventories->store(entry.second); diff --git a/src/world/World.cpp b/src/world/World.cpp index e16b5e6e..0b10dc33 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -110,7 +110,7 @@ std::unique_ptr World::load( DEF_PLAYER_SPEED, level->inventories->create(DEF_PLAYER_INVENTORY_SIZE) ); - player->deserialize(players->map(i)); + player->deserialize(players->map(i).get()); level->inventories->store(player->getInventory()); } } else { From f4d3e62b3f9aaf869530e273c3c6efeb78b29679 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 5 Jul 2024 23:26:17 +0300 Subject: [PATCH 071/178] add chunk 'entities' flag --- src/files/WorldRegions.cpp | 8 ++++++-- src/voxels/Chunk.hpp | 1 + src/voxels/Chunks.cpp | 2 +- src/voxels/ChunksStorage.cpp | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/files/WorldRegions.cpp b/src/files/WorldRegions.cpp index 6d2485d7..92feacda 100644 --- a/src/files/WorldRegions.cpp +++ b/src/files/WorldRegions.cpp @@ -360,7 +360,7 @@ void WorldRegions::put(Chunk* chunk, std::vector entitiesData){ return; } bool lightsUnsaved = !chunk->flags.loadedLights && doWriteLights; - if (!chunk->flags.unsaved && !lightsUnsaved) { + if (!chunk->flags.unsaved && !lightsUnsaved && !chunk->flags.entities) { return; } @@ -441,7 +441,11 @@ chunk_inventories_map WorldRegions::fetchInventories(int x, int z) { if (data == nullptr) { return nullptr; } - return json::from_binary(data, bytesSize); + auto map = json::from_binary(data, bytesSize); + if (map->size() == 0) { + return nullptr; + } + return map; } void WorldRegions::processRegionVoxels(int x, int z, const regionproc& func) { diff --git a/src/voxels/Chunk.hpp b/src/voxels/Chunk.hpp index a0157763..b04accc6 100644 --- a/src/voxels/Chunk.hpp +++ b/src/voxels/Chunk.hpp @@ -35,6 +35,7 @@ public: bool lighted: 1; bool unsaved: 1; bool loadedLights: 1; + bool entities: 1; } flags {}; /// @brief Block inventories map where key is index of block in voxels array diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index ca35c798..6f365c44 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -717,7 +717,7 @@ void Chunks::save(Chunk* chunk) { list.put(level->entities->serialize(entity)); } if (!entities.empty()) { - chunk->flags.unsaved = true; + chunk->flags.entities = true; } worldFiles->getRegions().put(chunk, json::to_binary(root, true)); } diff --git a/src/voxels/ChunksStorage.cpp b/src/voxels/ChunksStorage.cpp index bac62015..3231ce35 100644 --- a/src/voxels/ChunksStorage.cpp +++ b/src/voxels/ChunksStorage.cpp @@ -66,6 +66,7 @@ std::shared_ptr ChunksStorage::create(int x, int z) { if (auto map = regions.fetchEntities(chunk->x, chunk->z)) { level->entities->loadEntities(std::move(map)); + chunk->flags.entities = true; } chunk->flags.loaded = true; From cf2faa4a0109678be3ddef12a514aeb52060de8a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 5 Jul 2024 23:41:55 +0300 Subject: [PATCH 072/178] implement nextEntityID save/load --- src/frontend/debug_panel.cpp | 3 ++- src/objects/Entities.hpp | 8 ++++++++ src/world/Level.cpp | 1 + src/world/World.cpp | 5 +++++ src/world/World.hpp | 2 ++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index 6960a6e9..59741526 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -85,7 +85,8 @@ std::shared_ptr create_debug_panel( L" visible: "+std::to_wstring(level->chunks->visible); })); panel->add(create_label([=]() { - return L"entities: "+std::to_wstring(level->entities->size()); + return L"entities: "+std::to_wstring(level->entities->size())+L" next: "+ + std::to_wstring(level->entities->peekNextID()); })); panel->add(create_label([=](){ const auto& vox = player->selection.vox; diff --git a/src/objects/Entities.hpp b/src/objects/Entities.hpp index 8492186c..579c1ec0 100644 --- a/src/objects/Entities.hpp +++ b/src/objects/Entities.hpp @@ -192,9 +192,17 @@ public: void despawn(entityid_t id); dynamic::Value serialize(const Entity& entity); + void setNextID(entityid_t id) { + nextID = id; + } + inline size_t size() const { return entities.size(); } + + inline entityid_t peekNextID() const { + return nextID; + } }; #endif // OBJECTS_ENTITIES_HPP_ diff --git a/src/world/Level.cpp b/src/world/Level.cpp index e057708d..fc0549ab 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -26,6 +26,7 @@ Level::Level( entities(std::make_unique(this)), settings(settings) { + entities->setNextID(this->world->nextEntityId); auto inv = std::make_shared( this->world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE ); diff --git a/src/world/World.cpp b/src/world/World.cpp index 0b10dc33..9c85e38b 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -9,10 +9,12 @@ #include "../files/WorldFiles.hpp" #include "../items/Inventories.hpp" #include "../objects/Player.hpp" +#include "../objects/Entities.hpp" #include "../voxels/Chunk.hpp" #include "../voxels/Chunks.hpp" #include "../voxels/ChunksStorage.hpp" #include "../world/WorldGenerators.hpp" +#include "Level.hpp" #include #include @@ -52,6 +54,7 @@ void World::updateTimers(float delta) { void World::write(Level* level) { const Content* content = level->content; level->chunks->saveAll(); + nextEntityId = level->entities->peekNextID(); wfile->write(this, content); auto playerFile = dynamic::Map(); @@ -193,6 +196,7 @@ void World::deserialize(dynamic::Map* root) { weatherobj->num("fog", fog); } nextInventoryId = root->get("next-inventory-id", 2); + nextEntityId = root->get("next-entity-id", 1); } std::unique_ptr World::serialize() const { @@ -215,5 +219,6 @@ std::unique_ptr World::serialize() const { weatherobj.put("fog", fog); root->put("next-inventory-id", nextInventoryId); + root->put("next-entity-id", nextEntityId); return root; } diff --git a/src/world/World.hpp b/src/world/World.hpp index 904ed027..6926dcf6 100644 --- a/src/world/World.hpp +++ b/src/world/World.hpp @@ -51,6 +51,8 @@ public: /// @brief will be replaced with weather in future float fog = 0.0f; + entityid_t nextEntityId = 0; + World( std::string name, std::string generator, From e6d4688f034873bd702bf55eae6db68390a65ef9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 6 Jul 2024 01:30:43 +0300 Subject: [PATCH 073/178] despawn entities after chunk unload --- src/voxels/Chunks.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 6f365c44..ca9abd13 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -715,6 +715,7 @@ void Chunks::save(Chunk* chunk) { for (auto& entity : entities) { level->entities->onSave(entity); list.put(level->entities->serialize(entity)); + entity.destroy(); } if (!entities.empty()) { chunk->flags.entities = true; From 0f26bbadfd5f053e127c68cb23809b76a6472015 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 6 Jul 2024 01:34:52 +0300 Subject: [PATCH 074/178] fix Block.rt and ItemDef.rt initialization --- src/items/ItemDef.hpp | 2 +- src/voxels/Block.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/items/ItemDef.hpp b/src/items/ItemDef.hpp index 015cfb21..12100fb3 100644 --- a/src/items/ItemDef.hpp +++ b/src/items/ItemDef.hpp @@ -41,7 +41,7 @@ struct ItemDef { item_funcs_set funcsset {}; blockid_t placingBlock; bool emissive = false; - } rt; + } rt {}; ItemDef(const std::string& name); ItemDef(const ItemDef&) = delete; diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 90ae2f6a..23ecdc26 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -195,7 +195,7 @@ public: /// @brief picking item integer id itemid_t pickingItem = 0; - } rt; + } rt {}; Block(const std::string& name); Block(std::string name, const std::string& texture); From 623b6ad8be2b8da210506885b18dca9f51425c6a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 6 Jul 2024 01:37:18 +0300 Subject: [PATCH 075/178] remove extra debug output --- src/objects/Entities.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index f514d6cc..7a305fee 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -211,7 +211,6 @@ dynamic::Value Entities::serialize(const Entity& entity) { auto data = scripting::get_component_value(comp->env, "SAVED_DATA"); compsMap.put(comp->name, data); } - std::cout << root << std::endl; } return root; } From 9efb327270d43be3a284d91ebd38fe8fad4a64d7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 6 Jul 2024 02:55:19 +0300 Subject: [PATCH 076/178] refactor: minor cleanup --- src/objects/Entities.cpp | 8 ++++---- src/objects/EntityDef.hpp | 4 ++-- src/world/Level.hpp | 2 -- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 7a305fee..88f72538 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -193,8 +193,8 @@ dynamic::Value Entities::serialize(const Entity& entity) { auto& rigmap = root->putMap("rig"); if (def.save.rig.textures) { auto& map = rigmap.putMap("textures"); - for (auto& entry : rig.textures) { - map.put(entry.first, entry.second); + for (auto& [slot, texture] : rig.textures) { + map.put(slot, texture); } } if (def.save.rig.pose) { @@ -363,8 +363,8 @@ std::vector Entities::getAllInside(AABB aabb) { if (found == uids.end()) { continue; } - if (auto entity = get(found->second)) { - collected.push_back(*entity); + if (auto wrapper = get(found->second)) { + collected.push_back(*wrapper); } } } diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index 1abfca14..47fc906c 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -21,7 +21,7 @@ struct EntityDef { glm::vec3 hitbox {0.5f}; std::vector> boxTriggers {}; std::vector> radialTriggers {}; - std::string rigName = name.substr(name.find(":")+1); + std::string rigName = name.substr(name.find(":") + 1); struct { bool enabled = true; @@ -35,7 +35,7 @@ struct EntityDef { entityid_t id; rigging::RigConfig* rig; } rt {}; - + EntityDef(const std::string& name) : name(name) {} EntityDef(const EntityDef&) = delete; }; diff --git a/src/world/Level.hpp b/src/world/Level.hpp index 3f57ac10..4b5a1f53 100644 --- a/src/world/Level.hpp +++ b/src/world/Level.hpp @@ -12,10 +12,8 @@ inline constexpr int DEF_PLAYER_INVENTORY_SIZE = 40; class Content; class World; -class Player; class Chunks; class Entities; -class Inventory; class Inventories; class LevelEvents; class Lighting; From 5522cfc231219d28723bf588b79404668ed4462a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 6 Jul 2024 05:36:16 +0300 Subject: [PATCH 077/178] add "Show Hitboxes" to the debug panel --- src/frontend/debug_panel.cpp | 13 +++++++++++++ src/graphics/render/WorldRenderer.cpp | 3 ++- src/graphics/render/WorldRenderer.hpp | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index 59741526..663670ac 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -33,6 +33,7 @@ static std::shared_ptr