Index: source/collada/PSAConvert.cpp =================================================================== --- source/collada/PSAConvert.cpp +++ source/collada/PSAConvert.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -90,7 +90,9 @@ REQUIRE(frameCount > 0, "animation must have frames"); // (TODO: sort out the timing/looping problems) - size_t boneCount = skeleton.GetBoneCount(); + const size_t boneCount = skeleton.GetBoneCount(); + if (boneCount > 64) + Log(LOG_ERROR, "Skeleton has too many bones %zu/64", boneCount); std::vector boneTransforms; @@ -99,7 +101,7 @@ float time = timeStart + frameLength * frame; BoneTransform boneDefault = { { 0, 0, 0 }, { 0, 0, 0, 1 } }; - std::vector frameBoneTransforms (boneCount, boneDefault); + std::vector frameBoneTransforms(boneCount, boneDefault); // Move the model into the new animated pose // (We can't tell exactly which nodes should be animated, so Index: source/renderer/InstancingModelRenderer.cpp =================================================================== --- source/renderer/InstancingModelRenderer.cpp +++ source/renderer/InstancingModelRenderer.cpp @@ -78,6 +78,13 @@ if (gpuSkinning) { + // We can't use a lot of bones because it costs uniform memory. Recommended + // number of bones per model is 32. + // Add 1 to NumBones because of the special 'root' bone. + if (mdef->GetNumBones() + 1u > 64u) + LOGERROR("Model '%s' has too many bones %d/64", mdef->GetName().string8().c_str(), static_cast(mdef->GetNumBones() + 1)); + ENSURE(mdef->GetNumBones() + 1u <= 64u); + m_BlendJoints.type = GL_UNSIGNED_BYTE; m_BlendJoints.elems = 4; m_Array.AddAttribute(&m_BlendJoints);