diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index af9fdf853..a922fa170 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -1270,7 +1270,7 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con if (bonename.empty()) params.mObjects = NifOgre::Loader::createObjects(mInsert, model); else - params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model); + params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, "", mInsert, model); // TODO: turn off shadow casting setRenderProperties(params.mObjects, RV_Misc, diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index fef9fa644..c1957d7a8 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -106,7 +106,7 @@ void CreatureWeaponAnimation::updatePart(NifOgre::ObjectScenePtr& scene, int slo else bonename = "Shield Bone"; - scene = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, item.getClass().getModel(item)); + scene = NifOgre::Loader::createObjects(mSkelBase, bonename, bonename, mInsert, item.getClass().getModel(item)); Ogre::Vector3 glowColor = getEnchantmentColor(item); setRenderProperties(scene, RV_Actors, RQG_Main, RQG_Alpha, 0, diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 3b0b4e08b..1cc9ad232 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -160,7 +160,7 @@ static NpcAnimation::PartBoneMap createPartListMap() { NpcAnimation::PartBoneMap result; result.insert(std::make_pair(ESM::PRT_Head, "Head")); - result.insert(std::make_pair(ESM::PRT_Hair, "Head")); + result.insert(std::make_pair(ESM::PRT_Hair, "Head")); // note it uses "Head" as attach bone, but "Hair" as filter result.insert(std::make_pair(ESM::PRT_Neck, "Neck")); result.insert(std::make_pair(ESM::PRT_Cuirass, "Chest")); result.insert(std::make_pair(ESM::PRT_Groin, "Groin")); @@ -574,9 +574,9 @@ public: } }; -NifOgre::ObjectScenePtr NpcAnimation::insertBoundedPart(const std::string &model, int group, const std::string &bonename, bool enchantedGlow, Ogre::Vector3* glowColor) +NifOgre::ObjectScenePtr NpcAnimation::insertBoundedPart(const std::string &model, int group, const std::string &bonename, const std::string &bonefilter, bool enchantedGlow, Ogre::Vector3* glowColor) { - NifOgre::ObjectScenePtr objects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model); + NifOgre::ObjectScenePtr objects = NifOgre::Loader::createObjects(mSkelBase, bonename, bonefilter, mInsert, model); setRenderProperties(objects, (mViewMode == VM_FirstPerson) ? RV_FirstPerson : mVisibilityFlags, RQG_Main, RQG_Alpha, 0, enchantedGlow, glowColor); @@ -690,7 +690,10 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g mPartPriorities[type] = priority; try { - mObjectParts[type] = insertBoundedPart(mesh, group, sPartList.at(type), enchantedGlow, glowColor); + const std::string& bonename = sPartList.at(type); + // PRT_Hair seems to be the only type that breaks consistency and uses a filter that's different from the attachment bone + const std::string bonefilter = (type == ESM::PRT_Hair) ? "hair" : bonename; + mObjectParts[type] = insertBoundedPart(mesh, group, bonename, bonefilter, enchantedGlow, glowColor); } catch (std::exception& e) { diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index f3603fe14..90b1c269b 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -106,6 +106,7 @@ private: void updateNpcBase(); NifOgre::ObjectScenePtr insertBoundedPart(const std::string &model, int group, const std::string &bonename, + const std::string &bonefilter, bool enchantedGlow, Ogre::Vector3* glowColor=NULL); void removeIndividualPart(ESM::PartReferenceType type); diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index c59a93feb..7a52ce7ea 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -55,8 +55,11 @@ void WeaponAnimation::attachArrow(MWWorld::Ptr actor) return; std::string model = ammo->getClass().getModel(*ammo); - assert(weapon->mSkelBase && "Need a skeleton to attach the arrow to"); - mAmmunition = NifOgre::Loader::createObjects(weapon->mSkelBase, "ArrowBone", weapon->mSkelBase->getParentSceneNode(), model); + if (!weapon->mSkelBase) + throw std::runtime_error("Need a skeleton to attach the arrow to"); + + const std::string bonename = "ArrowBone"; + mAmmunition = NifOgre::Loader::createObjects(weapon->mSkelBase, bonename, bonename, weapon->mSkelBase->getParentSceneNode(), model); configureAddedObject(mAmmunition, *ammo, MWWorld::InventoryStore::Slot_Ammunition); } } diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp index ef4b9e985..b55248784 100644 --- a/components/nifogre/ogrenifloader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -1383,6 +1383,7 @@ ObjectScenePtr Loader::createObjects(Ogre::SceneNode *parentNode, std::string na } ObjectScenePtr Loader::createObjects(Ogre::Entity *parent, const std::string &bonename, + const std::string& bonefilter, Ogre::SceneNode *parentNode, std::string name, const std::string &group) { @@ -1408,11 +1409,9 @@ ObjectScenePtr Loader::createObjects(Ogre::Entity *parent, const std::string &bo if(isskinned) { - // Apparently both are allowed. Sigh. - // This could also mean that filters are supposed to work on the actual node - // hierarchy, rather than just trishapes, and the 'tri ' should be omitted? - std::string filter = "@shape=tri "+bonename; - std::string filter2 = "@shape="+bonename; + // accepts anything named "filter*" or "tri filter*" + std::string filter = "@shape=tri "+bonefilter; + std::string filter2 = "@shape="+bonefilter; Misc::StringUtils::toLower(filter); Misc::StringUtils::toLower(filter2); for(size_t i = 0;i < scene->mEntities.size();i++) diff --git a/components/nifogre/ogrenifloader.hpp b/components/nifogre/ogrenifloader.hpp index 485495a38..fd5ddca7d 100644 --- a/components/nifogre/ogrenifloader.hpp +++ b/components/nifogre/ogrenifloader.hpp @@ -97,6 +97,7 @@ class Loader { public: static ObjectScenePtr createObjects(Ogre::Entity *parent, const std::string &bonename, + const std::string& filter, Ogre::SceneNode *parentNode, std::string name, const std::string &group="General");