feature: bone model overriding
This commit is contained in:
+29
-11
@@ -7,6 +7,13 @@
|
||||
|
||||
using namespace rigging;
|
||||
|
||||
void ModelReference::refresh(const Assets* assets) {
|
||||
if (updateFlag) {
|
||||
model = assets->get<model::Model>(name);
|
||||
updateFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
Bone::Bone(
|
||||
size_t index,
|
||||
std::string name,
|
||||
@@ -14,22 +21,27 @@ Bone::Bone(
|
||||
std::vector<std::unique_ptr<Bone>> bones)
|
||||
: index(index),
|
||||
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) {
|
||||
if (modelName == name) {
|
||||
if (model.name == name) {
|
||||
return;
|
||||
}
|
||||
modelName = name;
|
||||
modelUpdated = true;
|
||||
model = {name, nullptr, true};
|
||||
}
|
||||
|
||||
void Bone::refreshModel(const Assets* assets) {
|
||||
if (modelUpdated) {
|
||||
model = assets->get<model::Model>(modelName);
|
||||
modelUpdated = false;
|
||||
Skeleton::Skeleton(const SkeletonConfig* config)
|
||||
: config(config),
|
||||
pose(config->getNodes().size()),
|
||||
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++) {
|
||||
auto* node = nodes[i];
|
||||
node->refreshModel(assets);
|
||||
if (!skeleton.flags[i].visible) {
|
||||
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.draw(model, &skeleton.textures);
|
||||
batch.popMatrix();
|
||||
|
||||
+14
-21
@@ -28,14 +28,20 @@ namespace rigging {
|
||||
}
|
||||
};
|
||||
|
||||
struct ModelReference {
|
||||
std::string name;
|
||||
model::Model* model;
|
||||
bool updateFlag;
|
||||
|
||||
void refresh(const Assets* assets);
|
||||
};
|
||||
|
||||
class Bone {
|
||||
size_t index;
|
||||
std::string name;
|
||||
std::string modelName;
|
||||
std::vector<std::unique_ptr<Bone>> bones;
|
||||
model::Model* model = nullptr;
|
||||
bool modelUpdated = true;
|
||||
public:
|
||||
ModelReference model;
|
||||
Bone(
|
||||
size_t index,
|
||||
std::string name,
|
||||
@@ -44,20 +50,10 @@ namespace rigging {
|
||||
|
||||
void setModel(const std::string& name);
|
||||
|
||||
void refreshModel(const Assets* assets);
|
||||
|
||||
const std::string& getName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
const std::string& getModelName() const {
|
||||
return modelName;
|
||||
}
|
||||
|
||||
model::Model* getModel() const {
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
size_t getIndex() const {
|
||||
return index;
|
||||
}
|
||||
@@ -77,7 +73,10 @@ namespace rigging {
|
||||
Pose calculated;
|
||||
std::vector<BoneFlags> flags;
|
||||
std::unordered_map<std::string, std::string> textures;
|
||||
std::vector<ModelReference> modelOverrides;
|
||||
bool visible;
|
||||
|
||||
Skeleton(const SkeletonConfig* config);
|
||||
};
|
||||
|
||||
class SkeletonConfig {
|
||||
@@ -110,13 +109,7 @@ namespace rigging {
|
||||
const glm::mat4& matrix) const;
|
||||
|
||||
Skeleton instance() const {
|
||||
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;
|
||||
return Skeleton(this);
|
||||
}
|
||||
|
||||
Bone* find(std::string_view str) const;
|
||||
|
||||
Reference in New Issue
Block a user