Offset bone matrices by 1 to prevent out of bound access
This commit is contained in:
parent
5817ba0a79
commit
3160e177f9
5 changed files with 19 additions and 19 deletions
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue