From d8c9fa1fe25618372c4aebc340ca9192d5e7758b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 9 Jul 2024 21:19:29 +0300 Subject: [PATCH] loading rig pose, textures, body settings --- .../base/scripts/components/falling_block.lua | 3 +- src/assets/AssetsLoader.cpp | 10 ++--- src/content/ContentLUT.cpp | 6 +-- src/content/ContentLoader.cpp | 2 + src/data/dynamic.cpp | 4 +- src/data/dynamic.hpp | 2 +- src/data/dynamic_util.hpp | 31 ++++++++++++++ src/logic/PlayerController.cpp | 9 ++-- src/objects/Entities.cpp | 41 ++++++++++++++++++- src/objects/EntityDef.hpp | 4 ++ src/objects/Player.cpp | 1 + 11 files changed, 96 insertions(+), 17 deletions(-) diff --git a/res/content/base/scripts/components/falling_block.lua b/res/content/base/scripts/components/falling_block.lua index 959ceaec..44345ec6 100644 --- a/res/content/base/scripts/components/falling_block.lua +++ b/res/content/base/scripts/components/falling_block.lua @@ -25,7 +25,8 @@ function on_grounded() if block.is_replaceable_at(ix, iy, iz) then block.set(ix, iy, iz, block.index(blockid)) else - entities.spawn("base:drop", pos, {item={id=item.index(blockid..".item"), count=1}}) + local picking_item = block.get_picking_item(block.index(blockid)) + entities.spawn("base:drop", pos, {item={id=picking_item, count=1}}) end entity:despawn() end diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index ad836ae4..5deb4b5a 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -153,11 +153,11 @@ 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").get()); + processPreloadList(AssetType::SHADER, root->list("shaders").get()); + processPreloadList(AssetType::TEXTURE, root->list("textures").get()); + processPreloadList(AssetType::SOUND, root->list("sounds").get()); + processPreloadList(AssetType::MODEL, root->list("models").get()); // layouts are loaded automatically } diff --git a/src/content/ContentLUT.cpp b/src/content/ContentLUT.cpp index 53245444..5aa95bc3 100644 --- a/src/content/ContentLUT.cpp +++ b/src/content/ContentLUT.cpp @@ -14,7 +14,7 @@ ContentLUT::ContentLUT(const ContentIndices* indices, size_t blocksCount, size_t {} template static constexpr size_t get_entries_count( - const ContentUnitIndices& indices, dynamic::List* list) { + const ContentUnitIndices& indices, const dynamic::List_sptr& list) { return list ? std::max(list->size(), indices.count()) : indices.count(); } @@ -32,8 +32,8 @@ std::shared_ptr ContentLUT::create( auto lut = std::make_shared(indices, blocks_c, items_c); - lut->blocks.setup(blocklist, content->blocks); - lut->items.setup(itemlist, content->items); + lut->blocks.setup(blocklist.get(), content->blocks); + lut->items.setup(itemlist.get(), content->items); if (lut->hasContentReorder() || lut->hasMissingContent()) { return lut; diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index efc5b361..1c7c659b 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -338,6 +338,8 @@ void ContentLoader::loadEntity(EntityDef& def, const std::string& name, const fs root->flag("save", def.save.enabled); root->flag("save-rig-pose", def.save.rig.pose); root->flag("save-rig-textures", def.save.rig.textures); + root->flag("save-body-velocity", def.save.body.velocity); + root->flag("save-body-settings", def.save.body.settings); std::string bodyTypeName; root->str("body-type", bodyTypeName); diff --git a/src/data/dynamic.cpp b/src/data/dynamic.cpp index a7e78a44..d8819bcd 100644 --- a/src/data/dynamic.cpp +++ b/src/data/dynamic.cpp @@ -202,10 +202,10 @@ Map_sptr Map::map(const std::string& key) const { return nullptr; } -List* Map::list(const std::string& key) const { +List_sptr Map::list(const std::string& key) const { auto found = values.find(key); if (found != values.end()) - return std::get(found->second).get(); + return std::get(found->second); return nullptr; } diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index 902a5adc..90f4fe69 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -115,7 +115,7 @@ namespace dynamic { void num(const std::string& key, ubyte& dst) const; void num(const std::string& key, double& dst) const; Map_sptr map(const std::string& key) const; - List* list(const std::string& key) const; + List_sptr list(const std::string& key) const; void flag(const std::string& key, bool& dst) const; Map& put(std::string key, std::unique_ptr value) { diff --git a/src/data/dynamic_util.hpp b/src/data/dynamic_util.hpp index d9e5566e..576d84e4 100644 --- a/src/data/dynamic_util.hpp +++ b/src/data/dynamic_util.hpp @@ -34,6 +34,37 @@ namespace dynamic { } } } + + template + void get_vec(const dynamic::List_sptr& root, size_t index, glm::vec& vec) { + if (const auto& list = root->list(index)) { + for (size_t i = 0; i < n; i++) { + vec[i] = list->num(i); + } + } + } + + template + void get_mat(const dynamic::Map_sptr& root, const std::string& name, glm::mat& mat) { + if (const auto& list = root->list(name)) { + for (size_t y = 0; y < n; y++) { + for (size_t x = 0; x < m; x++) { + mat[y][x] = list->num(y*m+x); + } + } + } + } + + template + void get_mat(const dynamic::List_sptr& root, size_t index, glm::mat& mat) { + if (const auto& list = root->list(index)) { + for (size_t y = 0; y < n; y++) { + for (size_t x = 0; x < m; x++) { + mat[y][x] = list->num(y*m+x); + } + } + } + } } #endif // DATA_DYNAMIC_UTIL_HPP_ diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 3fcd7202..006510ec 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -161,12 +161,14 @@ void CameraControl::update(const PlayerInput& input, float delta, Chunks* chunks auto tpCamera = player->tpCamera; if (player->currentCamera == spCamera) { - spCamera->position = chunks->rayCastToObstacle(camera->position, camera->front, 3.0f) - 0.2f * camera->front; + spCamera->position = chunks->rayCastToObstacle( + camera->position, camera->front, 3.0f) - 0.2f * camera->front; spCamera->dir = -camera->dir; spCamera->front = -camera->front; } else if (player->currentCamera == tpCamera) { - tpCamera->position = chunks->rayCastToObstacle(camera->position, -camera->front, 3.0f) + 0.2f * camera->front; + tpCamera->position = chunks->rayCastToObstacle( + camera->position, -camera->front, 3.0f) + 0.2f * camera->front; tpCamera->dir = camera->dir; tpCamera->front = camera->front; } @@ -324,7 +326,8 @@ static int determine_rotation(Block* def, const glm::ivec3& norm, glm::vec3& cam return 0; } -static void pick_block(ContentIndices* indices, Chunks* chunks, Player* player, int x, int y, int z) { +static void pick_block(ContentIndices* indices, Chunks* chunks, Player* player, + int x, int y, int z) { auto block = indices->blocks.get(chunks->get(x,y,z)->id); itemid_t id = block->rt.pickingItem; auto inventory = player->getInventory(); diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 83ccb181..b8726efc 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -149,13 +149,39 @@ void Entities::loadEntity(const dynamic::Map_sptr& map) { void Entities::loadEntity(const dynamic::Map_sptr& map, Entity entity) { auto& transform = entity.getTransform(); auto& body = entity.getRigidbody(); + auto& rig = entity.getModeltree(); if (auto bodymap = map->map(COMP_RIGIDBODY)) { dynamic::get_vec(bodymap, "vel", body.hitbox.velocity); + std::string bodyTypeName; + bodymap->str("type", bodyTypeName); + if (auto bodyType = BodyType_from(bodyTypeName)) { + body.hitbox.type = *bodyType; + } + bodymap->flag("crouch", body.hitbox.crouching); + bodymap->num("damping", body.hitbox.linearDamping); } if (auto tsfmap = map->map(COMP_TRANSFORM)) { dynamic::get_vec(tsfmap, "pos", transform.pos); dynamic::get_vec(tsfmap, "size", transform.size); + dynamic::get_mat(tsfmap, "rot", transform.rot); + } + std::string rigName = rig.config->getName(); + map->str("rig", rigName); + if (rigName != rig.config->getName()) { + rig.config = level->content->getRig(rigName); + } + if (auto rigmap = map->map(COMP_MODELTREE)) { + if (auto texturesmap = rigmap->map("textures")) { + for (auto& [slot, _] : texturesmap->values) { + texturesmap->str(slot, rig.textures[slot]); + } + } + if (auto posearr = rigmap->list("pose")) { + for (size_t i = 0; i < std::min(rig.pose.matrices.size(), posearr->size()); i++) { + dynamic::get_mat(posearr, i, rig.pose.matrices[i]); + } + } } } @@ -193,12 +219,23 @@ dynamic::Value Entities::serialize(const Entity& entity) { } { auto& rigidbody = entity.getRigidbody(); + auto& hitbox = rigidbody.hitbox; auto& bodymap = root->putMap(COMP_RIGIDBODY); if (!rigidbody.enabled) { bodymap.put("enabled", rigidbody.enabled); } - bodymap.put("vel", dynamic::to_value(rigidbody.hitbox.velocity)); - bodymap.put("damping", rigidbody.hitbox.linearDamping); + if (def.save.body.velocity) { + bodymap.put("vel", dynamic::to_value(rigidbody.hitbox.velocity)); + } + if (def.save.body.settings) { + bodymap.put("damping", rigidbody.hitbox.linearDamping); + if (hitbox.type != def.bodyType) { + bodymap.put("type", to_string(hitbox.type)); + } + if (hitbox.crouching) { + bodymap.put("crouch", hitbox.crouching); + } + } } auto& rig = entity.getModeltree(); if (rig.config->getName() != def.rigName) { diff --git a/src/objects/EntityDef.hpp b/src/objects/EntityDef.hpp index 83bf579c..df9e5d18 100644 --- a/src/objects/EntityDef.hpp +++ b/src/objects/EntityDef.hpp @@ -31,6 +31,10 @@ struct EntityDef { bool textures = false; bool pose = false; } rig; + struct { + bool velocity = true; + bool settings = false; + } body; } save {}; struct { diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 679ef5dd..4c9e5067 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -123,6 +123,7 @@ void Player::updateInput(PlayerInput& input, float delta) { hitbox->velocity.y += 1.0f; } } + hitbox->type = noclip ? BodyType::KINEMATIC : BodyType::DYNAMIC; if (input.noclip) { noclip = !noclip; }