|
|
@ -67,31 +67,29 @@ namespace MWRender
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PartHolderPtr ActorAnimation::attachMesh(
|
|
|
|
PartHolderPtr ActorAnimation::attachMesh(
|
|
|
|
const std::string& model, std::string_view bonename, bool enchantedGlow, osg::Vec4f* glowColor)
|
|
|
|
VFS::Path::NormalizedView model, std::string_view bonename, const osg::Vec4f* glowColor)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
osg::Group* parent = getBoneByName(bonename);
|
|
|
|
osg::Group* parent = getBoneByName(bonename);
|
|
|
|
if (!parent)
|
|
|
|
if (!parent)
|
|
|
|
return nullptr;
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> instance
|
|
|
|
osg::ref_ptr<osg::Node> instance = mResourceSystem->getSceneManager()->getInstance(model, parent);
|
|
|
|
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(model), parent);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const NodeMap& nodeMap = getNodeMap();
|
|
|
|
const NodeMap& nodeMap = getNodeMap();
|
|
|
|
NodeMap::const_iterator found = nodeMap.find(bonename);
|
|
|
|
NodeMap::const_iterator found = nodeMap.find(bonename);
|
|
|
|
if (found == nodeMap.end())
|
|
|
|
if (found == nodeMap.end())
|
|
|
|
return {};
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
|
|
if (enchantedGlow)
|
|
|
|
if (glowColor != nullptr)
|
|
|
|
mGlowUpdater = SceneUtil::addEnchantedGlow(instance, mResourceSystem, *glowColor);
|
|
|
|
mGlowUpdater = SceneUtil::addEnchantedGlow(instance, mResourceSystem, *glowColor);
|
|
|
|
|
|
|
|
|
|
|
|
return std::make_unique<PartHolder>(instance);
|
|
|
|
return std::make_unique<PartHolder>(instance);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> ActorAnimation::attach(
|
|
|
|
osg::ref_ptr<osg::Node> ActorAnimation::attach(
|
|
|
|
const std::string& model, std::string_view bonename, std::string_view bonefilter, bool isLight)
|
|
|
|
VFS::Path::NormalizedView model, std::string_view bonename, std::string_view bonefilter, bool isLight)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
osg::ref_ptr<const osg::Node> templateNode
|
|
|
|
osg::ref_ptr<const osg::Node> templateNode = mResourceSystem->getSceneManager()->getTemplate(model);
|
|
|
|
= mResourceSystem->getSceneManager()->getTemplate(VFS::Path::toNormalized(model));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const NodeMap& nodeMap = getNodeMap();
|
|
|
|
const NodeMap& nodeMap = getNodeMap();
|
|
|
|
auto found = nodeMap.find(bonename);
|
|
|
|
auto found = nodeMap.find(bonename);
|
|
|
@ -218,20 +216,20 @@ namespace MWRender
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string mesh = getSheathedShieldMesh(*shield);
|
|
|
|
const VFS::Path::Normalized mesh = getSheathedShieldMesh(*shield);
|
|
|
|
if (mesh.empty())
|
|
|
|
if (mesh.empty())
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
std::string_view boneName = "Bip01 AttachShield";
|
|
|
|
constexpr std::string_view boneName = "Bip01 AttachShield";
|
|
|
|
osg::Vec4f glowColor = shield->getClass().getEnchantmentColor(*shield);
|
|
|
|
const bool isEnchanted = !shield->getClass().getEnchantment(*shield).empty();
|
|
|
|
const std::string holsteredName = addSuffixBeforeExtension(mesh, "_sh");
|
|
|
|
const osg::Vec4f glowColor = isEnchanted ? shield->getClass().getEnchantmentColor(*shield) : osg::Vec4f();
|
|
|
|
bool isEnchanted = !shield->getClass().getEnchantment(*shield).empty();
|
|
|
|
const VFS::Path::Normalized holsteredName = addSuffixBeforeExtension(mesh, "_sh");
|
|
|
|
|
|
|
|
|
|
|
|
// If we have no dedicated sheath model, use basic shield model as fallback.
|
|
|
|
// If we have no dedicated sheath model, use basic shield model as fallback.
|
|
|
|
if (!mResourceSystem->getVFS()->exists(holsteredName))
|
|
|
|
if (!mResourceSystem->getVFS()->exists(holsteredName))
|
|
|
|
mHolsteredShield = attachMesh(mesh, boneName, isEnchanted, &glowColor);
|
|
|
|
mHolsteredShield = attachMesh(mesh, boneName, isEnchanted ? &glowColor : nullptr);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
mHolsteredShield = attachMesh(holsteredName, boneName, isEnchanted, &glowColor);
|
|
|
|
mHolsteredShield = attachMesh(holsteredName, boneName, isEnchanted ? &glowColor : nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
if (!mHolsteredShield)
|
|
|
|
if (!mHolsteredShield)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -245,8 +243,7 @@ namespace MWRender
|
|
|
|
// file.
|
|
|
|
// file.
|
|
|
|
if (shieldNode && !shieldNode->getNumChildren())
|
|
|
|
if (shieldNode && !shieldNode->getNumChildren())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
osg::ref_ptr<osg::Node> fallbackNode
|
|
|
|
osg::ref_ptr<osg::Node> fallbackNode = mResourceSystem->getSceneManager()->getInstance(mesh, shieldNode);
|
|
|
|
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(mesh), shieldNode);
|
|
|
|
|
|
|
|
if (isEnchanted)
|
|
|
|
if (isEnchanted)
|
|
|
|
SceneUtil::addEnchantedGlow(shieldNode, mResourceSystem, glowColor);
|
|
|
|
SceneUtil::addEnchantedGlow(shieldNode, mResourceSystem, glowColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -341,20 +338,24 @@ namespace MWRender
|
|
|
|
if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown)
|
|
|
|
if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown)
|
|
|
|
showHolsteredWeapons = false;
|
|
|
|
showHolsteredWeapons = false;
|
|
|
|
|
|
|
|
|
|
|
|
std::string mesh = weapon->getClass().getCorrectedModel(*weapon);
|
|
|
|
const VFS::Path::Normalized mesh = weapon->getClass().getCorrectedModel(*weapon);
|
|
|
|
std::string_view boneName = getHolsteredWeaponBoneName(*weapon);
|
|
|
|
if (mesh.empty())
|
|
|
|
if (mesh.empty() || boneName.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const std::string_view boneName = getHolsteredWeaponBoneName(*weapon);
|
|
|
|
|
|
|
|
if (boneName.empty())
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
// If the scabbard is not found, use the weapon mesh as fallback.
|
|
|
|
// If the scabbard is not found, use the weapon mesh as fallback.
|
|
|
|
const std::string scabbardName = addSuffixBeforeExtension(mesh, "_sh");
|
|
|
|
const VFS::Path::Normalized scabbardName = addSuffixBeforeExtension(mesh, "_sh");
|
|
|
|
bool isEnchanted = !weapon->getClass().getEnchantment(*weapon).empty();
|
|
|
|
const bool isEnchanted = !weapon->getClass().getEnchantment(*weapon).empty();
|
|
|
|
if (!mResourceSystem->getVFS()->exists(scabbardName))
|
|
|
|
if (!mResourceSystem->getVFS()->exists(scabbardName))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (showHolsteredWeapons)
|
|
|
|
if (showHolsteredWeapons)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
osg::Vec4f glowColor = weapon->getClass().getEnchantmentColor(*weapon);
|
|
|
|
const osg::Vec4f glowColor
|
|
|
|
mScabbard = attachMesh(mesh, boneName, isEnchanted, &glowColor);
|
|
|
|
= isEnchanted ? weapon->getClass().getEnchantmentColor(*weapon) : osg::Vec4f();
|
|
|
|
|
|
|
|
mScabbard = attachMesh(mesh, boneName, isEnchanted ? &glowColor : nullptr);
|
|
|
|
if (mScabbard)
|
|
|
|
if (mScabbard)
|
|
|
|
resetControllers(mScabbard->getNode());
|
|
|
|
resetControllers(mScabbard->getNode());
|
|
|
|
}
|
|
|
|
}
|
|
|
|