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
177 HDX_API
179 const TfToken &nameInPrimOrigin =
180 HdPrimOriginSchemaTokens->scenePath) const;
181
188 HDX_API
189 HdInstancerContext ComputeInstancerContext(
190 const TfToken &nameInPrimOrigin =
191 HdPrimOriginSchemaTokens->scenePath) const;
192
195 std::vector<HdxInstancerContext> instancerContexts;
198 HdContainerDataSourceHandle primOrigin;
199};
200
234{
235 using DepthMaskCallback = std::function<void(void)>;
236
238 : resolution(128, 128)
239 , maxNumDeepEntries(32000)
240 , pickTarget(HdxPickTokens->pickPrimsAndInstances)
241 , resolveMode(HdxPickTokens->resolveNearestToCamera)
242 , doUnpickablesOcclude(false)
243 , viewMatrix(1)
244 , projectionMatrix(1)
245 , clipPlanes()
246 , depthMaskCallback(nullptr)
247 , collection()
248 , alphaThreshold(0.0001f)
249 , outHits(nullptr)
250 {}
251
252 GfVec2i resolution;
253 int maxNumDeepEntries;
254 TfToken pickTarget;
255 TfToken resolveMode;
256 bool doUnpickablesOcclude;
257 GfMatrix4d viewMatrix;
258 GfMatrix4d projectionMatrix;
259 std::vector<GfVec4d> clipPlanes;
260 DepthMaskCallback depthMaskCallback;
261 HdRprimCollection collection;
262 float alphaThreshold;
263 HdxPickHitVector *outHits;
264};
265
278class HdxPickTask : public HdTask
279{
280public:
281 HDX_API
282 HdxPickTask(HdSceneDelegate* delegate, SdfPath const& id);
283
284 HDX_API
285 ~HdxPickTask() override;
286
288 HDX_API
289 void Sync(HdSceneDelegate* delegate,
290 HdTaskContext* ctx,
291 HdDirtyBits* dirtyBits) override;
292
294 HDX_API
295 void Prepare(HdTaskContext* ctx,
296 HdRenderIndex* renderIndex) override;
297
299 HDX_API
300 void Execute(HdTaskContext* ctx) override;
301
302 HDX_API
303 const TfTokenVector &GetRenderTags() const override;
304
306 static inline int DecodeIDRenderColor(unsigned char const idColor[4]) {
307 return (int32_t(idColor[0] & 0xff) << 0) |
308 (int32_t(idColor[1] & 0xff) << 8) |
309 (int32_t(idColor[2] & 0xff) << 16) |
310 (int32_t(idColor[3] & 0xff) << 24);
311 }
312
313private:
314 HdxPickTaskParams _params;
315 HdxPickTaskContextParams _contextParams;
316 TfTokenVector _allRenderTags;
317 TfTokenVector _nonWidgetRenderTags;
318
319 // We need to cache a pointer to the render index so Execute() can
320 // map prim ID to paths.
321 HdRenderIndex *_index;
322
323 void _InitIfNeeded();
324 void _CreateAovBindings();
325 void _CleanupAovBindings();
326 void _ResizeOrCreateBufferForAOV(
327 const HdRenderPassAovBinding& aovBinding);
328
329 void _ConditionStencilWithGLCallback(
330 HdxPickTaskContextParams::DepthMaskCallback maskCallback,
331 HdRenderBuffer const * depthStencilBuffer);
332
333 bool _UseOcclusionPass() const;
334 bool _UseWidgetPass() const;
335
336 void _ClearPickBuffer();
337 void _ResolveDeep();
338
339 template<typename T>
340 HdStTextureUtils::AlignedBuffer<T>
341 _ReadAovBuffer(TfToken const & aovName) const;
342
343 HdRenderBuffer const * _FindAovBuffer(TfToken const & aovName) const;
344
345 // Create a shared render pass each for pickables, unpickables, and
346 // widgets (which may draw on top even when occluded).
347 HdRenderPassSharedPtr _pickableRenderPass;
348 HdRenderPassSharedPtr _occluderRenderPass;
349 HdRenderPassSharedPtr _widgetRenderPass;
350
351 // Having separate render pass states allows us to use different
352 // shader mixins if we choose to (we don't currently).
353 HdRenderPassStateSharedPtr _pickableRenderPassState;
354 HdRenderPassStateSharedPtr _occluderRenderPassState;
355 HdRenderPassStateSharedPtr _widgetRenderPassState;
356
357 Hgi* _hgi;
358
359 std::vector<std::unique_ptr<HdStRenderBuffer>> _pickableAovBuffers;
360 HdRenderPassAovBindingVector _pickableAovBindings;
361 HdRenderPassAovBinding _occluderAovBinding;
362 size_t _pickableDepthIndex;
363 TfToken _depthToken;
364 std::unique_ptr<HdStRenderBuffer> _widgetDepthStencilBuffer;
365 HdRenderPassAovBindingVector _widgetAovBindings;
366
367 // pick buffer used for deep selection
368 HdBufferArrayRangeSharedPtr _pickBuffer;
369
370 HdxPickTask() = delete;
371 HdxPickTask(const HdxPickTask &) = delete;
372 HdxPickTask &operator =(const HdxPickTask &) = delete;
373};
374
377public:
378
379 // Pick result takes a tuple of ID buffers:
380 // - (primId, instanceId, elementId, edgeId, pointId)
381 // along with some geometric buffers:
382 // - (depth, Neye)
383 // ... and resolves them into a series of hits, using one of the
384 // algorithms specified below.
385 //
386 // index is used to fill in the HdxPickHit structure;
387 // pickTarget is used to determine what a valid hit is;
388 // viewMatrix, projectionMatrix, depthRange are used for unprojection
389 // to calculate the worldSpaceHitPosition and worldSpaceHitNormal.
390 // bufferSize is the size of the ID buffers, and subRect is the sub-region
391 // of the id buffers to iterate over in the resolution algorithm.
392 //
393 // All buffers need to be the same size, if passed in. It's legal for
394 // only the depth and primId buffers to be provided; everything else is
395 // optional but provides a richer picking result.
396 HDX_API
397 HdxPickResult(int const* primIds,
398 int const* instanceIds,
399 int const* elementIds,
400 int const* edgeIds,
401 int const* pointIds,
402 int const* neyes,
403 float const* depths,
404 HdRenderIndex const *index,
405 TfToken const& pickTarget,
406 GfMatrix4d const& viewMatrix,
407 GfMatrix4d const& projectionMatrix,
408 GfVec2f const& depthRange,
409 GfVec2i const& bufferSize,
410 GfVec4i const& subRect);
411
412 HDX_API
414
415 HDX_API
417 HDX_API
418 HdxPickResult& operator=(HdxPickResult &&);
419
421 HDX_API
422 bool IsValid() const;
423
427 HDX_API
428 void ResolveNearestToCamera(HdxPickHitVector* allHits) const;
429
433 HDX_API
434 void ResolveNearestToCenter(HdxPickHitVector* allHits) const;
435
438 HDX_API
439 void ResolveAll(HdxPickHitVector* allHits) const;
440
443 HDX_API
444 void ResolveUnique(HdxPickHitVector* allHits) const;
445
446private:
447 bool _ResolveHit(int index, int x, int y, float z, HdxPickHit* hit) const;
448
449 size_t _GetHash(int index) const;
450 bool _IsValidHit(int index) const;
451
452 // Provide accessors for all of the ID buffers. Since all but _primIds
453 // are optional, if the buffer doesn't exist just return -1 (== no hit).
454 int _GetPrimId(int index) const {
455 return _primIds ? _primIds[index] : -1;
456 }
457 int _GetInstanceId(int index) const {
458 return _instanceIds ? _instanceIds[index] : -1;
459 }
460 int _GetElementId(int index) const {
461 return _elementIds ? _elementIds[index] : -1;
462 }
463 int _GetEdgeId(int index) const {
464 return _edgeIds ? _edgeIds[index] : -1;
465 }
466 int _GetPointId(int index) const {
467 return _pointIds ? _pointIds[index] : -1;
468 }
469
470 // Provide an accessor for the normal buffer. If the normal buffer is
471 // provided, this function will unpack the normal. The fallback is
472 // GfVec3f(0.0f).
473 GfVec3f _GetNormal(int index) const;
474
475 int const* _primIds;
476 int const* _instanceIds;
477 int const* _elementIds;
478 int const* _edgeIds;
479 int const* _pointIds;
480 int const* _neyes;
481 float const* _depths;
482 HdRenderIndex const *_index;
483 TfToken _pickTarget;
484 GfMatrix4d _ndcToWorld;
485 GfMatrix4d _eyeToWorld;
486 GfVec2f _depthRange;
487 GfVec2i _bufferSize;
488 GfVec4i _subRect;
489};
490
491// For sorting, order hits by ndc depth.
492HDX_API
493bool operator<(HdxPickHit const& lhs, HdxPickHit const& rhs);
494
495// VtValue requirements
496HDX_API
497std::ostream& operator<<(std::ostream& out, const HdxPickHit& h);
498HDX_API
499bool operator==(const HdxPickHit& lhs,
500 const HdxPickHit& rhs);
501HDX_API
502bool operator!=(const HdxPickHit& lhs,
503 const HdxPickHit& rhs);
504
505HDX_API
506std::ostream& operator<<(std::ostream& out, const HdxPickTaskParams& pv);
507HDX_API
508bool operator==(const HdxPickTaskParams& lhs,
509 const HdxPickTaskParams& rhs);
510HDX_API
511bool operator!=(const HdxPickTaskParams& lhs,
512 const HdxPickTaskParams& rhs);
513
514HDX_API
515std::ostream& operator<<(std::ostream& out, const HdxPickTaskContextParams& pv);
516HDX_API
517bool operator==(const HdxPickTaskContextParams& lhs,
518 const HdxPickTaskContextParams& rhs);
519HDX_API
520bool operator!=(const HdxPickTaskContextParams& lhs,
521 const HdxPickTaskContextParams& rhs);
522PXR_NAMESPACE_CLOSE_SCOPE
523
524#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:104
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.
A utility class for resolving ID buffers into hits.
Definition: pickTask.h:376
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:279
static int DecodeIDRenderColor(unsigned char const idColor[4])
Utility: Given a UNorm8Vec4 pixel, unpack it into an int32 ID.
Definition: pickTask.h:306
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:234
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
HdContainerDataSourceHandle primOrigin
The prim origin data source for the picked prim if provided by the scene index.
Definition: pickTask.h:198
std::vector< HdxInstancerContext > instancerContexts
Information about the instancers instancing the picked object.
Definition: pickTask.h:195
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