记录我有始以来最坑爹,被坑出翔的BUG,解决的时间为一周!
我3月12日的时候,已经做出了动画,但是不知道为什么,我一但播放我的小哪吒的动画的时候,整个哪吒就崩溃了。我花了一周的时间来解决这个BUG。
到了3月19日的时候,我才解决这个BUG!本来我开始从网上学习ASSIMP的教程,把第一个小动画也制作出来。我自已用的一个小树枝,然后有三个骨骼,里面的动画能够播放,没有任何问题。然后我导入自已的小哪吒,结果一播放动画就完全崩溃了。
然后我这一周重新研究每一个细节,从动画的基础开始研究,以前我学教程很多代码就是抄过来用的,反正我能看明白就行了。但是这次我全部自已写。然后终于被我找到代码在哪儿了。
我用于蒙皮骨骼的结构如下:
struct SkinnedVertex {
DirectX::XMFLOAT3 Pos;
DirectX::XMFLOAT3 Normal;
DirectX::XMFLOAT2 TexC;
DirectX::XMFLOAT3 TangentU;
DirectX::XMFLOAT3 BoneWeights;
std::uint16_t BoneIndices[4];
SkinnedVertex()
: Pos(0.0f, 0.0f, 0.0f)
, Normal(0.0f, 0.0f, 0.0f)
, TexC(0.0f, 0.0f)
, TangentU(0.0f, 0.0f, 0.0f)
, BoneWeights(0.0f, 0.0f, 0.0f)
, BoneIndices{0, 0, 0, 0} {}
};
大家别看我的权重只有3个,这是可以的。在《DirectX12编程》这本书里面,作者就这样做的。因为你可以通1-其它权重,得到第四个权重。这样节约4个字节的空间。
但是,我在抄代码的时候,只是理所当然地使用了这个判断,出问题的代码在这里:
void SkinMesh::AddBoneData(
unsigned int vertex_index, unsigned int bone_id, float weight) {
auto& v = skinned_vertices_[vertex_index];
// 依次设置x,y,z值
if (v.BoneWeights.x == 0.0f) {
v.BoneIndices[0] = bone_id;
v.BoneWeights.x = weight;
return;
}
if (v.BoneWeights.y == 0.0f) {
v.BoneIndices[1] = bone_id;
v.BoneWeights.y = weight;
return;
}
if (v.BoneWeights.z == 0.0f) {
v.BoneIndices[2] = bone_id;
v.BoneWeights.z = weight;
return;
}
}
我通过判断权重是否被设置,来填充权重和骨骼的ID,但问题就在于,我这种方法导致第四个骨骼的权重加不上!
但是我最初用小树枝的时候,我并没有发现这个BUG,因为小树枝只有三个骨骼,我为了测试,自已建模,自已做动画。一切都很正常,让我以为代码很正常。
已经测试正常的代码,在我脑中就会自动被“封装”了,我就不再去管他。结果没有想到,这里面居然有这么一段坑爹的东西。如果我的小树枝一开始有4个或以上骨骼,也许我一瞬间就能明白这个BUG。
但是这东西我调了一整天。把代码全部重写,终于重写到这个添加的时候,一眼就看见问题了。
被坑出翔啊……