//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// #pragma once #include "BsEditorPrerequisites.h" #include "Math/BsVector2I.h" #include "Math/BsMatrix4.h" #include "Math/BsQuaternion.h" namespace bs { /** @addtogroup Handles * @{ */ /** * Base class for all handle sliders. A handle slider is geometry that the user can interact with by selecting or * dragging (sliding) it. Sliders generally output a one- or multi-dimensional delta value that signals the drag * amount (and/or direction). */ class BS_ED_EXPORT HandleSlider { public: /** Possible states the slider can be in. */ enum class State { Inactive, /**< Slider is not being interacted with. */ Active, /**< Slider is clicked on and being dragged. */ Hover /**< Slider is being hovered over but isn't clicked on. */ }; /** * Constructs a new handle slider. * * @param[in] fixedScale If true the handle slider will always try to maintain the same visible area in the * viewport regardless of distance from camera. * @param[in] layer Layer that allows filtering of which sliders are interacted with from a specific camera. */ HandleSlider(bool fixedScale, UINT64 layer); virtual ~HandleSlider() { } /** * Attempts to find an intersection between the provided ray and the slider geometry. * * @param[in] screenPos Position in screen space at which to look for intersection. Some sliders might ignore * this and use the @p ray instead. * @param[in] ray Ray in world space to try to interect with geometry. * @param[in] t Position of the intersection along the ray. Only if intersection happened. * @return Whether an intersection was detected. */ virtual bool intersects(const Vector2I& screenPos, const Ray& ray, float& t) const = 0; /** * Updates a slider that is currently active (being dragged). * * @param[in] camera Camera through which we're interacting with the slider. * @param[in] inputDelta Pointer movement since the last time this method was called. */ virtual void handleInput(const SPtr& camera, const Vector2I& inputDelta) = 0; /** * Updates the state of the slider. Must be called every frame. * * @param[in] camera Camera through which we're interacting with the slider. */ void update(const SPtr& camera); /** Returns the state the slider is currently in. */ State getState() const { return mState; } /** * Returns if fixed scale is enabled. If enabled the handle slider will always try to maintain the same visible * area in the viewport regardless of distance from camera. */ bool getFixedScale() const { return mFixedScale; } /** Returns a layer that determines which sliders are interacted with from a specific camera. */ UINT64 getLayer() const { return mLayer; } /** Sets the world position of the slider. */ void setPosition(const Vector3& position); /** Sets the world rotation of the slider. */ void setRotation(const Quaternion& rotation); /** Sets the scale of the slider. */ void setScale(const Vector3& scale); /** Enables or disables the slider, making it interactable or not. */ void setEnabled(bool enabled); /** Gets the world position of the slider. */ const Vector3& getPosition() const { return mPosition; } /** Gets the world rotation of the slider. */ const Quaternion& getRotation() const { return mRotation; } /** Gets the scale of the slider. */ const Vector3& getScale() const { return mScale; } /** Checks whether the slider can be interacted with or not. */ bool getEnabled() const { return mEnabled; } protected: friend class HandleSliderManager; /** Toggles the slider state to inactive. */ void setInactive(); /** * Toggles the slider state to active. * * @param[in] camera Camera through which the slider was activated. * @param[in] pointerPos Position of the pointer when the slider was activated. */ void setActive(const SPtr& camera, const Vector2I& pointerPos); /** Toggles the slider state to hovered. */ void setHover(); /** Gets the slider transform depending on set position, rotation and scale values. */ const Matrix4& getTransform() const; /** Gets the inverse of the slider transform depending on set position, rotation and scale values. */ const Matrix4& getTransformInv() const; /** Triggered when the slider state is changed to active. */ virtual void activate(const SPtr& camera, const Vector2I& pointerPos) { } /** Triggered when the slider state is changed from active to some other state. */ virtual void reset() { } /** Updates the internal transform from the stored position, rotation and scale values. */ void updateCachedTransform() const; /** * Calculates amount of movement along the provided ray depending on pointer movement. * * @param[in] camera Camera on which the pointer movement is occurring. * @param[in] position Position of the ray to calculate movement on. * @param[in] direction Direction of the ray to calculate movement on. Must be normalized. * @param[in] pointerStart Starting position of the pointer when movement started, in pixels relative to * provided camera. * @param[in] pointerEnd Current position of the pointer, in pixels relative to provided camera. */ float calcDelta(const SPtr& camera, const Vector3& position, const Vector3& direction, const Vector2I& pointerStart, const Vector2I& pointerEnd); bool mFixedScale; UINT64 mLayer; Vector3 mPosition; Quaternion mRotation; Vector3 mScale; float mDistanceScale; Vector2I mStartPointerPos; Vector2I mCurrentPointerPos; State mState; bool mEnabled; mutable bool mTransformDirty; mutable Matrix4 mTransform; mutable Matrix4 mTransformInv; }; /** @} */ }