mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 06:29:56 +00:00
Fix weapon sheathing for non-nif meshes
This commit is contained in:
parent
012d10703f
commit
7897ff7ac9
5 changed files with 43 additions and 9 deletions
|
@ -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…
Reference in a new issue