Loading...
Searching...
No Matches
pickTask.h
1//
2// Copyright 2019 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_IMAGING_HDX_PICK_TASK_H
8#define PXR_IMAGING_HDX_PICK_TASK_H
9
10#include "pxr/pxr.h"
11#include "pxr/imaging/hdx/api.h"
12
13#include "pxr/imaging/hdSt/textureUtils.h"
14#include "pxr/imaging/hd/dataSource.h"
15#include "pxr/imaging/hd/enums.h"
17#include "pxr/imaging/hd/renderPass.h"
18#include "pxr/imaging/hd/renderPassState.h"
19#include "pxr/imaging/hd/rprimCollection.h"
20#include "pxr/imaging/hd/task.h"
21
22#include "pxr/base/arch/align.h"
25#include "pxr/base/gf/vec2i.h"
26#include "pxr/base/gf/vec2f.h"
27#include "pxr/base/gf/vec4i.h"
28#include "pxr/base/gf/vec4d.h"
29#include "pxr/usd/sdf/path.h"
30
31#include <vector>
32#include <memory>
33
34PXR_NAMESPACE_OPEN_SCOPE
35
36#define HDX_PICK_TOKENS \
37 /* Task context */ \
38 (pickParams) \
39 \
40 /* Pick target */ \
41 (pickPrimsAndInstances) \
42 (pickFaces) \
43 (pickEdges) \
44 (pickPoints) \
45 (pickPointsAndInstances) \
46 \
47 /* Resolve mode */ \
48 (resolveNearestToCamera) \
49 (resolveNearestToCenter) \
50 (resolveUnique) \
51 (resolveAll) \
52 (resolveDeep)
53
54TF_DECLARE_PUBLIC_TOKENS(HdxPickTokens, HDX_API, HDX_PICK_TOKENS);
55
56class HdStRenderBuffer;
58using HdStShaderCodeSharedPtr = std::shared_ptr<class HdStShaderCode>;
59
60class Hgi;
61
66{
68 : cullStyle(HdCullStyleNothing)
69 , enableSceneMaterials(true)
70 {}
71
72 HdCullStyle cullStyle;
73 bool enableSceneMaterials;
74};
75
79{
90 int instanceIndex;
91 int elementIndex;
92 int edgeIndex;
93 int pointIndex;
94 GfVec3d worldSpaceHitPoint;
95 GfVec3f worldSpaceHitNormal;
99
100 inline bool IsValid() const {
101 return !objectId.IsEmpty();
102 }
103
104 HDX_API
105 size_t GetHash() const;
106};
107
108using HdxPickHitVector = std::vector<HdxPickHit>;
109
113{
117 HdContainerDataSourceHandle instancerPrimOrigin;
118
122
140 HdContainerDataSourceHandle instancePrimOrigin;
143};
144
163{
166 HDX_API
167 static HdxPrimOriginInfo
169 const HdxPickHit &hit);
170
175 HDX_API
176 static std::vector<HdxPrimOriginInfo>
178 const std::vector<HdxPickHit> &hits);
179
186 HDX_API
188 const TfToken &nameInPrimOrigin =
189 HdPrimOriginSchemaTokens->scenePath) const;
190
197 HDX_API
198 HdInstancerContext ComputeInstancerContext(
199 const TfToken &nameInPrimOrigin =
200 HdPrimOriginSchemaTokens->scenePath) const;
201
204 std::vector<HdxInstancerContext> instancerContexts;
207 HdContainerDataSourceHandle primOrigin;
208};
209
243{
244 using DepthMaskCallback = std::function<void(void)>;
245
247 : resolution(128, 128)
248 , maxNumDeepEntries(32000)
249 , pickTarget(HdxPickTokens->pickPrimsAndInstances)
250 , resolveMode(HdxPickTokens->resolveNearestToCamera)
251 , doUnpickablesOcclude(false)
252 , viewMatrix(1)
253 , projectionMatrix(1)
254 , clipPlanes()
255 , depthMaskCallback(nullptr)
256 , collection()
257 , alphaThreshold(0.0001f)
258 , outHits(nullptr)
259 {}
260
261 GfVec2i resolution;
262 int maxNumDeepEntries;
263 TfToken pickTarget;
264 TfToken resolveMode;
265 bool doUnpickablesOcclude;
266 GfMatrix4d viewMatrix;
267 GfMatrix4d projectionMatrix;
268 std::vector<GfVec4d> clipPlanes;
269 DepthMaskCallback depthMaskCallback;
270 HdRprimCollection collection;
271 float alphaThreshold;
272 HdxPickHitVector *outHits;
273};
274
287class HdxPickTask : public HdTask
288{
289public:
291
292 HDX_API
293 HdxPickTask(HdSceneDelegate* delegate, SdfPath const& id);
294
295 HDX_API
296 ~HdxPickTask() override;
297
299 HDX_API
300 void Sync(HdSceneDelegate* delegate,
301 HdTaskContext* ctx,
302 HdDirtyBits* dirtyBits) override;
303
305 HDX_API
306 void Prepare(HdTaskContext* ctx,
307 HdRenderIndex* renderIndex) override;
308
310 HDX_API
311 void Execute(HdTaskContext* ctx) override;
312
313 HDX_API
314 const TfTokenVector &GetRenderTags() const override;
315
317 static inline int DecodeIDRenderColor(unsigned char const idColor[4]) {
318 return (int32_t(idColor[0] & 0xff) << 0) |
319 (int32_t(idColor[1] & 0xff) << 8) |
320 (int32_t(idColor[2] & 0xff) << 16) |
321 (int32_t(idColor[3] & 0xff) << 24);
322 }
323
324private:
325 HdxPickTaskParams _params;
326 HdxPickTaskContextParams _contextParams;
327 TfTokenVector _renderTags;
328 bool _useOverlayPass;
329
330 // We need to cache a pointer to the render index so Execute() can
331 // map prim ID to paths.
332 HdRenderIndex *_index;
333
334 void _InitIfNeeded();
335 void _CreateAovBindings();
336 void _CleanupAovBindings();
337 void _ResizeOrCreateBufferForAOV(
338 const HdRenderPassAovBinding& aovBinding);
339
340 void _ConditionStencilWithGLCallback(
341 HdxPickTaskContextParams::DepthMaskCallback maskCallback,
342 HdRenderBuffer const * depthStencilBuffer);
343
344 bool _UseOcclusionPass() const;
345 bool _UseOverlayPass() const;
346 void _UpdateUseOverlayPass();
347
348 void _ClearPickBuffer();
349 void _ResolveDeep();
350
351 template<typename T>
352 HdStTextureUtils::AlignedBuffer<T>
353 _ReadAovBuffer(TfToken const & aovName) const;
354
355 HdRenderBuffer const * _FindAovBuffer(TfToken const & aovName) const;
356
357 // Create a shared render pass each for pickables, unpickables, and
358 // items in overlay (which may draw on top even when occluded).
359 HdRenderPassSharedPtr _pickableRenderPass;
360 HdRenderPassSharedPtr _occluderRenderPass;
361 HdRenderPassSharedPtr _overlayRenderPass;
362
363 // Having separate render pass states allows us to use different
364 // shader mixins if we choose to (we don't currently).
365 HdRenderPassStateSharedPtr _pickableRenderPassState;
366 HdRenderPassStateSharedPtr _occluderRenderPassState;
367 HdRenderPassStateSharedPtr _overlayRenderPassState;
368
369 Hgi* _hgi;
370
371 std::vector<std::unique_ptr<HdStRenderBuffer>> _pickableAovBuffers;
372 HdRenderPassAovBindingVector _pickableAovBindings;
373 HdRenderPassAovBinding _occluderAovBinding;
374 size_t _pickableDepthIndex;
375 TfToken _depthToken;
376 std::unique_ptr<HdStRenderBuffer> _overlayDepthStencilBuffer;
377 HdRenderPassAovBindingVector _overlayAovBindings;
378
379 // pick buffer used for deep selection
380 HdBufferArrayRangeSharedPtr _pickBuffer;
381
382 HdxPickTask() = delete;
383 HdxPickTask(const HdxPickTask &) = delete;
384 HdxPickTask &operator =(const HdxPickTask &) = delete;
385};
386
389public:
390
391 // Pick result takes a tuple of ID buffers:
392 // - (primId, instanceId, elementId, edgeId, pointId)
393 // along with some geometric buffers:
394 // - (depth, Neye)
395 // ... and resolves them into a series of hits, using one of the
396 // algorithms specified below.
397 //
398 // index is used to fill in the HdxPickHit structure;
399 // pickTarget is used to determine what a valid hit is;
400 // viewMatrix, projectionMatrix, depthRange are used for unprojection
401 // to calculate the worldSpaceHitPosition and worldSpaceHitNormal.
402 // bufferSize is the size of the ID buffers, and subRect is the sub-region
403 // of the id buffers to iterate over in the resolution algorithm.
404 //
405 // All buffers need to be the same size, if passed in. It's legal for
406 // only the depth and primId buffers to be provided; everything else is
407 // optional but provides a richer picking result.
408 HDX_API
409 HdxPickResult(int const* primIds,
410 int const* instanceIds,
411 int const* elementIds,
412 int const* edgeIds,
413 int const* pointIds,
414 int const* neyes,
415 float const* depths,
416 HdRenderIndex const *index,
417 TfToken const& pickTarget,
418 GfMatrix4d const& viewMatrix,
419 GfMatrix4d const& projectionMatrix,
420 GfVec2f const& depthRange,
421 GfVec2i const& bufferSize,
422 GfVec4i const& subRect);
423
424 HDX_API
426
427 HDX_API
429 HDX_API
430 HdxPickResult& operator=(HdxPickResult &&);
431
433 HDX_API
434 bool IsValid() const;
435
439 HDX_API
440 void ResolveNearestToCamera(HdxPickHitVector* allHits) const;
441
445 HDX_API
446 void ResolveNearestToCenter(HdxPickHitVector* allHits) const;
447
450 HDX_API
451 void ResolveAll(HdxPickHitVector* allHits) const;
452
455 HDX_API
456 void ResolveUnique(HdxPickHitVector* allHits) const;
457
458private:
459 bool _ResolveHit(int index, int x, int y, float z, HdxPickHit* hit) const;
460
461 size_t _GetHash(int index) const;
462 bool _IsValidHit(int index) const;
463
464 // Provide accessors for all of the ID buffers. Since all but _primIds
465 // are optional, if the buffer doesn't exist just return -1 (== no hit).
466 int _GetPrimId(int index) const {
467 return _primIds ? _primIds[index] : -1;
468 }
469 int _GetInstanceId(int index) const {
470 return _instanceIds ? _instanceIds[index] : -1;
471 }
472 int _GetElementId(int index) const {
473 return _elementIds ? _elementIds[index] : -1;
474 }
475 int _GetEdgeId(int index) const {
476 return _edgeIds ? _edgeIds[index] : -1;
477 }
478 int _GetPointId(int index) const {
479 return _pointIds ? _pointIds[index] : -1;
480 }
481
482 // Provide an accessor for the normal buffer. If the normal buffer is
483 // provided, this function will unpack the normal. The fallback is
484 // GfVec3f(0.0f).
485 GfVec3f _GetNormal(int index) const;
486
487 int const* _primIds;
488 int const* _instanceIds;
489 int const* _elementIds;
490 int const* _edgeIds;
491 int const* _pointIds;
492 int const* _neyes;
493 float const* _depths;
494 HdRenderIndex const *_index;
495 TfToken _pickTarget;
496 GfMatrix4d _ndcToWorld;
497 GfMatrix4d _eyeToWorld;
498 GfVec2f _depthRange;
499 GfVec2i _bufferSize;
500 GfVec4i _subRect;
501};
502
503// For sorting, order hits by ndc depth.
504HDX_API
505bool operator<(HdxPickHit const& lhs, HdxPickHit const& rhs);
506
507// VtValue requirements
508HDX_API
509std::ostream& operator<<(std::ostream& out, const HdxPickHit& h);
510HDX_API
511bool operator==(const HdxPickHit& lhs,
512 const HdxPickHit& rhs);
513HDX_API
514bool operator!=(const HdxPickHit& lhs,
515 const HdxPickHit& rhs);
516
517HDX_API
518std::ostream& operator<<(std::ostream& out, const HdxPickTaskParams& pv);
519HDX_API
520bool operator==(const HdxPickTaskParams& lhs,
521 const HdxPickTaskParams& rhs);
522HDX_API
523bool operator!=(const HdxPickTaskParams& lhs,
524 const HdxPickTaskParams& rhs);
525
526HDX_API
527std::ostream& operator<<(std::ostream& out, const HdxPickTaskContextParams& pv);
528HDX_API
529bool operator==(const HdxPickTaskContextParams& lhs,
530 const HdxPickTaskContextParams& rhs);
531HDX_API
532bool operator!=(const HdxPickTaskContextParams& lhs,
533 const HdxPickTaskContextParams& rhs);
534PXR_NAMESPACE_CLOSE_SCOPE
535
536#endif // PXR_IMAGING_HDX_PICK_TASK_H
Provide architecture-specific memory-alignment information.
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:71
Basic type for a vector of 2 float components.
Definition: vec2f.h:46
Basic type for a vector of 2 int components.
Definition: vec2i.h:44
Basic type for a vector of 3 double components.
Definition: vec3d.h:46
Basic type for a vector of 3 float components.
Definition: vec3f.h:46
Basic type for a vector of 4 int components.
Definition: vec4i.h:44
A render buffer is a handle to a data resource that can be rendered into, such as a 2d image for a dr...
Definition: renderBuffer.h:33
The Hydra render index is a flattened representation of the client scene graph, which may be composed...
Definition: renderIndex.h:105
A named, semantic collection of objects.
Adapter class providing data exchange with the client scene graph.
A set of rendering parameters used among render passes.
HdTask represents a unit of work to perform during a Hydra render.
Definition: task.h:43
A utility class for resolving ID buffers into hits.
Definition: pickTask.h:388
HDX_API void ResolveUnique(HdxPickHitVector *allHits) const
Return the set of unique hit points, keeping only the nearest depth value.
HDX_API void ResolveNearestToCenter(HdxPickHitVector *allHits) const
Return the nearest single hit point from the center of the viewport.
HDX_API bool IsValid() const
Return whether the result was given well-formed parameters.
HDX_API void ResolveAll(HdxPickHitVector *allHits) const
Return all hit points.
HDX_API void ResolveNearestToCamera(HdxPickHitVector *allHits) const
Return the nearest single hit point.
A task for running picking queries against the current scene.
Definition: pickTask.h:288
static int DecodeIDRenderColor(unsigned char const idColor[4])
Utility: Given a UNorm8Vec4 pixel, unpack it into an int32 ID.
Definition: pickTask.h:317
HDX_API const TfTokenVector & GetRenderTags() const override
Render Tag Gather.
HDX_API void Sync(HdSceneDelegate *delegate, HdTaskContext *ctx, HdDirtyBits *dirtyBits) override
Sync the render pass resources.
HDX_API void Prepare(HdTaskContext *ctx, HdRenderIndex *renderIndex) override
Prepare the pick task.
HDX_API void Execute(HdTaskContext *ctx) override
Execute the pick task.
Hydra Graphics Interface.
Definition: hgi.h:94
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:274
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Definition: path.h:398
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
Standard pointer typedefs.
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
#define TF_DECLARE_PUBLIC_TOKENS(...)
Macro to define public tokens.
Definition: staticTokens.h:81
A renderpass AOV represents a binding of some output of the rendering process to an output buffer.
Definition: aov.h:100
Information about an instancer instancing a picked object (or an instancer instancing such an instanc...
Definition: pickTask.h:113
HdContainerDataSourceHandle instancerPrimOrigin
The prim origin data source of the instancer.
Definition: pickTask.h:117
HdContainerDataSourceHandle instancePrimOrigin
The prim origin data source of the picked (implicit) instance.
Definition: pickTask.h:140
int instanceId
Index of the picked instance.
Definition: pickTask.h:142
SdfPath instanceSceneIndexPath
For implicit instancing (native instancing in USD), the path of the picked instance in the scene inde...
Definition: pickTask.h:121
SdfPath instancerSceneIndexPath
The path of the instancer in the scene index.
Definition: pickTask.h:115
Picking hit structure.
Definition: pickTask.h:79
float normalizedDepth
normalizedDepth is in the range [0,1].
Definition: pickTask.h:98
SdfPath delegateId
delegateID of HdSceneDelegate that provided the picked prim.
Definition: pickTask.h:82
SdfPath objectId
Path computed from scenePath's in primOrigin data source of picked prim and instancers if provided by...
Definition: pickTask.h:86
SdfPath instancerId
Only supported for scene delegates, see HdxPrimOriginInfo for scene indices.
Definition: pickTask.h:89
Pick task context params.
Definition: pickTask.h:243
Pick task params.
Definition: pickTask.h:66
A helper to extract information about the picked prim that allows modern applications to identify a p...
Definition: pickTask.h:163
static HDX_API std::vector< HdxPrimOriginInfo > FromPickHits(HdRenderIndex *renderIndex, const std::vector< HdxPickHit > &hits)
Vectorized implementation of function to query terminal scene index of render index for information a...
HdContainerDataSourceHandle primOrigin
The prim origin data source for the picked prim if provided by the scene index.
Definition: pickTask.h:207
std::vector< HdxInstancerContext > instancerContexts
Information about the instancers instancing the picked object.
Definition: pickTask.h:204
static HDX_API HdxPrimOriginInfo FromPickHit(HdRenderIndex *renderIndex, const HdxPickHit &hit)
Query terminal scene index of render index for information about picked prim.
HDX_API HdInstancerContext ComputeInstancerContext(const TfToken &nameInPrimOrigin=HdPrimOriginSchemaTokens->scenePath) const
Computes an HdInstancerContext object (equivalent to the one computed by GetScenePrimPath) from the v...
HDX_API SdfPath GetFullPath(const TfToken &nameInPrimOrigin=HdPrimOriginSchemaTokens->scenePath) const
Combines instance scene paths and prim scene path to obtain the full scene path.
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440