HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pickTask.h
Go to the documentation of this file.
1 //
2 // Copyright 2019 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_HDX_PICK_TASK_H
25 #define PXR_IMAGING_HDX_PICK_TASK_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hdx/api.h"
29 
30 #include "pxr/imaging/hd/enums.h"
34 #include "pxr/imaging/hd/task.h"
35 
37 
39 #include "pxr/base/gf/matrix4d.h"
40 #include "pxr/base/gf/vec2i.h"
41 #include "pxr/base/gf/vec2f.h"
42 #include "pxr/base/gf/vec4i.h"
43 #include "pxr/base/gf/vec4d.h"
44 #include "pxr/usd/sdf/path.h"
45 
46 #include <vector>
47 #include <memory>
48 
50 
51 #define HDX_PICK_TOKENS \
52  /* Task context */ \
53  (pickParams) \
54  \
55  /* Hit mode */ \
56  (hitFirst) \
57  (hitAll) \
58  \
59  /* Pick target */ \
60  (pickPrimsAndInstances) \
61  (pickFaces) \
62  (pickEdges) \
63  (pickPoints) \
64  \
65  /* Resolve mode */ \
66  (resolveNearestToCamera) \
67  (resolveNearestToCenter) \
68  (resolveUnique) \
69  (resolveAll)
70 
72 
74 using HdStShaderCodeSharedPtr = std::shared_ptr<class HdStShaderCode>;
75 
76 /// Pick task params. This contains render-style state (for example), but is
77 /// augmented by HdxPickTaskContextParams, which is passed in on the task
78 /// context.
80 {
83  , enableSceneMaterials(true)
84  {}
85 
88 };
89 
90 /// Picking hit structure. This is output by the pick task as a record of
91 /// what objects the picking query found.
92 struct HdxPickHit {
98  int edgeIndex;
102  // normalizedDepth is in the range [0,1].
104 
105  inline bool IsValid() const {
106  return !objectId.IsEmpty();
107  }
108 
109  HDX_API
110  size_t GetHash() const;
111 };
112 
113 typedef std::vector<HdxPickHit> HdxPickHitVector;
114 
115 /// Pick task context params. This contains task params that can't come from
116 /// the scene delegate (like resolution mode and pick location, that might
117 /// be resolved late), as well as the picking collection and the output
118 /// hit vector.
120 {
121  typedef std::function<void(void)> DepthMaskCallback;
122 
124  : resolution(128, 128)
125  , hitMode(HdxPickTokens->hitFirst)
126  , pickTarget(HdxPickTokens->pickPrimsAndInstances)
127  , resolveMode(HdxPickTokens->resolveNearestToCamera)
128  , doUnpickablesOcclude(false)
129  , viewMatrix(1)
130  , projectionMatrix(1)
131  , clipPlanes()
132  , depthMaskCallback(nullptr)
133  , collection()
134  , outHits(nullptr)
135  {}
136 
144  std::vector<GfVec4d> clipPlanes;
148 };
149 
150 /// \class HdxPickTask
151 ///
152 /// A task for running picking queries against the current scene.
153 /// This task generates an id buffer for a "pick frustum" (normally the
154 /// camera frustum with the near plane narrowed to an (x,y) location and a
155 /// pick radius); then it resolves that id buffer into a series of prim paths.
156 /// The "Hit" output also contains subprim picking results (e.g. picked face,
157 /// edge, point, instance) and the intersection point in scene worldspace.
158 ///
159 /// HdxPickTask takes an HdxPickTaskParams through the scene delegate, and
160 /// HdxPickTaskContextParams through the task context as "pickParams".
161 /// It produces a hit vector, in the task context as "pickHits".
162 class HdxPickTask : public HdTask
163 {
164 public:
165  HDX_API
166  HdxPickTask(HdSceneDelegate* delegate, SdfPath const& id);
167 
168  HDX_API
169  virtual ~HdxPickTask();
170 
171  /// Sync the render pass resources
172  HDX_API
173  virtual void Sync(HdSceneDelegate* delegate,
174  HdTaskContext* ctx,
175  HdDirtyBits* dirtyBits) override;
176 
177  /// Prepare the pick task
178  HDX_API
179  virtual void Prepare(HdTaskContext* ctx,
180  HdRenderIndex* renderIndex) override;
181 
182  /// Execute the pick task
183  HDX_API
184  virtual void Execute(HdTaskContext* ctx) override;
185 
186  HDX_API
187  virtual const TfTokenVector &GetRenderTags() const override;
188 
189  /// Utility: Given a UNorm8Vec4 pixel, unpack it into an int32 ID.
190  static inline int DecodeIDRenderColor(unsigned char const idColor[4]) {
191  return (int32_t(idColor[0] & 0xff) << 0) |
192  (int32_t(idColor[1] & 0xff) << 8) |
193  (int32_t(idColor[2] & 0xff) << 16) |
194  (int32_t(idColor[3] & 0xff) << 24);
195  }
196 
197 private:
198  HdxPickTaskParams _params;
199  HdxPickTaskContextParams _contextParams;
200  TfTokenVector _renderTags;
201 
202  // We need to cache a pointer to the render index so Execute() can
203  // map prim ID to paths.
204  HdRenderIndex *_index;
205 
206  void _Init(GfVec2i const& widthHeight);
207  void _SetResolution(GfVec2i const& widthHeight);
208  void _ConditionStencilWithGLCallback(
210  void _ConfigureSceneMaterials(
211  bool enableSceneMaterials, HdStRenderPassState *renderPassState);
212 
213  bool _UseOcclusionPass() const;
214 
215  // Create a shared render pass each for pickables and unpickables
216  HdRenderPassSharedPtr _pickableRenderPass;
217  HdRenderPassSharedPtr _occluderRenderPass;
218 
219  // Override shader is used when scene materials are disabled
220  HdStShaderCodeSharedPtr _overrideShader;
221 
222  // Having separate render pass states allows us to use different
223  // shader mixins if we choose to (we don't currently).
224  HdRenderPassStateSharedPtr _pickableRenderPassState;
225  HdRenderPassStateSharedPtr _occluderRenderPassState;
226 
227  // A single draw target is shared for all contexts. Since the FBO cannot
228  // be shared, we clone the attachments on each request.
229  GlfDrawTargetRefPtr _drawTarget;
230 
231  HdxPickTask() = delete;
232  HdxPickTask(const HdxPickTask &) = delete;
233  HdxPickTask &operator =(const HdxPickTask &) = delete;
234 };
235 
236 /// A utility class for resolving ID buffers into hits.
238 public:
239 
240  // Pick result takes a tuple of ID buffers:
241  // - (primId, instanceId, elementId, edgeId, pointId)
242  // along with some geometric buffers:
243  // - (depth, Neye)
244  // ... and resolves them into a series of hits, using one of the
245  // algorithms specified below.
246  //
247  // index is used to fill in the HdxPickHit structure;
248  // pickTarget is used to determine what a valid hit is;
249  // viewMatrix, projectionMatrix, depthRange are used for unprojection
250  // to calculate the worldSpaceHitPosition and worldSpaceHitNormal.
251  // bufferSize is the size of the ID buffers, and subRect is the sub-region
252  // of the id buffers to iterate over in the resolution algorithm.
253  //
254  // All buffers need to be the same size, if passed in. It's legal for
255  // only the depth and primId buffers to be provided; everything else is
256  // optional but provides a richer picking result.
257  HDX_API
258  HdxPickResult(int const* primIds,
259  int const* instanceIds,
260  int const* elementIds,
261  int const* edgeIds,
262  int const* pointIds,
263  int const* neyes,
264  float const* depths,
265  HdRenderIndex const *index,
266  TfToken const& pickTarget,
267  GfMatrix4d const& viewMatrix,
268  GfMatrix4d const& projectionMatrix,
269  GfVec2f const& depthRange,
270  GfVec2i const& bufferSize,
271  GfVec4i const& subRect);
272 
273  HDX_API
274  ~HdxPickResult();
275 
276  HDX_API
277  HdxPickResult(HdxPickResult &&);
278  HDX_API
279  HdxPickResult& operator=(HdxPickResult &&);
280 
281  /// Return whether the result was given well-formed parameters.
282  HDX_API
283  bool IsValid() const;
284 
285  /// Return the nearest single hit point. Note that this method may be
286  /// considerably more efficient, as it only needs to construct a single
287  /// Hit object.
288  HDX_API
289  void ResolveNearestToCamera(HdxPickHitVector* allHits) const;
290 
291  /// Return the nearest single hit point from the center of the viewport.
292  /// Note that this method may be considerably more efficient, as it only
293  /// needs to construct a single Hit object.
294  HDX_API
295  void ResolveNearestToCenter(HdxPickHitVector* allHits) const;
296 
297  /// Return all hit points. Note that this may contain redundant objects,
298  /// however it allows access to all depth values for a given object.
299  HDX_API
300  void ResolveAll(HdxPickHitVector* allHits) const;
301 
302  /// Return the set of unique hit points, keeping only the nearest depth
303  /// value.
304  HDX_API
305  void ResolveUnique(HdxPickHitVector* allHits) const;
306 
307 private:
308  bool _ResolveHit(int index, int x, int y, float z, HdxPickHit* hit) const;
309  size_t _GetHash(int index) const;
310  bool _IsValidHit(int index) const;
311 
312  // Provide accessors for all of the ID buffers. Since all but _primIds
313  // are optional, if the buffer doesn't exist just return -1 (== no hit).
314  int _GetPrimId(int index) const {
315  return _primIds ? _primIds[index] : -1;
316  }
317  int _GetInstanceId(int index) const {
318  return _instanceIds ? _instanceIds[index] : -1;
319  }
320  int _GetElementId(int index) const {
321  return _elementIds ? _elementIds[index] : -1;
322  }
323  int _GetEdgeId(int index) const {
324  return _edgeIds ? _edgeIds[index] : -1;
325  }
326  int _GetPointId(int index) const {
327  return _pointIds ? _pointIds[index] : -1;
328  }
329 
330  // Provide an accessor for the normal buffer. If the normal buffer is
331  // provided, this function will unpack the normal. The fallback is
332  // GfVec3f(0.0f).
333  GfVec3f _GetNormal(int index) const;
334 
335  int const* _primIds;
336  int const* _instanceIds;
337  int const* _elementIds;
338  int const* _edgeIds;
339  int const* _pointIds;
340  int const* _neyes;
341  float const* _depths;
342  HdRenderIndex const *_index;
343  TfToken _pickTarget;
344  GfMatrix4d _ndcToWorld;
345  GfMatrix4d _eyeToWorld;
346  GfVec2f _depthRange;
347  GfVec2i _bufferSize;
348  GfVec4i _subRect;
349 };
350 
351 // For sorting, order hits by ndc depth.
352 HDX_API
353 bool operator<(HdxPickHit const& lhs, HdxPickHit const& rhs);
354 
355 // VtValue requirements
356 HDX_API
357 std::ostream& operator<<(std::ostream& out, const HdxPickHit& h);
358 HDX_API
359 bool operator==(const HdxPickHit& lhs,
360  const HdxPickHit& rhs);
361 HDX_API
362 bool operator!=(const HdxPickHit& lhs,
363  const HdxPickHit& rhs);
364 
365 HDX_API
366 std::ostream& operator<<(std::ostream& out, const HdxPickTaskParams& pv);
367 HDX_API
368 bool operator==(const HdxPickTaskParams& lhs,
369  const HdxPickTaskParams& rhs);
370 HDX_API
371 bool operator!=(const HdxPickTaskParams& lhs,
372  const HdxPickTaskParams& rhs);
373 
374 HDX_API
375 std::ostream& operator<<(std::ostream& out, const HdxPickTaskContextParams& pv);
376 HDX_API
377 bool operator==(const HdxPickTaskContextParams& lhs,
378  const HdxPickTaskContextParams& rhs);
379 HDX_API
380 bool operator!=(const HdxPickTaskContextParams& lhs,
381  const HdxPickTaskContextParams& rhs);
383 
384 #endif // PXR_IMAGING_HDX_PICK_TASK_H
bool enableSceneMaterials
Definition: pickTask.h:87
Definition: vec4i.h:61
HdCullStyle cullStyle
Definition: pickTask.h:86
std::shared_ptr< class HdRenderPassState > HdRenderPassStateSharedPtr
Definition: engine.h:42
GfVec3f worldSpaceHitNormal
Definition: pickTask.h:101
HdCullStyle
Definition: enums.h:122
HDX_API size_t GetHash() const
Definition: vec2i.h:61
std::shared_ptr< class HdRenderPass > HdRenderPassSharedPtr
Definition: engine.h:41
int edgeIndex
Definition: pickTask.h:98
GLuint index
Definition: glew.h:1814
SdfPath delegateId
Definition: pickTask.h:93
uint32_t HdDirtyBits
Definition: types.h:127
SdfPath objectId
Definition: pickTask.h:94
int pointIndex
Definition: pickTask.h:99
GfVec3f worldSpaceHitPoint
Definition: pickTask.h:100
Definition: vec3f.h:63
HDX_API void ResolveUnique(HdxPickHitVector *allHits) const
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Definition: path.h:413
virtual HDX_API const TfTokenVector & GetRenderTags() const override
#define HDX_API
Definition: api.h:40
SdfPath instancerId
Definition: pickTask.h:95
HdxPickHitVector * outHits
Definition: pickTask.h:147
virtual HDX_API void Prepare(HdTaskContext *ctx, HdRenderIndex *renderIndex) override
Prepare the pick task.
#define HDX_PICK_TOKENS
Definition: pickTask.h:51
TF_DECLARE_PUBLIC_TOKENS(HdxPickTokens, HDX_API, HDX_PICK_TOKENS)
GLdouble GLdouble z
Definition: glew.h:1559
DepthMaskCallback depthMaskCallback
Definition: pickTask.h:145
HDX_API void ResolveNearestToCenter(HdxPickHitVector *allHits) const
virtual HDX_API void Sync(HdSceneDelegate *delegate, HdTaskContext *ctx, HdDirtyBits *dirtyBits) override
Sync the render pass resources.
Definition: token.h:87
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
virtual HDX_API void Execute(HdTaskContext *ctx) override
Execute the pick task.
virtual HDX_API ~HdxPickTask()
float normalizedDepth
Definition: pickTask.h:103
bool operator!=(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Inequality operator, does exact floating point comparisons.
Definition: Mat3.h:563
HDX_API ~HdxPickResult()
HDX_API HdxPickResult & operator=(HdxPickResult &&)
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:446
int instanceIndex
Definition: pickTask.h:96
HDX_API void ResolveAll(HdxPickHitVector *allHits) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:8011
A utility class for resolving ID buffers into hits.
Definition: pickTask.h:237
Definition: task.h:54
Definition: path.h:288
HDX_API std::ostream & operator<<(std::ostream &out, const HdxPickHit &h)
std::unordered_map< TfToken, VtValue, TfToken::HashFunctor > HdTaskContext
Definition: renderIndex.h:73
GfMatrix4d projectionMatrix
Definition: pickTask.h:143
HDX_API bool IsValid() const
Return whether the result was given well-formed parameters.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
HDX_API HdxPickResult(int const *primIds, int const *instanceIds, int const *elementIds, int const *edgeIds, int const *pointIds, int const *neyes, float const *depths, HdRenderIndex const *index, TfToken const &pickTarget, GfMatrix4d const &viewMatrix, GfMatrix4d const &projectionMatrix, GfVec2f const &depthRange, GfVec2i const &bufferSize, GfVec4i const &subRect)
Definition: vec2f.h:63
static int DecodeIDRenderColor(unsigned char const idColor[4])
Utility: Given a UNorm8Vec4 pixel, unpack it into an int32 ID.
Definition: pickTask.h:190
HDX_API bool operator<(HdxPickHit const &lhs, HdxPickHit const &rhs)
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
std::function< void(void)> DepthMaskCallback
Definition: pickTask.h:121
std::vector< GfVec4d > clipPlanes
Definition: pickTask.h:144
int elementIndex
Definition: pickTask.h:97
bool IsValid() const
Definition: pickTask.h:105
HdRprimCollection collection
Definition: pickTask.h:146
HDX_API void ResolveNearestToCamera(HdxPickHitVector *allHits) const
std::shared_ptr< class HdStShaderCode > HdStShaderCodeSharedPtr
Definition: drawItem.h:34
bool operator==(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat3.h:549
std::vector< HdxPickHit > HdxPickHitVector
Definition: pickTask.h:113