@@ -890,6 +890,11 @@ void GenericCAO::updateNodePos()
890
890
891
891
void GenericCAO::step (float dtime, ClientEnvironment *env)
892
892
{
893
+ if (m_animated_meshnode) {
894
+ m_animated_meshnode->animateJoints ();
895
+ updateBonePosition ();
896
+ }
897
+
893
898
// Handle model animations and update positions instantly to prevent lags
894
899
if (m_is_local_player) {
895
900
LocalPlayer *player = m_env->getLocalPlayer ();
@@ -1360,16 +1365,41 @@ void GenericCAO::updateBonePosition()
1360
1365
return ;
1361
1366
1362
1367
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 ;
1368
1370
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 ) {
1372
1401
bone->setRotation (bone_rot);
1402
+ bone->updateAbsolutePosition ();
1373
1403
}
1374
1404
}
1375
1405
}
@@ -1583,7 +1613,7 @@ void GenericCAO::processMessage(const std::string &data)
1583
1613
v3f rotation = readV3F32 (is);
1584
1614
m_bone_position[bone] = core::vector2d<v3f>(position, rotation);
1585
1615
1586
- updateBonePosition ();
1616
+ // updateBonePosition(); now called every step
1587
1617
} else if (cmd == AO_CMD_ATTACH_TO) {
1588
1618
u16 parent_id = readS16 (is);
1589
1619
std::string bone = deSerializeString (is);
0 commit comments