Don't use xkf if xnif is merely the base model (bug #5371)

7220-lua-add-a-general-purpose-lexical-parser
Alexei Kotov 1 year ago
parent 4d0788e016
commit 434b4deda1

@ -6,6 +6,7 @@
Bug #4816: GetWeaponDrawn returns 1 before weapon is attached
Bug #5057: Weapon swing sound plays at same pitch whether it hits or misses
Bug #5129: Stuttering animation on Centurion Archer
Bug #5371: Keyframe animation tracks are used for any file that begins with an X
Bug #5714: Touch spells cast using ExplodeSpell don't always explode
Bug #5849: Paralysis breaks landing
Bug #5883: Immobile creatures don't cause water ripples

@ -45,7 +45,7 @@ namespace MWClass
{
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
renderingInterface.getObjects().insertModel(ptr, model);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
}
}

@ -108,7 +108,7 @@ namespace MWClass
{
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
renderingInterface.getObjects().insertModel(ptr, model);
}
}

@ -57,7 +57,7 @@ namespace MWClass
{
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
renderingInterface.getObjects().insertModel(ptr, model);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
}
}

@ -40,8 +40,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light>* ref = ptr.get<ESM::Light>();
// Insert even if model is empty, so that the light is added
renderingInterface.getObjects().insertModel(
ptr, model, true, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
renderingInterface.getObjects().insertModel(ptr, model, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
}
void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation,

@ -23,6 +23,7 @@
#include <components/esm3/loadgmst.hpp>
#include <components/esm3/loadmgef.hpp>
#include <components/misc/convert.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/bulletshapemanager.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/settings/settings.hpp>
@ -642,15 +643,15 @@ namespace MWPhysics
void PhysicsSystem::addActor(const MWWorld::Ptr& ptr, const std::string& mesh)
{
osg::ref_ptr<const Resource::BulletShape> shape = mShapeManager->getShape(mesh);
std::string animationMesh = Misc::ResourceHelpers::correctActorModelPath(mesh, mResourceSystem->getVFS());
osg::ref_ptr<const Resource::BulletShape> shape = mShapeManager->getShape(animationMesh);
// Try to get shape from basic model as fallback for creatures
if (!ptr.getClass().isNpc() && shape && shape->mCollisionBox.mExtents.length2() == 0)
{
const std::string fallbackModel = ptr.getClass().getModel(ptr);
if (fallbackModel != mesh)
if (animationMesh != mesh)
{
shape = mShapeManager->getShape(fallbackModel);
shape = mShapeManager->getShape(mesh);
}
}

@ -3,6 +3,7 @@
#include <osg/Group>
#include <osg/UserDataContainer>
#include <components/misc/resourcehelpers.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/unrefqueue.hpp>
@ -68,12 +69,21 @@ namespace MWRender
ptr.getRefData().setBaseNode(insert);
}
void Objects::insertModel(const MWWorld::Ptr& ptr, const std::string& mesh, bool animated, bool allowLight)
void Objects::insertModel(const MWWorld::Ptr& ptr, const std::string& mesh, bool allowLight)
{
insertBegin(ptr);
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Object);
bool animated = ptr.getClass().useAnim();
std::string animationMesh = mesh;
if (animated && !mesh.empty())
{
animationMesh = Misc::ResourceHelpers::correctActorModelPath(mesh, mResourceSystem->getVFS());
if (animationMesh == mesh)
animated = false;
}
osg::ref_ptr<ObjectAnimation> anim(new ObjectAnimation(ptr, mesh, mResourceSystem, animated, allowLight));
osg::ref_ptr<ObjectAnimation> anim(
new ObjectAnimation(ptr, animationMesh, mResourceSystem, animated, allowLight));
mObjects.emplace(ptr.mRef, std::move(anim));
}
@ -83,13 +93,16 @@ namespace MWRender
insertBegin(ptr);
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor);
std::string animationMesh = Misc::ResourceHelpers::correctActorModelPath(mesh, mResourceSystem->getVFS());
// FIXME: if animationMesh == mesh, the creature shouldn't be animated
// CreatureAnimation
osg::ref_ptr<Animation> anim;
if (weaponsShields)
anim = new CreatureWeaponAnimation(ptr, mesh, mResourceSystem);
anim = new CreatureWeaponAnimation(ptr, animationMesh, mResourceSystem);
else
anim = new CreatureAnimation(ptr, mesh, mResourceSystem);
anim = new CreatureAnimation(ptr, animationMesh, mResourceSystem);
if (mObjects.emplace(ptr.mRef, anim).second)
ptr.getClass().getContainerStore(ptr).setContListener(static_cast<ActorAnimation*>(anim.get()));

