1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-30 03:32:36 +00:00
OpenMW/apps/openmw/mwrender/camera.hpp

162 lines
4.9 KiB
C++
Raw Normal View History

2013-04-29 05:50:40 -07:00
#ifndef GAME_MWRENDER_CAMERA_H
#define GAME_MWRENDER_CAMERA_H
2021-06-20 00:57:41 +02:00
#include <optional>
#include <string>
2011-02-10 12:56:19 +01:00
2015-05-21 23:54:39 +02:00
#include <osg/ref_ptr>
#include <osg/Vec3>
2015-06-01 15:34:46 +02:00
#include <osg/Vec3d>
2015-05-21 23:54:39 +02:00
#include "../mwworld/ptr.hpp"
2015-05-21 23:54:39 +02:00
namespace osg
2012-08-12 18:35:35 +04:00
{
class Camera;
class Callback;
2015-05-21 23:54:39 +02:00
class Node;
}
namespace MWRender
{
2012-08-14 20:33:29 +04:00
class NpcAnimation;
2013-04-29 05:50:40 -07:00
/// \brief Camera control
class Camera
{
public:
2021-06-20 00:57:41 +02:00
enum class Mode : int {Static = 0, FirstPerson = 1, ThirdPerson = 2, Vanity = 3, Preview = 4, StandingPreview = 5};
2020-06-22 01:54:08 +02:00
private:
MWWorld::Ptr mTrackingPtr;
2015-05-21 23:54:39 +02:00
osg::ref_ptr<const osg::Node> mTrackingNode;
float mHeightScale;
2012-08-12 15:50:37 +04:00
2015-05-21 23:54:39 +02:00
osg::ref_ptr<osg::Camera> mCamera;
2012-08-14 20:33:29 +04:00
NpcAnimation *mAnimation;
2021-06-20 00:57:41 +02:00
// Always 'true' if mMode == `FirstPerson`. Also it is 'true' in `Vanity` or `Preview` modes if
// the camera should return to `FirstPerson` view after it.
bool mFirstPersonView;
2021-06-20 00:57:41 +02:00
Mode mMode;
2021-06-20 00:57:41 +02:00
std::optional<Mode> mQueuedMode;
bool mVanityAllowed;
bool mStandingPreviewAllowed;
bool mDeferredRotationAllowed;
float mNearest;
float mFurthest;
bool mIsNearest;
2012-08-12 15:50:37 +04:00
2021-06-20 00:57:41 +02:00
bool mProcessViewChange;
2020-06-22 01:54:08 +02:00
float mHeight, mBaseCameraDistance;
2020-10-04 20:12:45 +02:00
float mPitch, mYaw, mRoll;
2021-06-20 00:57:41 +02:00
osg::Vec3d mPosition;
2015-05-21 23:54:39 +02:00
float mCameraDistance;
float mMaxNextCameraDistance;
2015-05-21 23:54:39 +02:00
osg::Vec2d mFocalPointCurrentOffset;
osg::Vec2d mFocalPointTargetOffset;
float mFocalPointTransitionSpeedCoef;
bool mSkipFocalPointTransition;
// This fields are used to make focal point transition smooth if previous transition was not finished.
float mPreviousTransitionInfluence;
osg::Vec2d mFocalPointTransitionSpeed;
osg::Vec2d mPreviousTransitionSpeed;
osg::Vec2d mPreviousExtraOffset;
float mSmoothedSpeed;
float mZoomOutWhenMoveCoef;
bool mDynamicCameraDistanceEnabled;
bool mShowCrosshairInThirdPersonMode;
2020-10-04 20:12:45 +02:00
bool mHeadBobbingEnabled;
float mHeadBobbingOffset;
2020-10-28 18:02:31 +04:00
float mHeadBobbingWeight; // Value from 0 to 1 for smooth enabling/disabling.
float mTotalMovement; // Needed for head bobbing.
2020-10-04 20:12:45 +02:00
void updateHeadBobbing(float duration);
2021-06-20 00:57:41 +02:00
osg::Vec3d getTrackingNodePosition() const;
osg::Vec3d getFocalPointOffset() const;
void updateFocalPointOffset(float duration);
void updatePosition();
2020-06-22 01:54:08 +02:00
float getCameraDistanceCorrection() const;
osg::ref_ptr<osg::Callback> mUpdateCallback;
// Used to rotate player to the direction of view after exiting preview or vanity mode.
osg::Vec3f mDeferredRotation;
bool mDeferredRotationDisabled;
void calculateDeferredRotation();
void updateStandingPreviewMode();
public:
2015-05-21 23:54:39 +02:00
Camera(osg::Camera* camera);
2013-04-29 05:50:40 -07:00
~Camera();
/// Attach camera to object
void attachTo(const MWWorld::Ptr &ptr) { mTrackingPtr = ptr; }
MWWorld::Ptr getTrackingPtr() const { return mTrackingPtr; }
2015-05-21 23:54:39 +02:00
void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeedCoef = v; }
2021-06-20 00:57:41 +02:00
void setFocalPointTargetOffset(const osg::Vec2d& v);
void instantTransition();
void enableDynamicCameraDistance(bool v) { mDynamicCameraDistanceEnabled = v; }
void enableCrosshairInThirdPersonMode(bool v) { mShowCrosshairInThirdPersonMode = v; }
2015-05-21 23:54:39 +02:00
/// Update the view matrix of \a cam
void updateCamera(osg::Camera* cam);
2013-05-17 22:53:43 +02:00
/// Reset to defaults
2021-06-20 00:57:41 +02:00
void reset() { setMode(Mode::FirstPerson); }
2013-05-17 22:53:43 +02:00
void rotateCameraToTrackingPtr();
float getYaw() const { return mYaw; }
void setYaw(float angle);
float getPitch() const { return mPitch; }
void setPitch(float angle);
/// @param Force view mode switch, even if currently not allowed by the animation.
void toggleViewMode(bool force=false);
2012-08-12 15:50:37 +04:00
2013-04-27 01:24:36 -07:00
bool toggleVanityMode(bool enable);
2012-08-14 14:37:48 +04:00
void allowVanityMode(bool allow);
2012-08-12 15:50:37 +04:00
/// @note this may be ignored if an important animation is currently playing
2012-08-14 02:36:18 +04:00
void togglePreviewMode(bool enable);
void applyDeferredPreviewRotationToPlayer(float dt);
void disableDeferredPreviewRotation() { mDeferredRotationDisabled = true; }
/// \brief Lowers the camera for sneak.
void setSneakOffset(float offset);
void processViewChange();
void update(float duration, bool paused=false);
2012-08-14 14:37:48 +04:00
/// Adds distDelta to the camera distance. Switches 3rd/1st person view if distance is less than limit.
void adjustCameraDistance(float distDelta);
float getCameraDistance() const;
2013-01-17 15:48:09 -08:00
void setAnimation(NpcAnimation *anim);
2012-08-14 20:33:29 +04:00
2021-06-20 00:57:41 +02:00
osg::Vec3d getThirdPersonBasePosition() const;
const osg::Vec3d& getPosition() const { return mPosition; }
2021-06-20 00:57:41 +02:00
bool isVanityOrPreviewModeEnabled() const;
Mode getMode() const { return mMode; }
2021-06-20 00:57:41 +02:00
void setMode(Mode mode, bool force = true);
};
}
#endif