feature: bone model overriding
This commit is contained in:
parent
4a0bc016ce
commit
d5877a342f
@ -118,6 +118,10 @@ local rig = entity.skeleton
|
|||||||
-- Returns the model name assigned to the bone at the specified index
|
-- Returns the model name assigned to the bone at the specified index
|
||||||
rig:get_model(index: int) -> str
|
rig:get_model(index: int) -> str
|
||||||
|
|
||||||
|
-- Reassigns the bone model at the specified index
|
||||||
|
-- Resets to original if name is not specified
|
||||||
|
rig:set_model(index: int, name: str)
|
||||||
|
|
||||||
-- Returns the bone transformation matrix at the specified index
|
-- Returns the bone transformation matrix at the specified index
|
||||||
rig:get_matrix(index: int) -> mat4
|
rig:get_matrix(index: int) -> mat4
|
||||||
-- Sets the bone transformation matrix at the specified index
|
-- Sets the bone transformation matrix at the specified index
|
||||||
|
|||||||
@ -119,6 +119,10 @@ local rig = entity.skeleton
|
|||||||
-- Возвращает имя модели, назначенной на кость с указанным индексом
|
-- Возвращает имя модели, назначенной на кость с указанным индексом
|
||||||
rig:get_model(index: int) -> str
|
rig:get_model(index: int) -> str
|
||||||
|
|
||||||
|
-- Переназначает модель кости с указанным индексом
|
||||||
|
-- Сбрасывает до изначальной, если не указывать имя
|
||||||
|
rig:set_model(index: int, name: str)
|
||||||
|
|
||||||
-- Возвращает матрицу трансформации кости с указанным индексом
|
-- Возвращает матрицу трансформации кости с указанным индексом
|
||||||
rig:get_matrix(index: int) -> mat4
|
rig:get_matrix(index: int) -> mat4
|
||||||
-- Устанавливает матрицу трансформации кости с указанным индексом
|
-- Устанавливает матрицу трансформации кости с указанным индексом
|
||||||
|
|||||||
@ -39,6 +39,7 @@ end
|
|||||||
|
|
||||||
local Skeleton = {__index={
|
local Skeleton = {__index={
|
||||||
get_model=function(self, i) return __skeleton.get_model(self.eid, i) end,
|
get_model=function(self, i) return __skeleton.get_model(self.eid, i) end,
|
||||||
|
set_model=function(self, i, s) return __skeleton.set_model(self.eid, i, s) end,
|
||||||
get_matrix=function(self, i) return __skeleton.get_matrix(self.eid, i) end,
|
get_matrix=function(self, i) return __skeleton.get_matrix(self.eid, i) end,
|
||||||
set_matrix=function(self, i, m) return __skeleton.set_matrix(self.eid, i, m) end,
|
set_matrix=function(self, i, m) return __skeleton.set_matrix(self.eid, i, m) end,
|
||||||
get_texture=function(self, s) return __skeleton.get_texture(self.eid, s) end,
|
get_texture=function(self, s) return __skeleton.get_texture(self.eid, s) end,
|
||||||
|
|||||||
@ -20,6 +20,7 @@ enum class BlockInteraction {
|
|||||||
placing
|
placing
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Player argument is nullable
|
||||||
using on_block_interaction = std::function<void(
|
using on_block_interaction = std::function<void(
|
||||||
Player*, glm::ivec3, const Block*, BlockInteraction type
|
Player*, glm::ivec3, const Block*, BlockInteraction type
|
||||||
)>;
|
)>;
|
||||||
@ -76,6 +77,7 @@ public:
|
|||||||
BlockInteraction type
|
BlockInteraction type
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// @brief Add block interaction callback
|
||||||
void listenBlockInteraction(const on_block_interaction& callback);
|
void listenBlockInteraction(const on_block_interaction& callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,25 @@ static int l_get_model(lua::State* L) {
|
|||||||
auto& skeleton = entity->getSkeleton();
|
auto& skeleton = entity->getSkeleton();
|
||||||
auto* rigConfig = skeleton.config;
|
auto* rigConfig = skeleton.config;
|
||||||
auto index = index_range_check(skeleton, lua::tointeger(L, 2));
|
auto index = index_range_check(skeleton, lua::tointeger(L, 2));
|
||||||
return lua::pushstring(L, rigConfig->getNodes()[index]->getModelName());
|
const auto& modelOverride = skeleton.modelOverrides[index];
|
||||||
|
if (!modelOverride.model) {
|
||||||
|
return lua::pushstring(L, modelOverride.name);
|
||||||
|
}
|
||||||
|
return lua::pushstring(L, rigConfig->getNodes()[index]->model.name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_set_model(lua::State* L) {
|
||||||
|
if (auto entity = get_entity(L, 1)) {
|
||||||
|
auto& skeleton = entity->getSkeleton();
|
||||||
|
auto index = index_range_check(skeleton, lua::tointeger(L, 2));
|
||||||
|
auto& modelOverride = skeleton.modelOverrides[index];
|
||||||
|
if (lua::isnoneornil(L, 3)) {
|
||||||
|
modelOverride = {"", nullptr, true};
|
||||||
|
} else {
|
||||||
|
modelOverride = {lua::require_string(L, 3), nullptr, true};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -96,6 +114,7 @@ static int l_set_visible(lua::State* L) {
|
|||||||
|
|
||||||
const luaL_Reg skeletonlib [] = {
|
const luaL_Reg skeletonlib [] = {
|
||||||
{"get_model", lua::wrap<l_get_model>},
|
{"get_model", lua::wrap<l_get_model>},
|
||||||
|
{"set_model", lua::wrap<l_set_model>},
|
||||||
{"get_matrix", lua::wrap<l_get_matrix>},
|
{"get_matrix", lua::wrap<l_get_matrix>},
|
||||||
{"set_matrix", lua::wrap<l_set_matrix>},
|
{"set_matrix", lua::wrap<l_set_matrix>},
|
||||||
{"get_texture", lua::wrap<l_get_texture>},
|
{"get_texture", lua::wrap<l_get_texture>},
|
||||||
|
|||||||
@ -7,6 +7,13 @@
|
|||||||
|
|
||||||
using namespace rigging;
|
using namespace rigging;
|
||||||
|
|
||||||
|
void ModelReference::refresh(const Assets* assets) {
|
||||||
|
if (updateFlag) {
|
||||||
|
model = assets->get<model::Model>(name);
|
||||||
|
updateFlag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Bone::Bone(
|
Bone::Bone(
|
||||||
size_t index,
|
size_t index,
|
||||||
std::string name,
|
std::string name,
|
||||||
@ -14,22 +21,27 @@ Bone::Bone(
|
|||||||
std::vector<std::unique_ptr<Bone>> bones)
|
std::vector<std::unique_ptr<Bone>> bones)
|
||||||
: index(index),
|
: index(index),
|
||||||
name(std::move(name)),
|
name(std::move(name)),
|
||||||
modelName(std::move(model)),
|
bones(std::move(bones)),
|
||||||
bones(std::move(bones))
|
model({model, nullptr, true})
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Bone::setModel(const std::string& name) {
|
void Bone::setModel(const std::string& name) {
|
||||||
if (modelName == name) {
|
if (model.name == name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
modelName = name;
|
model = {name, nullptr, true};
|
||||||
modelUpdated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bone::refreshModel(const Assets* assets) {
|
Skeleton::Skeleton(const SkeletonConfig* config)
|
||||||
if (modelUpdated) {
|
: config(config),
|
||||||
model = assets->get<model::Model>(modelName);
|
pose(config->getNodes().size()),
|
||||||
modelUpdated = false;
|
calculated(config->getNodes().size()),
|
||||||
|
flags(config->getNodes().size()),
|
||||||
|
textures(),
|
||||||
|
modelOverrides(config->getNodes().size()),
|
||||||
|
visible(true) {
|
||||||
|
for (size_t i = 0; i < config->getNodes().size(); i++) {
|
||||||
|
flags[i].visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,11 +88,17 @@ void SkeletonConfig::render(
|
|||||||
}
|
}
|
||||||
for (size_t i = 0; i < nodes.size(); i++) {
|
for (size_t i = 0; i < nodes.size(); i++) {
|
||||||
auto* node = nodes[i];
|
auto* node = nodes[i];
|
||||||
node->refreshModel(assets);
|
|
||||||
if (!skeleton.flags[i].visible) {
|
if (!skeleton.flags[i].visible) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (auto model = node->getModel()) {
|
node->model.refresh(assets);
|
||||||
|
auto model = node->model.model;
|
||||||
|
auto& modelOverride = skeleton.modelOverrides.at(i);
|
||||||
|
if (!modelOverride.updateFlag) {
|
||||||
|
modelOverride.refresh(assets);
|
||||||
|
}
|
||||||
|
model = modelOverride.model ? modelOverride.model : model;
|
||||||
|
if (model) {
|
||||||
batch.pushMatrix(skeleton.calculated.matrices[i]);
|
batch.pushMatrix(skeleton.calculated.matrices[i]);
|
||||||
batch.draw(model, &skeleton.textures);
|
batch.draw(model, &skeleton.textures);
|
||||||
batch.popMatrix();
|
batch.popMatrix();
|
||||||
|
|||||||
@ -28,14 +28,20 @@ namespace rigging {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ModelReference {
|
||||||
|
std::string name;
|
||||||
|
model::Model* model;
|
||||||
|
bool updateFlag;
|
||||||
|
|
||||||
|
void refresh(const Assets* assets);
|
||||||
|
};
|
||||||
|
|
||||||
class Bone {
|
class Bone {
|
||||||
size_t index;
|
size_t index;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string modelName;
|
|
||||||
std::vector<std::unique_ptr<Bone>> bones;
|
std::vector<std::unique_ptr<Bone>> bones;
|
||||||
model::Model* model = nullptr;
|
|
||||||
bool modelUpdated = true;
|
|
||||||
public:
|
public:
|
||||||
|
ModelReference model;
|
||||||
Bone(
|
Bone(
|
||||||
size_t index,
|
size_t index,
|
||||||
std::string name,
|
std::string name,
|
||||||
@ -44,20 +50,10 @@ namespace rigging {
|
|||||||
|
|
||||||
void setModel(const std::string& name);
|
void setModel(const std::string& name);
|
||||||
|
|
||||||
void refreshModel(const Assets* assets);
|
|
||||||
|
|
||||||
const std::string& getName() const {
|
const std::string& getName() const {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& getModelName() const {
|
|
||||||
return modelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
model::Model* getModel() const {
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getIndex() const {
|
size_t getIndex() const {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
@ -77,7 +73,10 @@ namespace rigging {
|
|||||||
Pose calculated;
|
Pose calculated;
|
||||||
std::vector<BoneFlags> flags;
|
std::vector<BoneFlags> flags;
|
||||||
std::unordered_map<std::string, std::string> textures;
|
std::unordered_map<std::string, std::string> textures;
|
||||||
|
std::vector<ModelReference> modelOverrides;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
|
||||||
|
Skeleton(const SkeletonConfig* config);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SkeletonConfig {
|
class SkeletonConfig {
|
||||||
@ -110,13 +109,7 @@ namespace rigging {
|
|||||||
const glm::mat4& matrix) const;
|
const glm::mat4& matrix) const;
|
||||||
|
|
||||||
Skeleton instance() const {
|
Skeleton instance() const {
|
||||||
auto rig = Skeleton {
|
return Skeleton(this);
|
||||||
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;
|
Bone* find(std::string_view str) const;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user