@ -72,10 +72,8 @@ namespace MWRender
SceneUtil::UnrefQueue& unrefQueue);
~Objects();
/// @param animated Attempt to load separate keyframes from a .kf file matching the model file?
/// @param allowLight If false, no lights will be created, and particles systems will be removed.
void insertModel(
const MWWorld::Ptr& ptr, const std::string& model, bool animated = false, bool allowLight = true);
void insertModel(const MWWorld::Ptr& ptr, const std::string& model, bool allowLight = true);
void insertNPC(const MWWorld::Ptr& ptr);
void insertCreature(const MWWorld::Ptr& ptr, const std::string& model, bool weaponsShields);

@ -90,15 +90,11 @@ namespace
rendering.rotateObject(ptr, rotation);
}
std::string getModel(const MWWorld::Ptr& ptr, const VFS::Manager* vfs)
std::string getModel(const MWWorld::Ptr& ptr)
{
if (Misc::ResourceHelpers::isHiddenMarker(ptr.getCellRef().getRefId()))
return {};
bool useAnim = ptr.getClass().useAnim();
std::string model = ptr.getClass().getModel(ptr);
if (useAnim)
model = Misc::ResourceHelpers::correctActorModelPath(model, vfs);
return model;
return ptr.getClass().getModel(ptr);
}
void addObject(const MWWorld::Ptr& ptr, const MWWorld::World& world, const std::vector<ESM::RefNum>& pagedRefs,
@ -110,7 +106,7 @@ namespace
return;
}
std::string model = getModel(ptr, rendering.getResourceSystem()->getVFS());
std::string model = getModel(ptr);
const auto rotation = makeDirectNodeRotation(ptr);
const ESM::RefNum& refnum = ptr.getCellRef().getRefNum();
@ -279,8 +275,7 @@ namespace MWWorld
{
if (!ptr.getRefData().getBaseNode())
return;
ptr.getClass().insertObjectRendering(
ptr, getModel(ptr, mRendering.getResourceSystem()->getVFS()), mRendering);
ptr.getClass().insertObjectRendering(ptr, getModel(ptr), mRendering);
setNodeRotation(ptr, mRendering, makeNodeRotation(ptr, RotationOrder::direct));
reloadTerrain();
}
@ -630,7 +625,7 @@ namespace MWWorld
ptr.mRef->mData.mPhysicsPostponed = false;
if (ptr.mRef->mData.isEnabled() && ptr.mRef->mData.getCount() > 0)
{
std::string model = getModel(ptr, MWBase::Environment::get().getResourceSystem()->getVFS());
std::string model = getModel(ptr);
if (!model.empty())
{
const auto rotation = makeNodeRotation(ptr, RotationOrder::direct);

@ -2430,10 +2430,8 @@ namespace MWWorld
MWBase::Environment::get().getMechanicsManager()->add(getPlayerPtr());
MWBase::Environment::get().getWindowManager()->watchActor(getPlayerPtr());
std::string model = getPlayerPtr().getClass().getModel(getPlayerPtr());
model = Misc::ResourceHelpers::correctActorModelPath(model, mResourceSystem->getVFS());
mPhysics->remove(getPlayerPtr());
mPhysics->addActor(getPlayerPtr(), model);
mPhysics->addActor(getPlayerPtr(), getPlayerPtr().getClass().getModel(getPlayerPtr()));
applyLoopingParticles(player);

@ -208,6 +208,7 @@ namespace NifBullet
}
// files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see
// Animation::addAnimSource). assume all nodes in the file will be animated
// TODO: investigate whether this should and could be optimized.
const bool isAnimated = pathFileNameStartsWithX(filename);
// If there's no bounding box, we'll have to generate a Bullet collision shape

Loading…
Cancel
Save