Merge branch 'fix-sheathing-non-nifs' into 'master'

Fix weapon and shield sheathing for non-nif meshes

See merge request OpenMW/openmw!3985
fix-osga-rotate-wildly
psi29a 9 months ago
commit b70f1d86c5

@ -35,6 +35,7 @@
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/ptr.hpp"
#include "actorutil.hpp"
#include "vismask.hpp"
namespace MWRender
@ -144,8 +145,7 @@ namespace MWRender
if (mesh.empty())
return mesh;
std::string holsteredName = mesh;
holsteredName = holsteredName.replace(holsteredName.size() - 4, 4, "_sh.nif");
const std::string holsteredName = addSuffixBeforeExtension(mesh, "_sh");
if (mResourceSystem->getVFS()->exists(holsteredName))
{
osg::ref_ptr<osg::Node> shieldTemplate = mResourceSystem->getSceneManager()->getInstance(holsteredName);
@ -222,8 +222,7 @@ namespace MWRender
std::string_view boneName = "Bip01 AttachShield";
osg::Vec4f glowColor = shield->getClass().getEnchantmentColor(*shield);
std::string holsteredName = mesh;
holsteredName = holsteredName.replace(holsteredName.size() - 4, 4, "_sh.nif");
const std::string holsteredName = addSuffixBeforeExtension(mesh, "_sh");
bool isEnchanted = !shield->getClass().getEnchantment(*shield).empty();
// If we have no dedicated sheath model, use basic shield model as fallback.
@ -340,14 +339,12 @@ namespace MWRender
showHolsteredWeapons = false;
std::string mesh = weapon->getClass().getCorrectedModel(*weapon);
std::string scabbardName = mesh;
std::string_view boneName = getHolsteredWeaponBoneName(*weapon);
if (mesh.empty() || boneName.empty())
return;
// If the scabbard is not found, use the weapon mesh as fallback.
scabbardName = scabbardName.replace(scabbardName.size() - 4, 4, "_sh.nif");
const std::string scabbardName = addSuffixBeforeExtension(mesh, "_sh");
bool isEnchanted = !weapon->getClass().getEnchantment(*weapon).empty();
if (!mResourceSystem->getVFS()->exists(scabbardName))
{

@ -37,4 +37,16 @@ namespace MWRender
|| VFS::Path::pathEqual(Settings::models().mBaseanimfemale.get(), model)
|| VFS::Path::pathEqual(Settings::models().mBaseanim.get(), model);
}
std::string addSuffixBeforeExtension(const std::string& filename, const std::string& suffix)
{
size_t dotPos = filename.rfind('.');
// No extension found; return the original filename with suffix appended
if (dotPos == std::string::npos)
return filename + suffix;
// Insert the suffix before the dot (extension) and return the new filename
return filename.substr(0, dotPos) + suffix + filename.substr(dotPos);
}
}

@ -8,6 +8,7 @@ namespace MWRender
{
const std::string& getActorSkeleton(bool firstPerson, bool female, bool beast, bool werewolf);
bool isDefaultActorSkeleton(std::string_view model);
std::string addSuffixBeforeExtension(const std::string& filename, const std::string& suffix);
}
#endif

@ -539,8 +539,7 @@ namespace MWRender
if (mesh.empty())
return std::string();
std::string holsteredName = mesh;
holsteredName = holsteredName.replace(holsteredName.size() - 4, 4, "_sh.nif");
const std::string holsteredName = addSuffixBeforeExtension(mesh, "_sh");
if (mResourceSystem->getVFS()->exists(holsteredName))
{
osg::ref_ptr<osg::Node> shieldTemplate = mResourceSystem->getSceneManager()->getInstance(holsteredName);

@ -21,13 +21,36 @@ namespace SceneUtil
mFoundNode = &group;
return true;
}
// FIXME: can the nodes/bones be renamed at loading stage rather than each time?
// Convert underscores to whitespaces as a workaround for Collada (OpenMW's animation system uses
// whitespace-separated names)
std::string nodeName = group.getName();
std::replace(nodeName.begin(), nodeName.end(), '_', ' ');
if (Misc::StringUtils::ciEqual(nodeName, mNameToFind))
{
mFoundNode = &group;
return true;
}
return false;
}
void FindByClassVisitor::apply(osg::Node& node)
{
if (Misc::StringUtils::ciEqual(node.className(), mNameToFind))
{
mFoundNodes.push_back(&node);
}
else
{
// FIXME: can the nodes/bones be renamed at loading stage rather than each time?
// Convert underscores to whitespaces as a workaround for Collada (OpenMW's animation system uses
// whitespace-separated names)
std::string nodeName = node.className();
std::replace(nodeName.begin(), nodeName.end(), '_', ' ');
if (Misc::StringUtils::ciEqual(nodeName, mNameToFind))
mFoundNodes.push_back(&node);
}
traverse(node);
}
@ -53,6 +76,8 @@ namespace SceneUtil
if (trans.libraryName() == std::string_view("osgAnimation"))
{
std::string nodeName = trans.getName();
// FIXME: can the nodes/bones be renamed at loading stage rather than each time?
// Convert underscores to whitespaces as a workaround for Collada (OpenMW's animation system uses
// whitespace-separated names)
std::replace(nodeName.begin(), nodeName.end(), '_', ' ');

Loading…
Cancel
Save