Override the field of view for first person meshes (Fixes #858, Fixes #3051)

openmw-38
scrawl 9 years ago
parent 9621b66b78
commit e520d37c87

@ -5,6 +5,7 @@
#include <osg/Depth> #include <osg/Depth>
#include <osgUtil/RenderBin> #include <osgUtil/RenderBin>
#include <osgUtil/CullVisitor>
#include <components/misc/rng.hpp> #include <components/misc/rng.hpp>
@ -274,13 +275,15 @@ NpcAnimation::~NpcAnimation()
mPtr.getClass().getInventoryStore(mPtr).setListener(NULL, mPtr); mPtr.getClass().getInventoryStore(mPtr).setListener(NULL, mPtr);
} }
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem, bool disableListener, bool disableSounds, ViewMode viewMode) NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
bool disableListener, bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView)
: Animation(ptr, parentNode, resourceSystem), : Animation(ptr, parentNode, resourceSystem),
mListenerDisabled(disableListener), mListenerDisabled(disableListener),
mViewMode(viewMode), mViewMode(viewMode),
mShowWeapons(false), mShowWeapons(false),
mShowCarriedLeft(true), mShowCarriedLeft(true),
mNpcType(Type_Normal), mNpcType(Type_Normal),
mFirstPersonFieldOfView(firstPersonFieldOfView),
mSoundsDisabled(disableSounds), mSoundsDisabled(disableSounds),
mAccurateAiming(false), mAccurateAiming(false),
mAimingFactor(0.f) mAimingFactor(0.f)
@ -336,6 +339,37 @@ public:
osg::ref_ptr<osg::Depth> mDepth; osg::ref_ptr<osg::Depth> mDepth;
}; };
/// Overrides Field of View to given value for rendering the subgraph.
/// Must be added as cull callback.
class OverrideFieldOfViewCallback : public osg::NodeCallback
{
public:
OverrideFieldOfViewCallback(float fov)
: mFov(fov)
{
}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
osg::RefMatrix* projectionMatrix = new osg::RefMatrix(*cv->getProjectionMatrix());
float fov, aspect, zNear, zFar;
if (projectionMatrix->getPerspective(fov, aspect, zNear, zFar))
{
fov = mFov;
projectionMatrix->makePerspective(fov, aspect, zNear, zFar);
cv->pushProjectionMatrix(projectionMatrix);
traverse(node, nv);
cv->popProjectionMatrix();
}
else
traverse(node, nv);
}
private:
float mFov;
};
void NpcAnimation::setRenderBin() void NpcAnimation::setRenderBin()
{ {
if (mViewMode == VM_FirstPerson) if (mViewMode == VM_FirstPerson)
@ -445,6 +479,7 @@ void NpcAnimation::updateNpcBase()
else else
{ {
mObjectRoot->setNodeMask(Mask_FirstPerson); mObjectRoot->setNodeMask(Mask_FirstPerson);
mObjectRoot->addCullCallback(new OverrideFieldOfViewCallback(mFirstPersonFieldOfView));
if(isWerewolf) if(isWerewolf)
addAnimSource(smodel); addAnimSource(smodel);
else else

@ -61,6 +61,8 @@ private:
int mPartPriorities[ESM::PRT_Count]; int mPartPriorities[ESM::PRT_Count];
osg::Vec3f mFirstPersonOffset; osg::Vec3f mFirstPersonOffset;
// Field of view to use when rendering first person meshes
float mFirstPersonFieldOfView;
boost::shared_ptr<HeadAnimationTime> mHeadAnimationTime; boost::shared_ptr<HeadAnimationTime> mHeadAnimationTime;
boost::shared_ptr<WeaponAnimationTime> mWeaponAnimationTime; boost::shared_ptr<WeaponAnimationTime> mWeaponAnimationTime;
@ -102,7 +104,7 @@ public:
* @param viewMode * @param viewMode
*/ */
NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem, bool disableListener = false, NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem, bool disableListener = false,
bool disableSounds = false, ViewMode viewMode=VM_Normal); bool disableSounds = false, ViewMode viewMode=VM_Normal, float firstPersonFieldOfView=55.f);
virtual ~NpcAnimation(); virtual ~NpcAnimation();
virtual void enableHeadAnimation(bool enable); virtual void enableHeadAnimation(bool enable);

@ -208,6 +208,7 @@ namespace MWRender
mNearClip = Settings::Manager::getFloat("near clip", "Camera"); mNearClip = Settings::Manager::getFloat("near clip", "Camera");
mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera"); mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera");
mFieldOfView = Settings::Manager::getFloat("field of view", "Camera"); mFieldOfView = Settings::Manager::getFloat("field of view", "Camera");
mFirstPersonFieldOfView = Settings::Manager::getFloat("first person field of view", "Camera");
updateProjectionMatrix(); updateProjectionMatrix();
mStateUpdater->setFogEnd(mViewDistance); mStateUpdater->setFogEnd(mViewDistance);
@ -729,7 +730,8 @@ namespace MWRender
void RenderingManager::renderPlayer(const MWWorld::Ptr &player) void RenderingManager::renderPlayer(const MWWorld::Ptr &player)
{ {
mPlayerAnimation.reset(new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0)); mPlayerAnimation.reset(new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0, false, NpcAnimation::VM_Normal,
mFirstPersonFieldOfView));
mCamera->setAnimation(mPlayerAnimation.get()); mCamera->setAnimation(mPlayerAnimation.get());
mCamera->attachTo(player); mCamera->attachTo(player);

@ -216,6 +216,7 @@ namespace MWRender
float mFieldOfViewOverride; float mFieldOfViewOverride;
bool mFieldOfViewOverridden; bool mFieldOfViewOverridden;
float mFieldOfView; float mFieldOfView;
float mFirstPersonFieldOfView;
void operator = (const RenderingManager&); void operator = (const RenderingManager&);
RenderingManager(const RenderingManager&); RenderingManager(const RenderingManager&);

@ -24,8 +24,13 @@ small feature culling = true
viewing distance = 6666.0 viewing distance = 6666.0
# Camera field of view in degrees (e.g. 30.0 to 110.0). # Camera field of view in degrees (e.g. 30.0 to 110.0).
# Does not affect the player's hands in the first person camera.
field of view = 55.0 field of view = 55.0
# Field of view for first person meshes (i.e. the player's hands)
# Best to leave this at the default since vanilla assets are not complete enough to adapt to high FoV's. Too low FoV would clip the hands off screen.
first person field of view = 55.0
[Cells] [Cells]
# Adjacent exterior cells loaded (>0). Caution: this setting can # Adjacent exterior cells loaded (>0). Caution: this setting can

Loading…
Cancel
Save