#ifndef GAME_MWRENDER_CAMERA_H #define GAME_MWRENDER_CAMERA_H #include #include #include #include #include "../mwworld/ptr.hpp" namespace osg { class Camera; class NodeCallback; class Node; } namespace MWRender { class NpcAnimation; /// \brief Camera control class Camera { public: enum class Mode { Normal, Vanity, Preview, StandingPreview }; private: MWWorld::Ptr mTrackingPtr; osg::ref_ptr mTrackingNode; float mHeightScale; osg::ref_ptr mCamera; NpcAnimation *mAnimation; bool mFirstPersonView; Mode mMode; bool mVanityAllowed; bool mStandingPreviewAllowed; bool mDeferredRotationAllowed; float mNearest; float mFurthest; bool mIsNearest; float mHeight, mBaseCameraDistance; float mPitch, mYaw, mRoll; bool mVanityToggleQueued; bool mVanityToggleQueuedValue; bool mViewModeToggleQueued; float mCameraDistance; float mMaxNextCameraDistance; osg::Vec3d mFocalPointAdjustment; 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; bool mHeadBobbingEnabled; float mHeadBobbingOffset; float mHeadBobbingWeight; // Value from 0 to 1 for smooth enabling/disabling. float mTotalMovement; // Needed for head bobbing. void updateHeadBobbing(float duration); void updateFocalPointOffset(float duration); void updatePosition(); float getCameraDistanceCorrection() const; osg::ref_ptr 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: Camera(osg::Camera* camera); ~Camera(); /// Attach camera to object void attachTo(const MWWorld::Ptr &ptr) { mTrackingPtr = ptr; } MWWorld::Ptr getTrackingPtr() const { return mTrackingPtr; } void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeedCoef = v; } void setFocalPointTargetOffset(osg::Vec2d v); void instantTransition(); void enableDynamicCameraDistance(bool v) { mDynamicCameraDistanceEnabled = v; } void enableCrosshairInThirdPersonMode(bool v) { mShowCrosshairInThirdPersonMode = v; } /// Update the view matrix of \a cam void updateCamera(osg::Camera* cam); /// Reset to defaults void reset(); /// Set where the camera is looking at. Uses Morrowind (euler) angles /// \param rot Rotation angles in radians void rotateCamera(float pitch, float yaw, bool adjust); 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); bool toggleVanityMode(bool enable); void allowVanityMode(bool allow); /// @note this may be ignored if an important animation is currently playing void togglePreviewMode(bool enable); void applyDeferredPreviewRotationToPlayer(float dt); void disableDeferredPreviewRotation() { mDeferredRotationDisabled = true; } /// \brief Lowers the camera for sneak. void setSneakOffset(float offset); bool isFirstPerson() const { return mFirstPersonView && mMode == Mode::Normal; } void processViewChange(); void update(float duration, bool paused=false); /// Adds distDelta to the camera distance. Switches 3rd/1st person view if distance is less than limit. void adjustCameraDistance(float distDelta); float getCameraDistance() const; void setAnimation(NpcAnimation *anim); osg::Vec3d getFocalPoint() const; osg::Vec3d getFocalPointOffset() const; /// Stores focal and camera world positions in passed arguments void getPosition(osg::Vec3d &focal, osg::Vec3d &camera) const; bool isVanityOrPreviewModeEnabled() const { return mMode != Mode::Normal; } Mode getMode() const { return mMode; } bool isNearest() const { return mIsNearest; } }; } #endif