All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pickTask.h
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"
31 #include "pxr/imaging/hd/renderPass.h"
32 #include "pxr/imaging/hd/renderPassState.h"
33 #include "pxr/imaging/hd/rprimCollection.h"
34 #include "pxr/imaging/hd/task.h"
35 
36 #include "pxr/imaging/glf/drawTarget.h"
37 
38 #include "pxr/base/tf/declarePtrs.h"
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 
49 PXR_NAMESPACE_OPEN_SCOPE
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 
71 TF_DECLARE_PUBLIC_TOKENS(HdxPickTokens, HDX_API, HDX_PICK_TOKENS);
72 
74 class HdStShaderCode;
75 typedef boost::shared_ptr<HdStShaderCode> HdStShaderCodeSharedPtr;
76 
81 {
83  : cullStyle(HdCullStyleNothing)
84  , enableSceneMaterials(true)
85  {}
86 
87  HdCullStyle cullStyle;
88  bool enableSceneMaterials;
89 };
90 
93 struct HdxPickHit {
94  SdfPath delegateId;
95  SdfPath objectId;
96  SdfPath instancerId;
97  int instanceIndex;
98  int elementIndex;
99  int edgeIndex;
100  int pointIndex;
101  GfVec3f worldSpaceHitPoint;
102  GfVec3f worldSpaceHitNormal;
103  // normalizedDepth is in the range [0,1].
104  float normalizedDepth;
105 
106  inline bool IsValid() const {
107  return !objectId.IsEmpty();
108  }
109 
110  HDX_API
111  size_t GetHash() const;
112 };
113 
114 typedef std::vector<HdxPickHit> HdxPickHitVector;
115 
121 {
122  typedef std::function<void(void)> DepthMaskCallback;
123 
125  : resolution(128, 128)
126  , hitMode(HdxPickTokens->hitFirst)
127  , pickTarget(HdxPickTokens->pickPrimsAndInstances)
128  , resolveMode(HdxPickTokens->resolveNearestToCamera)
129  , doUnpickablesOcclude(false)
130  , viewMatrix(1)
131  , projectionMatrix(1)
132  , clipPlanes()
133  , depthMaskCallback(nullptr)
134  , collection()
135  , outHits(nullptr)
136  {}
137 
138  GfVec2i resolution;
139  TfToken hitMode;
140  TfToken pickTarget;
141  TfToken resolveMode;
142  bool doUnpickablesOcclude;
143  GfMatrix4d viewMatrix;
144  GfMatrix4d projectionMatrix;
145  std::vector<GfVec4d> clipPlanes;
146  DepthMaskCallback depthMaskCallback;
147  HdRprimCollection collection;
148  HdxPickHitVector *outHits;
149 };
150 
163 class HdxPickTask : public HdTask
164 {
165 public:
166  HDX_API
167  HdxPickTask(HdSceneDelegate* delegate, SdfPath const& id);
168 
169  HDX_API
170  virtual ~HdxPickTask();
171 
173  HDX_API
174  virtual void Sync(HdSceneDelegate* delegate,
175  HdTaskContext* ctx,
176  HdDirtyBits* dirtyBits) override;
177 
179  HDX_API
180  virtual void Prepare(HdTaskContext* ctx,
181  HdRenderIndex* renderIndex) override;
182 
184  HDX_API
185  virtual void Execute(HdTaskContext* ctx) override;
186 
187  HDX_API
188  virtual const TfTokenVector &GetRenderTags() const override;
189 
191  static inline int DecodeIDRenderColor(unsigned char const idColor[4]) {
192  return (int32_t(idColor[0] & 0xff) << 0) |
193  (int32_t(idColor[1] & 0xff) << 8) |
194  (int32_t(idColor[2] & 0xff) << 16) |
195  (int32_t(idColor[3] & 0xff) << 24);
196  }
197 
198 private:
199  HdxPickTaskParams _params;
200  HdxPickTaskContextParams _contextParams;
201  TfTokenVector _renderTags;
202 
203  // We need to cache a pointer to the render index so Execute() can
204  // map prim ID to paths.
205  HdRenderIndex *_index;
206 
207  void _Init(GfVec2i const& widthHeight);
208  void _SetResolution(GfVec2i const& widthHeight);
209  void _ConditionStencilWithGLCallback(
210  HdxPickTaskContextParams::DepthMaskCallback maskCallback);
211  void _ConfigureSceneMaterials(
212  bool enableSceneMaterials, HdStRenderPassState *renderPassState);
213 
214  bool _UseOcclusionPass() const;
215 
216  // Create a shared render pass each for pickables and unpickables
217  HdRenderPassSharedPtr _pickableRenderPass;
218  HdRenderPassSharedPtr _occluderRenderPass;
219 
220  // Override shader is used when scene materials are disabled
221  HdStShaderCodeSharedPtr _overrideShader;
222 
223  // Having separate render pass states allows us to use different
224  // shader mixins if we choose to (we don't currently).
225  HdRenderPassStateSharedPtr _pickableRenderPassState;
226  HdRenderPassStateSharedPtr _occluderRenderPassState;
227 
228  // A single draw target is shared for all contexts. Since the FBO cannot
229  // be shared, we clone the attachments on each request.
230  GlfDrawTargetRefPtr _drawTarget;
231 
232  HdxPickTask() = delete;
233  HdxPickTask(const HdxPickTask &) = delete;
234  HdxPickTask &operator =(const HdxPickTask &) = delete;
235 };
236 
239 public:
240 
241  // Pick result takes a tuple of ID buffers:
242  // - (primId, instanceId, elementId, edgeId, pointId)
243  // along with some geometric buffers:
244  // - (depth, Neye)
245  // ... and resolves them into a series of hits, using one of the
246  // algorithms specified below.
247  //
248  // index is used to fill in the HdxPickHit structure;
249  // pickTarget is used to determine what a valid hit is;
250  // viewMatrix, projectionMatrix, depthRange are used for unprojection
251  // to calculate the worldSpaceHitPosition and worldSpaceHitNormal.
252  // bufferSize is the size of the ID buffers, and subRect is the sub-region
253  // of the id buffers to iterate over in the resolution algorithm.
254  //
255  // All buffers need to be the same size, if passed in. It's legal for
256  // only the depth and primId buffers to be provided; everything else is
257  // optional but provides a richer picking result.
258  HDX_API
259  HdxPickResult(int const* primIds,
260  int const* instanceIds,
261  int const* elementIds,
262  int const* edgeIds,
263  int const* pointIds,
264  int const* neyes,
265  float const* depths,
266  HdRenderIndex const *index,
267  TfToken const& pickTarget,
268  GfMatrix4d const& viewMatrix,
269  GfMatrix4d const& projectionMatrix,
270  GfVec2f const& depthRange,
271  GfVec2i const& bufferSize,
272  GfVec4i const& subRect);
273 
274  HDX_API
275  ~HdxPickResult();
276 
277  HDX_API
278  HdxPickResult(HdxPickResult &&);
279  HDX_API
280  HdxPickResult& operator=(HdxPickResult &&);
281 
283  HDX_API
284  bool IsValid() const;
285 
289  HDX_API
290  void ResolveNearestToCamera(HdxPickHitVector* allHits) const;
291 
295  HDX_API
296  void ResolveNearestToCenter(HdxPickHitVector* allHits) const;
297 
300  HDX_API
301  void ResolveAll(HdxPickHitVector* allHits) const;
302 
305  HDX_API
306  void ResolveUnique(HdxPickHitVector* allHits) const;
307 
308 private:
309  bool _ResolveHit(int index, int x, int y, float z, HdxPickHit* hit) const;
310  size_t _GetHash(int index) const;
311  bool _IsValidHit(int index) const;
312 
313  // Provide accessors for all of the ID buffers. Since all but _primIds
314  // are optional, if the buffer doesn't exist just return -1 (== no hit).
315  int _GetPrimId(int index) const {
316  return _primIds ? _primIds[index] : -1;
317  }
318  int _GetInstanceId(int index) const {
319  return _instanceIds ? _instanceIds[index] : -1;
320  }
321  int _GetElementId(int index) const {
322  return _elementIds ? _elementIds[index] : -1;
323  }
324  int _GetEdgeId(int index) const {
325  return _edgeIds ? _edgeIds[index] : -1;
326  }
327  int _GetPointId(int index) const {
328  return _pointIds ? _pointIds[index] : -1;
329  }
330 
331  // Provide an accessor for the normal buffer. If the normal buffer is
332  // provided, this function will unpack the normal. The fallback is
333  // GfVec3f(0.0f).
334  GfVec3f _GetNormal(int index) const;
335 
336  int const* _primIds;
337  int const* _instanceIds;
338  int const* _elementIds;
339  int const* _edgeIds;
340  int const* _pointIds;
341  int const* _neyes;
342  float const* _depths;
343  HdRenderIndex const *_index;
344  TfToken _pickTarget;
345  GfMatrix4d _ndcToWorld;
346  GfMatrix4d _eyeToWorld;
347  GfVec2f _depthRange;
348  GfVec2i _bufferSize;
349  GfVec4i _subRect;
350 };
351 
352 // For sorting, order hits by ndc depth.
353 HDX_API
354 bool operator<(HdxPickHit const& lhs, HdxPickHit const& rhs);
355 
356 // VtValue requirements
357 HDX_API
358 std::ostream& operator<<(std::ostream& out, const HdxPickHit& h);
359 HDX_API
360 bool operator==(const HdxPickHit& lhs,
361  const HdxPickHit& rhs);
362 HDX_API
363 bool operator!=(const HdxPickHit& lhs,
364  const HdxPickHit& rhs);
365 
366 HDX_API
367 std::ostream& operator<<(std::ostream& out, const HdxPickTaskParams& pv);
368 HDX_API
369 bool operator==(const HdxPickTaskParams& lhs,
370  const HdxPickTaskParams& rhs);
371 HDX_API
372 bool operator!=(const HdxPickTaskParams& lhs,
373  const HdxPickTaskParams& rhs);
374 
375 HDX_API
376 std::ostream& operator<<(std::ostream& out, const HdxPickTaskContextParams& pv);
377 HDX_API
378 bool operator==(const HdxPickTaskContextParams& lhs,
379  const HdxPickTaskContextParams& rhs);
380 HDX_API
381 bool operator!=(const HdxPickTaskContextParams& lhs,
382  const HdxPickTaskContextParams& rhs);
383 PXR_NAMESPACE_CLOSE_SCOPE
384 
385 #endif // PXR_IMAGING_HDX_PICK_TASK_H
Basic type for a vector of 4 int components.
Definition: vec4i.h:61
The Hydra render index is a flattened representation of the client scene graph, which may be composed...
Definition: renderIndex.h:121
HDX_API void ResolveAll(HdxPickHitVector *allHits) const
Return all hit points.
Pick task params.
Definition: pickTask.h:80
Basic type for a vector of 2 int components.
Definition: vec2i.h:61
Pick task context params.
Definition: pickTask.h:120
virtual HDX_API void Sync(HdSceneDelegate *delegate, HdTaskContext *ctx, HdDirtyBits *dirtyBits) override
Sync the render pass resources.
HDX_API void ResolveUnique(HdxPickHitVector *allHits) const
Return the set of unique hit points, keeping only the nearest depth value.
Basic type for a vector of 3 float components.
Definition: vec3f.h:63
AR_API bool operator!=(const ArAssetInfo &lhs, const ArAssetInfo &rhs)
A set of rendering parameters used among render passes.
AR_API bool operator==(const ArAssetInfo &lhs, const ArAssetInfo &rhs)
Picking hit structure.
Definition: pickTask.h:93
HDX_API void ResolveNearestToCenter(HdxPickHitVector *allHits) const
Return the nearest single hit point from the center of the viewport.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
HDX_API void ResolveNearestToCamera(HdxPickHitVector *allHits) const
Return the nearest single hit point.
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:88
Adapter class providing data exchange with the client scene graph.
#define TF_DECLARE_PUBLIC_TOKENS(...)
Macro to define public tokens.
Definition: staticTokens.h:118
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:431
A named, semantic collection of objects.
A utility class for resolving ID buffers into hits.
Definition: pickTask.h:238
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:288
HDX_API bool IsValid() const
Return whether the result was given well-formed parameters.
virtual HDX_API void Execute(HdTaskContext *ctx) override
Execute the pick task.
A base class representing the implementation (code) of a shader, used in conjunction with HdRenderPas...
Definition: shaderCode.h:62
static int DecodeIDRenderColor(unsigned char const idColor[4])
Utility: Given a UNorm8Vec4 pixel, unpack it into an int32 ID.
Definition: pickTask.h:191
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
Basic type for a vector of 2 float components.
Definition: vec2f.h:63
A task for running picking queries against the current scene.
Definition: pickTask.h:163
virtual HDX_API void Prepare(HdTaskContext *ctx, HdRenderIndex *renderIndex) override
Prepare the pick task.
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Definition: path.h:413