Skip to content

Commit e1fc72c

Browse files
authored
Fix UpdateBonePosition() breaking animations (#9577)
1 parent bc60e44 commit e1fc72c

File tree

1 file changed

+39
-9
lines changed

1 file changed

+39
-9
lines changed

src/client/content_cao.cpp

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,11 @@ void GenericCAO::updateNodePos()
890890

891891
void GenericCAO::step(float dtime, ClientEnvironment *env)
892892
{
893+
if (m_animated_meshnode) {
894+
m_animated_meshnode->animateJoints();
895+
updateBonePosition();
896+
}
897+
893898
// Handle model animations and update positions instantly to prevent lags
894899
if (m_is_local_player) {
895900
LocalPlayer *player = m_env->getLocalPlayer();
@@ -1360,16 +1365,41 @@ void GenericCAO::updateBonePosition()
13601365
return;
13611366

13621367
m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
1363-
for(std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator
1364-
ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) {
1365-
std::string bone_name = (*ii).first;
1366-
v3f bone_pos = (*ii).second.X;
1367-
v3f bone_rot = (*ii).second.Y;
1368+
for (auto &it : m_bone_position) {
1369+
std::string bone_name = it.first;
13681370
irr::scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str());
1369-
if(bone)
1370-
{
1371-
bone->setPosition(bone_pos);
1371+
if (bone) {
1372+
bone->setPosition(it.second.X);
1373+
bone->setRotation(it.second.Y);
1374+
}
1375+
}
1376+
1377+
// search through bones to find mistakenly rotated bones due to bug in Irrlicht
1378+
for (u32 i = 0; i < m_animated_meshnode->getJointCount(); ++i) {
1379+
irr::scene::IBoneSceneNode *bone = m_animated_meshnode->getJointNode(i);
1380+
if (!bone)
1381+
continue;
1382+
1383+
//If bone is manually positioned there is no need to perform the bug check
1384+
bool skip = false;
1385+
for (auto &it : m_bone_position) {
1386+
if (it.first == bone->getName()) {
1387+
skip = true;
1388+
break;
1389+
}
1390+
}
1391+
if (skip)
1392+
continue;
1393+
1394+
// Workaround for Irrlicht bug
1395+
// We check each bone to see if it has been rotated ~180deg from its expected position due to a bug in Irricht
1396+
// when using EJUOR_CONTROL joint control. If the bug is detected we update the bone to the proper position
1397+
// and update the bones transformation.
1398+
v3f bone_rot = bone->getRelativeTransformation().getRotationDegrees();
1399+
float offset = fabsf(bone_rot.X - bone->getRotation().X);
1400+
if (offset > 179.9f && offset < 180.1f) {
13721401
bone->setRotation(bone_rot);
1402+
bone->updateAbsolutePosition();
13731403
}
13741404
}
13751405
}
@@ -1583,7 +1613,7 @@ void GenericCAO::processMessage(const std::string &data)
15831613
v3f rotation = readV3F32(is);
15841614
m_bone_position[bone] = core::vector2d<v3f>(position, rotation);
15851615

1586-
updateBonePosition();
1616+
// updateBonePosition(); now called every step
15871617
} else if (cmd == AO_CMD_ATTACH_TO) {
15881618
u16 parent_id = readS16(is);
15891619
std::string bone = deSerializeString(is);

0 commit comments

Comments
 (0)