#pragma once #include "BsEditorPrerequisites.h" #include "BsModule.h" #include "BsMatrix4.h" #include "BsGpuParam.h" namespace BansheeEngine { class ScenePickingCore; /** * @brief Handles picking of scene objects with a pointer in scene view. */ class ScenePicking : public Module { /** * @brief Contains information about a single pickable item (mesh). */ struct RenderablePickData { SPtr mesh; UINT32 index; Matrix4 wvpTransform; bool alpha; CullingMode cullMode; HTexture mainTexture; }; public: ScenePicking(); ~ScenePicking(); /** * @brief Attempts to find a single nearest scene object under the provided position and area. * * @param cam Camera to perform the picking from. * @param position Pointer position relative to the camera viewport, in pixels. * @param area Width/height of the checked area in pixels. Use (1, 1) if you want the * exact position under the pointer. * * @return Nearest SceneObject under the provided area, or an empty handle if no object is found. */ HSceneObject pickClosestObject(const CameraPtr& cam, const Vector2I& position, const Vector2I& area); /** * @brief Attempts to find all scene objects under the provided position and area. This does not mean * objects occluded by other objects. * * @param cam Camera to perform the picking from. * @param position Pointer position relative to the camera viewport, in pixels. * @param area Width/height of the checked area in pixels. Use (1, 1) if you want the * exact position under the pointer. * * @return A list of SceneObject%s under the provided area. */ Vector pickObjects(const CameraPtr& cam, const Vector2I& position, const Vector2I& area); private: friend class ScenePickingCore; typedef Set> RenderableSet; /** * @brief Encodes a pickable object identifier to a unique color. */ static Color encodeIndex(UINT32 index); /** * @brief Decodes a color into a unique object identifier. Color should * have initially been encoded with ::encodeIndex. */ static UINT32 decodeIndex(Color color); ScenePickingCore* mCore; }; /** * @brief Core thread version of the ScenePicking manager. Handles * actual rendering. */ class ScenePickingCore { /** * @brief A list of materials and their parameters to be used for rendering * of pickable objects. */ struct MaterialData { SPtr mMatPickingCore; SPtr mMatPickingAlphaCore; SPtr mParamPickingVertParams; SPtr mParamPickingFragParams; SPtr mParamPickingAlphaVertParams; SPtr mParamPickingAlphaFragParams; GpuParamMat4Core mParamPickingWVP; GpuParamMat4Core mParamPickingAlphaWVP; GpuParamColorCore mParamPickingColor; GpuParamColorCore mParamPickingAlphaColor; GpuParamTextureCore mParamPickingAlphaTexture; }; public: /** * @brief Initializes the manager. Must be called right after construction. */ void initialize(); /** * @brief Destroys the manager. Must be called right before destruction. */ void destroy(); /** * @brief Sets up the viewport, materials and their parameters as needed for picking. Also renders * all the provided renderable objects. Must be followed by ::corePickingEnd. You may call other methods * after this one, but you must ensure they render proper unique pickable colors that can be resolved * to SceneObject%s later. * * @param target Render target to render to. * @param viewportArea Normalized area of the render target to render in. * @param renderables A set of pickable Renderable objects to render. * @param position Position of the pointer where to pick objects, in pixels relative to viewport. * @param area Width/height of the area to pick objects, in pixels. */ void corePickingBegin(const SPtr& target, const Rect2& viewportArea, const ScenePicking::RenderableSet& renderables, const Vector2I& position, const Vector2I& area); /** * @brief Ends picking operation started by ::corePickingBegin. Render target is resolved and objects in the picked area * are returned. * * @param target Render target we're rendering to. * @param viewportArea Normalized area of the render target we're rendering in. * @param position Position of the pointer where to pick objects, in pixels relative to viewport. * @param area Width/height of the area to pick objects, in pixels. * @param asyncOp Async operation handle that when complete will contain the results of the picking * operation in the form of Vector. */ void corePickingEnd(const SPtr& target, const Rect2& viewportArea, const Vector2I& position, const Vector2I& area, AsyncOp& asyncOp); private: friend class ScenePicking; static const float ALPHA_CUTOFF; MaterialData mMaterialData[3]; }; }