mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-19 10:39:44 +00:00
Don't use xkf if xnif is merely the base model (bug #5371)
This commit is contained in:
parent
4d0788e016
commit
434b4deda1
11 changed files with 35 additions and 29 deletions
|
@ -6,6 +6,7 @@
|
||||||
Bug #4816: GetWeaponDrawn returns 1 before weapon is attached
|
Bug #4816: GetWeaponDrawn returns 1 before weapon is attached
|
||||||
Bug #5057: Weapon swing sound plays at same pitch whether it hits or misses
|
Bug #5057: Weapon swing sound plays at same pitch whether it hits or misses
|
||||||
Bug #5129: Stuttering animation on Centurion Archer
|
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 #5714: Touch spells cast using ExplodeSpell don't always explode
|
||||||
Bug #5849: Paralysis breaks landing
|
Bug #5849: Paralysis breaks landing
|
||||||
Bug #5883: Immobile creatures don't cause water ripples
|
Bug #5883: Immobile creatures don't cause water ripples
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
if (!model.empty())
|
if (!model.empty())
|
||||||
{
|
{
|
||||||
renderingInterface.getObjects().insertModel(ptr, model, true);
|
renderingInterface.getObjects().insertModel(ptr, model);
|
||||||
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
|
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
if (!model.empty())
|
if (!model.empty())
|
||||||
{
|
{
|
||||||
renderingInterface.getObjects().insertModel(ptr, model, true);
|
renderingInterface.getObjects().insertModel(ptr, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
if (!model.empty())
|
if (!model.empty())
|
||||||
{
|
{
|
||||||
renderingInterface.getObjects().insertModel(ptr, model, true);
|
renderingInterface.getObjects().insertModel(ptr, model);
|
||||||
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
|
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Light>* ref = ptr.get<ESM::Light>();
|
MWWorld::LiveCellRef<ESM::Light>* ref = ptr.get<ESM::Light>();
|
||||||
|
|
||||||
// Insert even if model is empty, so that the light is added
|
// Insert even if model is empty, so that the light is added
|
||||||
renderingInterface.getObjects().insertModel(
|
renderingInterface.getObjects().insertModel(ptr, model, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
|
||||||
ptr, model, true, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation,
|
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/loadgmst.hpp>
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
#include <components/misc/convert.hpp>
|
#include <components/misc/convert.hpp>
|
||||||
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
#include <components/resource/bulletshapemanager.hpp>
|
#include <components/resource/bulletshapemanager.hpp>
|
||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
@ -642,15 +643,15 @@ namespace MWPhysics
|
||||||
|
|
||||||
void PhysicsSystem::addActor(const MWWorld::Ptr& ptr, const std::string& mesh)
|
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
|
// Try to get shape from basic model as fallback for creatures
|
||||||
if (!ptr.getClass().isNpc() && shape && shape->mCollisionBox.mExtents.length2() == 0)
|
if (!ptr.getClass().isNpc() && shape && shape->mCollisionBox.mExtents.length2() == 0)
|
||||||
{
|
{
|
||||||
const std::string fallbackModel = ptr.getClass().getModel(ptr);
|
if (animationMesh != mesh)
|
||||||
if (fallbackModel != mesh)
|
|
||||||
{
|
{
|
||||||
shape = mShapeManager->getShape(fallbackModel);
|
shape = mShapeManager->getShape(mesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <osg/Group>
|
#include <osg/Group>
|
||||||
#include <osg/UserDataContainer>
|
#include <osg/UserDataContainer>
|
||||||
|
|
||||||
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||||
#include <components/sceneutil/unrefqueue.hpp>
|
#include <components/sceneutil/unrefqueue.hpp>
|
||||||
|
|
||||||
|
@ -68,12 +69,21 @@ namespace MWRender
|
||||||
ptr.getRefData().setBaseNode(insert);
|
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);
|
insertBegin(ptr);
|
||||||
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Object);
|
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));
|
mObjects.emplace(ptr.mRef, std::move(anim));
|
||||||
}
|
}
|
||||||
|
@ -83,13 +93,16 @@ namespace MWRender
|
||||||
insertBegin(ptr);
|
insertBegin(ptr);
|
||||||
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor);
|
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
|
// CreatureAnimation
|
||||||
osg::ref_ptr<Animation> anim;
|
osg::ref_ptr<Animation> anim;
|
||||||
|
|
||||||
if (weaponsShields)
|
if (weaponsShields)
|
||||||
anim = new CreatureWeaponAnimation(ptr, mesh, mResourceSystem);
|
anim = new CreatureWeaponAnimation(ptr, animationMesh, mResourceSystem);
|
||||||
else
|
else
|
||||||
anim = new CreatureAnimation(ptr, mesh, mResourceSystem);
|
anim = new CreatureAnimation(ptr, animationMesh, mResourceSystem);
|
||||||
|
|
||||||
if (mObjects.emplace(ptr.mRef, anim).second)
|
if (mObjects.emplace(ptr.mRef, anim).second)
|
||||||
ptr.getClass().getContainerStore(ptr).setContListener(static_cast<ActorAnimation*>(anim.get()));
|
ptr.getClass().getContainerStore(ptr).setContListener(static_cast<ActorAnimation*>(anim.get()));
|
||||||
|
|
|
@ -72,10 +72,8 @@ namespace MWRender
|
||||||
SceneUtil::UnrefQueue& unrefQueue);
|
SceneUtil::UnrefQueue& unrefQueue);
|
||||||
~Objects();
|
~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.
|
/// @param allowLight If false, no lights will be created, and particles systems will be removed.
|
||||||
void insertModel(
|
void insertModel(const MWWorld::Ptr& ptr, const std::string& model, bool allowLight = true);
|
||||||
const MWWorld::Ptr& ptr, const std::string& model, bool animated = false, bool allowLight = true);
|
|
||||||
|
|
||||||
void insertNPC(const MWWorld::Ptr& ptr);
|
void insertNPC(const MWWorld::Ptr& ptr);
|
||||||
void insertCreature(const MWWorld::Ptr& ptr, const std::string& model, bool weaponsShields);
|
void insertCreature(const MWWorld::Ptr& ptr, const std::string& model, bool weaponsShields);
|
||||||
|
|
|
@ -90,15 +90,11 @@ namespace
|
||||||
rendering.rotateObject(ptr, rotation);
|
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()))
|
if (Misc::ResourceHelpers::isHiddenMarker(ptr.getCellRef().getRefId()))
|
||||||
return {};
|
return {};
|
||||||
bool useAnim = ptr.getClass().useAnim();
|
return ptr.getClass().getModel(ptr);
|
||||||
std::string model = ptr.getClass().getModel(ptr);
|
|
||||||
if (useAnim)
|
|
||||||
model = Misc::ResourceHelpers::correctActorModelPath(model, vfs);
|
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addObject(const MWWorld::Ptr& ptr, const MWWorld::World& world, const std::vector<ESM::RefNum>& pagedRefs,
|
void addObject(const MWWorld::Ptr& ptr, const MWWorld::World& world, const std::vector<ESM::RefNum>& pagedRefs,
|
||||||
|
@ -110,7 +106,7 @@ namespace
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string model = getModel(ptr, rendering.getResourceSystem()->getVFS());
|
std::string model = getModel(ptr);
|
||||||
const auto rotation = makeDirectNodeRotation(ptr);
|
const auto rotation = makeDirectNodeRotation(ptr);
|
||||||
|
|
||||||
const ESM::RefNum& refnum = ptr.getCellRef().getRefNum();
|
const ESM::RefNum& refnum = ptr.getCellRef().getRefNum();
|
||||||
|
@ -279,8 +275,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
if (!ptr.getRefData().getBaseNode())
|
if (!ptr.getRefData().getBaseNode())
|
||||||
return;
|
return;
|
||||||
ptr.getClass().insertObjectRendering(
|
ptr.getClass().insertObjectRendering(ptr, getModel(ptr), mRendering);
|
||||||
ptr, getModel(ptr, mRendering.getResourceSystem()->getVFS()), mRendering);
|
|
||||||
setNodeRotation(ptr, mRendering, makeNodeRotation(ptr, RotationOrder::direct));
|
setNodeRotation(ptr, mRendering, makeNodeRotation(ptr, RotationOrder::direct));
|
||||||
reloadTerrain();
|
reloadTerrain();
|
||||||
}
|
}
|
||||||
|
@ -630,7 +625,7 @@ namespace MWWorld
|
||||||
ptr.mRef->mData.mPhysicsPostponed = false;
|
ptr.mRef->mData.mPhysicsPostponed = false;
|
||||||
if (ptr.mRef->mData.isEnabled() && ptr.mRef->mData.getCount() > 0)
|
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())
|
if (!model.empty())
|
||||||
{
|
{
|
||||||
const auto rotation = makeNodeRotation(ptr, RotationOrder::direct);
|
const auto rotation = makeNodeRotation(ptr, RotationOrder::direct);
|
||||||
|
|
|
@ -2430,10 +2430,8 @@ namespace MWWorld
|
||||||
MWBase::Environment::get().getMechanicsManager()->add(getPlayerPtr());
|
MWBase::Environment::get().getMechanicsManager()->add(getPlayerPtr());
|
||||||
MWBase::Environment::get().getWindowManager()->watchActor(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->remove(getPlayerPtr());
|
||||||
mPhysics->addActor(getPlayerPtr(), model);
|
mPhysics->addActor(getPlayerPtr(), getPlayerPtr().getClass().getModel(getPlayerPtr()));
|
||||||
|
|
||||||
applyLoopingParticles(player);
|
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
|
// 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
|
// 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);
|
const bool isAnimated = pathFileNameStartsWithX(filename);
|
||||||
|
|
||||||
// If there's no bounding box, we'll have to generate a Bullet collision shape
|
// If there's no bounding box, we'll have to generate a Bullet collision shape
|
||||||
|
|
Loading…
Reference in a new issue