1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 18:59:57 +00:00

Merge branch 'blaze_it' into 'master'

Rotate lights by 90 degrees

Closes #5937

See merge request OpenMW/openmw!1343
This commit is contained in:
psi29a 2021-11-02 20:19:51 +00:00
commit c50aee9434
8 changed files with 38 additions and 26 deletions

View file

@ -28,6 +28,7 @@
Bug #5842: GetDisposition adds temporary disposition change from different actors Bug #5842: GetDisposition adds temporary disposition change from different actors
Bug #5863: GetEffect should return true after the player has teleported Bug #5863: GetEffect should return true after the player has teleported
Bug #5913: Failed assertion during Ritual of Trees quest Bug #5913: Failed assertion during Ritual of Trees quest
Bug #5937: Lights always need to be rotated by 90 degrees
Bug #6037: Morrowind Content Language Cannot be Set to English in OpenMW Launcher Bug #6037: Morrowind Content Language Cannot be Set to English in OpenMW Launcher
Bug #6051: NaN water height in ESM file is not handled gracefully Bug #6051: NaN water height in ESM file is not handled gracefully
Bug #6066: addtopic "return" does not work from within script. No errors thrown Bug #6066: addtopic "return" does not work from within script. No errors thrown

View file

@ -11,6 +11,7 @@
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
#include <components/sceneutil/attach.hpp>
#include <components/sceneutil/lightmanager.hpp> #include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/lightutil.hpp> #include <components/sceneutil/lightutil.hpp>
#include <components/sceneutil/visitor.hpp> #include <components/sceneutil/visitor.hpp>
@ -84,6 +85,22 @@ PartHolderPtr ActorAnimation::attachMesh(const std::string& model, const std::st
return PartHolderPtr(new PartHolder(instance)); return PartHolderPtr(new PartHolder(instance));
} }
osg::ref_ptr<osg::Node> ActorAnimation::attach(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool isLight)
{
osg::ref_ptr<const osg::Node> templateNode = mResourceSystem->getSceneManager()->getTemplate(model);
const NodeMap& nodeMap = getNodeMap();
auto found = nodeMap.find(bonename);
if (found == nodeMap.end())
throw std::runtime_error("Can't find attachment node " + bonename);
if(isLight)
{
osg::Quat rotation(osg::DegreesToRadians(-90.f), osg::Vec3f(1,0,0));
return SceneUtil::attach(templateNode, mObjectRoot, bonefilter, found->second, mResourceSystem->getSceneManager(), &rotation);
}
return SceneUtil::attach(templateNode, mObjectRoot, bonefilter, found->second, mResourceSystem->getSceneManager());
}
std::string ActorAnimation::getShieldMesh(const MWWorld::ConstPtr& shield, bool female) const std::string ActorAnimation::getShieldMesh(const MWWorld::ConstPtr& shield, bool female) const
{ {
const ESM::Armor *armor = shield.get<ESM::Armor>()->mBase; const ESM::Armor *armor = shield.get<ESM::Armor>()->mBase;

View file

@ -54,6 +54,7 @@ class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener
osg::Vec4f stubColor = osg::Vec4f(0,0,0,0); osg::Vec4f stubColor = osg::Vec4f(0,0,0,0);
return attachMesh(model, bonename, false, &stubColor); return attachMesh(model, bonename, false, &stubColor);
}; };
osg::ref_ptr<osg::Node> attach(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool isLight);
PartHolderPtr mScabbard; PartHolderPtr mScabbard;
PartHolderPtr mHolsteredShield; PartHolderPtr mHolsteredShield;

View file

@ -145,13 +145,7 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
try try
{ {
osg::ref_ptr<const osg::Node> node = mResourceSystem->getSceneManager()->getTemplate(itemModel); osg::ref_ptr<osg::Node> attached = attach(itemModel, bonename, bonename, item.getType() == ESM::Light::sRecordId);
const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = nodeMap.find(bonename);
if (found == nodeMap.end())
throw std::runtime_error("Can't find attachment node " + bonename);
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(node, mObjectRoot, bonename, found->second.get(), mResourceSystem->getSceneManager());
scene.reset(new PartHolder(attached)); scene.reset(new PartHolder(attached));

View file

@ -645,7 +645,7 @@ void NpcAnimation::updateParts()
{ {
const ESM::Light *light = part.get<ESM::Light>()->mBase; const ESM::Light *light = part.get<ESM::Light>()->mBase;
addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft,
1, "meshes\\"+light->mModel); 1, "meshes\\"+light->mModel, false, nullptr, true);
if (mObjectParts[ESM::PRT_Shield]) if (mObjectParts[ESM::PRT_Shield])
addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), light); addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), light);
} }
@ -675,16 +675,9 @@ void NpcAnimation::updateParts()
PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor) PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight)
{ {
osg::ref_ptr<const osg::Node> templateNode = mResourceSystem->getSceneManager()->getTemplate(model); osg::ref_ptr<osg::Node> attached = attach(model, bonename, bonefilter, isLight);
const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = nodeMap.find(bonename);
if (found == nodeMap.end())
throw std::runtime_error("Can't find attachment node " + bonename);
osg::ref_ptr<osg::Node> attached = SceneUtil::attach(templateNode, mObjectRoot, bonefilter, found->second, mResourceSystem->getSceneManager());
if (enchantedGlow) if (enchantedGlow)
mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, *glowColor); mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, *glowColor);
@ -757,7 +750,7 @@ bool NpcAnimation::isFemalePart(const ESM::BodyPart* bodypart)
return bodypart->mData.mFlags & ESM::BodyPart::BPF_Female; return bodypart->mData.mFlags & ESM::BodyPart::BPF_Female;
} }
bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh, bool enchantedGlow, osg::Vec4f* glowColor) bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight)
{ {
if(priority <= mPartPriorities[type]) if(priority <= mPartPriorities[type])
return false; return false;
@ -789,7 +782,7 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g
// PRT_Hair seems to be the only type that breaks consistency and uses a filter that's different from the attachment bone // 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; const std::string bonefilter = (type == ESM::PRT_Hair) ? "hair" : bonename;
mObjectParts[type] = insertBoundedPart(mesh, bonename, bonefilter, enchantedGlow, glowColor); mObjectParts[type] = insertBoundedPart(mesh, bonename, bonefilter, enchantedGlow, glowColor, isLight);
} }
catch (std::exception& e) catch (std::exception& e)
{ {
@ -981,7 +974,7 @@ void NpcAnimation::showCarriedLeft(bool show)
mesh = getShieldMesh(*iter, !mNpc->isMale()); mesh = getShieldMesh(*iter, !mNpc->isMale());
} }
if (mesh.empty() || addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, if (mesh.empty() || addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1,
mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor)) mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor, iter->getType() == ESM::Light::sRecordId))
{ {
if (mesh.empty()) if (mesh.empty())
reserveIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1); reserveIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1);

