Offset bone matrices by 1 to prevent out of bound access

This commit is contained in:
Vsevolod Kremianskii 2021-05-15 10:47:47 +07:00
parent 5817ba0a79
commit 3160e177f9
5 changed files with 19 additions and 19 deletions

View file

@ -129,8 +129,8 @@ void MdlReader::doLoad() {
_model = make_unique<Model>(
name,
getClassification(classification),
move(superModel),
move(rootNode),
move(superModel),
animationScale);
_model->setAffectedByFog(affectedByFog != 0);

View file

@ -31,14 +31,14 @@ namespace graphics {
Model::Model(
string name,
Classification classification,
shared_ptr<Model> superModel,
shared_ptr<ModelNode> rootNode,
shared_ptr<Model> superModel,
float animationScale
) :
_name(move(name)),
_classification(classification),
_superModel(move(superModel)),
_rootNode(rootNode),
_superModel(move(superModel)),
_animationScale(animationScale) {
if (!rootNode) {

View file

@ -54,8 +54,8 @@ public:
Model(
std::string name,
Classification classification,
std::shared_ptr<Model> superModel,
std::shared_ptr<ModelNode> rootNode,
std::shared_ptr<Model> superModel,
float animationScale);
void init();
@ -83,8 +83,8 @@ public:
private:
std::string _name;
Classification _classification;
std::shared_ptr<Model> _superModel;
std::shared_ptr<ModelNode> _rootNode;
std::shared_ptr<Model> _superModel;
std::unordered_map<std::string, std::shared_ptr<Animation>> _animations;
float _animationScale;
bool _affectedByFog;

View file

@ -367,10 +367,10 @@ void main() {
vec4 normal = vec4(aNormal, 0.0);
if (isFeatureEnabled(FEATURE_SKELETAL)) {
int i1 = int(aBoneIndices[0]);
int i2 = int(aBoneIndices[1]);
int i3 = int(aBoneIndices[2]);
int i4 = int(aBoneIndices[3]);
int i1 = 1 + int(aBoneIndices[0]);
int i2 = 1 + int(aBoneIndices[1]);
int i3 = 1 + int(aBoneIndices[2]);
int i4 = 1 + int(aBoneIndices[3]);
float w1 = aBoneWeights[0];
float w2 = aBoneWeights[1];
@ -383,6 +383,8 @@ void main() {
(uBones[i3] * position) * w3 +
(uBones[i4] * position) * w4;
position.w = 1.0;
normal =
(uBones[i1] * normal) * w1 +
(uBones[i2] * normal) * w2 +

View file

@ -291,17 +291,15 @@ void MeshSceneNode::drawSingle(bool shadowPass) {
if (mesh->skin) {
uniforms.combined.featureMask |= UniformFeatureFlags::skeletal;
for (int i = 0; i < kMaxBones; ++i) {
if (i < static_cast<int>(mesh->skin->boneNodeId.size())) {
uint16_t nodeId = mesh->skin->boneNodeId[i];
if (nodeId != 0xffff) {
shared_ptr<ModelNodeSceneNode> bone(_model->getNodeById(nodeId));
if (bone && bone->type() == SceneNodeType::Mesh) {
uniforms.skeletal->bones[i] = _modelNode->absoluteTransformInverse() * bone->boneTransform() * _modelNode->absoluteTransform();
}
// Offset bone matrices by 1 to account for negative bone indices
uniforms.skeletal->bones[0] = glm::mat4(1.0f);
for (size_t i = 1; i < 1 + mesh->skin->boneNodeId.size() && i < kMaxBones; ++i) {
uint16_t nodeId = mesh->skin->boneNodeId[i - 1];
if (nodeId != 0xffff) {
shared_ptr<ModelNodeSceneNode> bone(_model->getNodeById(nodeId));
if (bone && bone->type() == SceneNodeType::Mesh) {
uniforms.skeletal->bones[i] = _modelNode->absoluteTransformInverse() * bone->boneTransform() * _modelNode->absoluteTransform();
}
} else {
uniforms.skeletal->bones[i] = glm::mat4(1.0f);
}
}
}