diff --git a/doc/ru/scripting/ecs.md b/doc/ru/scripting/ecs.md index 3d83eb21..6173e58e 100644 --- a/doc/ru/scripting/ecs.md +++ b/doc/ru/scripting/ecs.md @@ -132,4 +132,12 @@ rig:set_texture(key: str, value: str) -- Возвращает индекс кости по имени или nil rig:index(name: str) -> int + +-- Проверяет статус видимости кости по индесу +-- или всего скелета, если индекс не указан +rig:is_visible([optional] index: int) -> bool + +-- Устанавливает статус видимости кости по индексу +-- или всего скелета, если индекс не указан +rig:set_visible([optional] index: int, status: bool) ``` diff --git a/res/content/base/models/player-head.obj b/res/content/base/models/player-head.obj new file mode 100644 index 00000000..6a6a9024 --- /dev/null +++ b/res/content/base/models/player-head.obj @@ -0,0 +1,48 @@ +# Blender v2.79 (sub 0) OBJ File: 'player.blend' +# www.blender.org +mtllib player-head.mtl +o Cube.002_Cube.003 +v -0.238204 0.476553 -0.238204 +v -0.238204 0.000145 -0.238204 +v -0.238204 0.476553 0.238204 +v -0.238204 0.000145 0.238204 +v 0.238204 0.000145 0.238204 +v 0.238204 0.476553 0.238204 +v 0.238204 0.000145 -0.238204 +v 0.238204 0.476553 -0.238204 +vt 0.783122 0.009685 +vt 0.982503 0.009685 +vt 0.982503 0.209065 +vt 0.783122 0.209065 +vt 0.735873 0.213345 +vt 0.735873 0.739780 +vt 0.209439 0.739780 +vt 0.209439 0.213345 +vt 0.783122 0.009685 +vt 0.982503 0.009685 +vt 0.982503 0.209065 +vt 0.783122 0.209065 +vt 0.783122 0.009685 +vt 0.982503 0.009685 +vt 0.982503 0.209065 +vt 0.783122 0.209065 +vt 0.783122 0.009685 +vt 0.982503 0.009685 +vt 0.982503 0.209065 +vt 0.783122 0.009685 +vt 0.982503 0.009685 +vt 0.783122 0.209065 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl entities/player +s off +f 4/1/1 3/2/1 1/3/1 2/4/1 +f 2/5/2 1/6/2 8/7/2 7/8/2 +f 7/9/3 8/10/3 6/11/3 5/12/3 +f 5/13/4 6/14/4 3/15/4 4/16/4 +f 2/17/5 7/18/5 5/19/5 4/16/5 +f 8/20/6 1/21/6 3/15/6 6/22/6 diff --git a/res/content/base/models/player.obj b/res/content/base/models/player.obj index b038797f..d0be9e17 100644 --- a/res/content/base/models/player.obj +++ b/res/content/base/models/player.obj @@ -1,3 +1,6 @@ +# Blender v2.79 (sub 0) OBJ File: 'player.blend' +# www.blender.org +mtllib player.mtl o Cube v 0.125000 -0.900000 -0.125000 v 0.125000 -0.900000 0.125000 @@ -7,14 +10,6 @@ v 0.125000 0.700000 -0.125000 v 0.125000 0.700000 0.125000 v -0.125000 0.700000 0.125000 v -0.125000 0.700000 -0.125000 -v -0.238204 0.898288 -0.238204 -v -0.238204 0.421881 -0.238204 -v -0.238204 0.898288 0.238204 -v -0.238204 0.421881 0.238204 -v 0.238204 0.421881 0.238204 -v 0.238204 0.898288 0.238204 -v 0.238204 0.421881 -0.238204 -v 0.238204 0.898288 -0.238204 vt 0.783122 0.009685 vt 0.982503 0.009685 vt 0.982503 0.209065 @@ -35,28 +30,6 @@ vt 0.982503 0.209065 vt 0.982503 0.009685 vt 0.982503 0.209065 vt 0.783122 0.209065 -vt 0.783122 0.009685 -vt 0.982503 0.009685 -vt 0.982503 0.209065 -vt 0.783122 0.209065 -vt 0.735873 0.213345 -vt 0.735873 0.739780 -vt 0.209439 0.739780 -vt 0.209439 0.213345 -vt 0.783122 0.009685 -vt 0.982503 0.009685 -vt 0.982503 0.209065 -vt 0.783122 0.209065 -vt 0.783122 0.009685 -vt 0.982503 0.009685 -vt 0.982503 0.209065 -vt 0.783122 0.209065 -vt 0.783122 0.009685 -vt 0.982503 0.009685 -vt 0.982503 0.209065 -vt 0.783122 0.009685 -vt 0.982503 0.009685 -vt 0.783122 0.209065 vn 0.0000 -1.0000 -0.0000 vn 0.0000 1.0000 0.0000 vn 1.0000 0.0000 0.0000 @@ -71,9 +44,3 @@ 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 -f 12/21/5 11/22/5 9/23/5 10/24/5 -f 10/25/6 9/26/6 16/27/6 15/28/6 -f 15/29/3 16/30/3 14/31/3 13/32/3 -f 13/33/4 14/34/4 11/35/4 12/36/4 -f 10/37/1 15/38/1 13/39/1 12/36/1 -f 16/40/2 9/41/2 11/35/2 14/42/2 diff --git a/res/content/base/preload.json b/res/content/base/preload.json index caf81b1c..9a2905c7 100644 --- a/res/content/base/preload.json +++ b/res/content/base/preload.json @@ -8,6 +8,7 @@ "block", "drop-block", "drop-item", - "player" + "player", + "player-head" ] } diff --git a/res/content/base/skeletons/player.json b/res/content/base/skeletons/player.json index a2a41980..ce2be7b6 100644 --- a/res/content/base/skeletons/player.json +++ b/res/content/base/skeletons/player.json @@ -2,7 +2,14 @@ "root": { "nodes": [ { - "model": "player" + "name": "body", + "model": "player", + "nodes": [ + { + "name": "head", + "model": "player-head" + } + ] } ] } diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index dc653325..0860caa9 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -44,6 +44,8 @@ local Skeleton = {__index={ get_texture=function(self, s) return __skeleton.get_texture(self.eid, s) end, set_texture=function(self, s, s2) return __skeleton.set_texture(self.eid, s, s2) end, index=function(self, s) return __skeleton.index(self.eid, s) end, + is_visible=function(self, i) return __skeleton.is_visible(self.eid, i) end, + set_visible=function(self, i, b) return __skeleton.set_visible(self.eid, i, b) end, }} local function new_Skeleton(eid) diff --git a/src/logic/scripting/lua/lib__skeleton.cpp b/src/logic/scripting/lua/lib__skeleton.cpp index 3ea3a10b..936963c5 100644 --- a/src/logic/scripting/lua/lib__skeleton.cpp +++ b/src/logic/scripting/lua/lib__skeleton.cpp @@ -69,6 +69,31 @@ static int l_index(lua::State* L) { return 0; } +static int l_is_visible(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + auto& skeleton = entity->getSkeleton(); + if (!lua::isnoneornil(L, 2)) { + auto index = index_range_check(skeleton, lua::tointeger(L, 2)); + return lua::pushboolean(L, skeleton.flags.at(index).visible); + } + return lua::pushboolean(L, skeleton.visible); + } + return 0; +} + +static int l_set_visible(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + auto& skeleton = entity->getSkeleton(); + if (!lua::isnoneornil(L, 3)) { + auto index = index_range_check(skeleton, lua::tointeger(L, 2)); + skeleton.flags.at(index).visible = lua::toboolean(L, 3); + } else { + skeleton.visible = lua::toboolean(L, 2); + } + } + return 0; +} + const luaL_Reg skeletonlib [] = { {"get_model", lua::wrap}, {"get_matrix", lua::wrap}, @@ -76,5 +101,7 @@ const luaL_Reg skeletonlib [] = { {"get_texture", lua::wrap}, {"set_texture", lua::wrap}, {"index", lua::wrap}, + {"is_visible", lua::wrap}, + {"set_visible", lua::wrap}, {NULL, NULL} }; diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 80f99dd4..5a22221c 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -9,6 +9,7 @@ #include "../window/Camera.hpp" #include "../items/Inventory.hpp" #include "../objects/Entities.hpp" +#include "../objects/rigging.hpp" #include #include @@ -66,9 +67,18 @@ void Player::updateInput(PlayerInput& input, float delta) { return; } auto& hitbox = entity->getRigidbody().hitbox; - auto& transform = entity->getTransform(); - transform.setRot( - glm::rotate(glm::mat4(1.0f), glm::radians(cam.x), glm::vec3(0, 1, 0))); + auto& skeleton = entity->getSkeleton(); + + skeleton.visible = currentCamera != camera; + + size_t bodyIndex = skeleton.config->find("body")->getIndex(); + size_t headIndex = skeleton.config->find("head")->getIndex(); + + skeleton.pose.matrices[bodyIndex] = + glm::rotate(glm::mat4(1.0f), glm::radians(cam.x-90), glm::vec3(0, 1, 0)); + skeleton.pose.matrices[headIndex] = glm::rotate(glm::rotate( + glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.6f, 0.0f)), + glm::radians(-cam.y), glm::vec3(0, 0, 1)), glm::radians(90.0f), glm::vec3(0, 1, 0)); bool crouch = input.shift && hitbox.grounded && !input.sprint; float speed = this->speed; diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index 2eed0fcf..4c161a5f 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -70,9 +70,16 @@ void SkeletonConfig::render( const glm::mat4& matrix) const { update(skeleton, matrix); + + if (!skeleton.visible) { + return; + } for (size_t i = 0; i < nodes.size(); i++) { auto* node = nodes[i]; node->refreshModel(assets); + if (!skeleton.flags[i].visible) { + continue; + } if (auto model = node->getModel()) { batch.pushMatrix(skeleton.calculated.matrices[i]); batch.draw(model, &skeleton.textures); diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index f0d833e0..8bb241fd 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -67,11 +67,17 @@ namespace rigging { } }; + struct BoneFlags { + bool visible: 1; + }; + struct Skeleton { const SkeletonConfig* config; Pose pose; Pose calculated; + std::vector flags; std::unordered_map textures; + bool visible; }; class SkeletonConfig { @@ -104,9 +110,13 @@ namespace rigging { const glm::mat4& matrix) const; Skeleton instance() const { - return Skeleton { - this, Pose(nodes.size()), Pose(nodes.size()), {} + auto rig = Skeleton { + this, Pose(nodes.size()), Pose(nodes.size()), {}, {}, true }; + for (size_t i = 0; i < nodes.size(); i++) { + rig.flags.push_back({true}); + } + return rig; } Bone* find(std::string_view str) const;