View file

@ -83,13 +83,13 @@ private:
NpcType getNpcType() const; NpcType getNpcType() const;
PartHolderPtr insertBoundedPart(const std::string &model, const std::string &bonename, PartHolderPtr insertBoundedPart(const std::string &model, const std::string &bonename,
const std::string &bonefilter, bool enchantedGlow, osg::Vec4f* glowColor=nullptr); const std::string &bonefilter, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight);
void removeIndividualPart(ESM::PartReferenceType type); void removeIndividualPart(ESM::PartReferenceType type);
void reserveIndividualPart(ESM::PartReferenceType type, int group, int priority); void reserveIndividualPart(ESM::PartReferenceType type, int group, int priority);
bool addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh, bool addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh,
bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr); bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr, bool isLight = false);
void removePartGroup(int group); void removePartGroup(int group);
void addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts, void addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts,
bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr); bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr);

View file

@ -100,7 +100,7 @@ namespace SceneUtil
} }
} }
osg::ref_ptr<osg::Node> attach(osg::ref_ptr<const osg::Node> toAttach, osg::Node *master, const std::string &filter, osg::Group* attachNode, Resource::SceneManager* sceneManager) osg::ref_ptr<osg::Node> attach(osg::ref_ptr<const osg::Node> toAttach, osg::Node *master, const std::string &filter, osg::Group* attachNode, Resource::SceneManager* sceneManager, const osg::Quat* attitude)
{ {
if (dynamic_cast<const SceneUtil::Skeleton*>(toAttach.get())) if (dynamic_cast<const SceneUtil::Skeleton*>(toAttach.get()))
{ {
@ -144,8 +144,6 @@ namespace SceneUtil
trans = new osg::PositionAttitudeTransform; trans = new osg::PositionAttitudeTransform;
trans->setPosition(boneOffset->getMatrix().getTrans()); trans->setPosition(boneOffset->getMatrix().getTrans());
// The BoneOffset rotation seems to be incorrect
trans->setAttitude(osg::Quat(osg::DegreesToRadians(-90.f), osg::Vec3f(1,0,0)));
// Now that we used it, get rid of the redundant node. // Now that we used it, get rid of the redundant node.
if (boneOffset->getNumChildren() == 0 && boneOffset->getNumParents() == 1) if (boneOffset->getNumChildren() == 0 && boneOffset->getNumParents() == 1)
@ -172,6 +170,13 @@ namespace SceneUtil
trans->setStateSet(frontFaceStateSet); trans->setStateSet(frontFaceStateSet);
} }
if(attitude)
{
if (!trans)
trans = new osg::PositionAttitudeTransform;
trans->setAttitude(*attitude);
}
if (trans) if (trans)
{ {
attachNode->addChild(trans); attachNode->addChild(trans);

View file

@ -9,6 +9,7 @@ namespace osg
{ {
class Node; class Node;
class Group; class Group;
class Quat;
} }
namespace Resource namespace Resource
{ {
@ -23,7 +24,7 @@ namespace SceneUtil
/// Otherwise, just attach all of the toAttach scenegraph to the attachment node on the master scenegraph, with no filtering. /// Otherwise, just attach all of the toAttach scenegraph to the attachment node on the master scenegraph, with no filtering.
/// @note The master scene graph is expected to include a skeleton. /// @note The master scene graph is expected to include a skeleton.
/// @return A newly created node that is directly attached to the master scene graph /// @return A newly created node that is directly attached to the master scene graph
osg::ref_ptr<osg::Node> attach(osg::ref_ptr<const osg::Node> toAttach, osg::Node* master, const std::string& filter, osg::Group* attachNode, Resource::SceneManager *sceneManager); osg::ref_ptr<osg::Node> attach(osg::ref_ptr<const osg::Node> toAttach, osg::Node* master, const std::string& filter, osg::Group* attachNode, Resource::SceneManager *sceneManager, const osg::Quat* attitude = nullptr);
} }