Loading...
Searching...
No Matches
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/hdSt/textureUtils.h"
31#include "pxr/imaging/hd/dataSource.h"
32#include "pxr/imaging/hd/enums.h"
34#include "pxr/imaging/hd/renderPass.h"
35#include "pxr/imaging/hd/renderPassState.h"
36#include "pxr/imaging/hd/rprimCollection.h"
37#include "pxr/imaging/hd/task.h"
38
39#include "pxr/base/arch/align.h"
42#include "pxr/base/gf/vec2i.h"
43#include "pxr/base/gf/vec2f.h"
44#include "pxr/base/gf/vec4i.h"
45#include "pxr/base/gf/vec4d.h"
46#include "pxr/usd/sdf/path.h"
47
48#include <vector>
49#include <memory>
50
51PXR_NAMESPACE_OPEN_SCOPE
52
53#define HDX_PICK_TOKENS \
54 /* Task context */ \
55 (pickParams) \
56 \
57 /* Pick target */ \
58 (pickPrimsAndInstances) \
59 (pickFaces) \
60 (pickEdges) \
61 (pickPoints) \
62 (pickPointsAndInstances) \
63 \
64 /* Resolve mode */ \
65 (resolveNearestToCamera) \
66 (resolveNearestToCenter) \
67 (resolveUnique) \
68 (resolveAll)
69
70TF_DECLARE_PUBLIC_TOKENS(HdxPickTokens, HDX_API, HDX_PICK_TOKENS);
71
72class HdStRenderBuffer;
74using HdStShaderCodeSharedPtr = std::shared_ptr<class HdStShaderCode>;
75
76class Hgi;
77
82{
84 : cullStyle(HdCullStyleNothing)
85 , enableSceneMaterials(true)
86 {}
87
88 HdCullStyle cullStyle;
89 bool enableSceneMaterials;
90};
91
95{
106 int instanceIndex;
107 int elementIndex;
108 int edgeIndex;
109 int pointIndex;
110 GfVec3f worldSpaceHitPoint;
111 GfVec3f worldSpaceHitNormal;
115
116 inline bool IsValid() const {
117 return !objectId.IsEmpty();
118 }
119
120 HDX_API
121 size_t GetHash() const;
122};
123
124using HdxPickHitVector = std::vector<HdxPickHit>;
125
129{
133 HdContainerDataSourceHandle instancerPrimOrigin;
134
138
156 HdContainerDataSourceHandle instancePrimOrigin;
159};
160
179{
182 HDX_API
183 static HdxPrimOriginInfo
185 const HdxPickHit &hit);
186
193 HDX_API
195 const TfToken &nameInPrimOrigin =
196 HdPrimOriginSchemaTokens->scenePath) const;
197
200 std::vector<HdxInstancerContext> instancerContexts;
203 HdContainerDataSourceHandle primOrigin;
204};
205
235{
236 using DepthMaskCallback = std::function<void(void)>;
237
239 : resolution(128, 128)
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 , outHits(nullptr)
249 {}
250
251 GfVec2i resolution;
252 TfToken pickTarget;
253 TfToken resolveMode;
254 bool doUnpickablesOcclude;
255 GfMatrix4d viewMatrix;
256 GfMatrix4d projectionMatrix;
257 std::vector<GfVec4d> clipPlanes;
258 DepthMaskCallback depthMaskCallback;
259 HdRprimCollection collection;
260 HdxPickHitVector *outHits;
261};
262
275class HdxPickTask : public HdTask
276{
277public:
278 HDX_API
279 HdxPickTask(HdSceneDelegate* delegate, SdfPath const& id);
280
281 HDX_API
282 ~HdxPickTask() override;
283
285 HDX_API
286 void Sync(HdSceneDelegate* delegate,
287 HdTaskContext* ctx,
288 HdDirtyBits* dirtyBits) override;
289
291 HDX_API
292 void Prepare(HdTaskContext* ctx,
293 HdRenderIndex* renderIndex) override;
294
296 HDX_API
297 void Execute(HdTaskContext* ctx) override;
298
299 HDX_API
300 const TfTokenVector &GetRenderTags() const override;
301
303 static inline int DecodeIDRenderColor(unsigned char const idColor[4]) {
304 return (int32_t(idColor[0] & 0xff) << 0) |
305 (int32_t(idColor[1] & 0xff) << 8) |
306 (int32_t(idColor[2] & 0xff) << 16) |
307 (int32_t(idColor[3] & 0xff) << 24);
308 }
309
310private:
311 HdxPickTaskParams _params;
312 HdxPickTaskContextParams _contextParams;
313 TfTokenVector _allRenderTags;
314 TfTokenVector _nonWidgetRenderTags;
315
316 // We need to cache a pointer to the render index so Execute() can
317 // map prim ID to paths.
318 HdRenderIndex *_index;
319
320 void _InitIfNeeded();
321 void _CreateAovBindings();
322 void _CleanupAovBindings();
323 void _ResizeOrCreateBufferForAOV(
324 const HdRenderPassAovBinding& aovBinding);
325
326 void _ConditionStencilWithGLCallback(
327 HdxPickTaskContextParams::DepthMaskCallback maskCallback,
328 HdRenderBuffer const * depthStencilBuffer);
329
330 bool _UseOcclusionPass() const;
331 bool _UseWidgetPass() const;
332
333 template<typename T>
334 HdStTextureUtils::AlignedBuffer<T>
335 _ReadAovBuffer(TfToken const & aovName) const;
336
337 HdRenderBuffer const * _FindAovBuffer(TfToken const & aovName) const;
338
339 // Create a shared render pass each for pickables, unpickables, and
340 // widgets (which may draw on top even when occluded).
341 HdRenderPassSharedPtr _pickableRenderPass;
342 HdRenderPassSharedPtr _occluderRenderPass;
343 HdRenderPassSharedPtr _widgetRenderPass;
344
345 // Having separate render pass states allows us to use different
346 // shader mixins if we choose to (we don't currently).
347 HdRenderPassStateSharedPtr _pickableRenderPassState;
348 HdRenderPassStateSharedPtr _occluderRenderPassState;
349 HdRenderPassStateSharedPtr _widgetRenderPassState;
350
351 Hgi* _hgi;
352
353 std::vector<std::unique_ptr<HdStRenderBuffer>> _pickableAovBuffers;
354 HdRenderPassAovBindingVector _pickableAovBindings;
355 HdRenderPassAovBinding _occluderAovBinding;
356 size_t _pickableDepthIndex;
357 TfToken _depthToken;
358 std::unique_ptr<HdStRenderBuffer> _widgetDepthStencilBuffer;
359 HdRenderPassAovBindingVector _widgetAovBindings;
360
361 HdxPickTask() = delete;
362 HdxPickTask(const HdxPickTask &) = delete;
363 HdxPickTask &operator =(const HdxPickTask &) = delete;
364};
365
368public:
369
370 // Pick result takes a tuple of ID buffers:
371 // - (primId, instanceId, elementId, edgeId, pointId)
372 // along with some geometric buffers:
373 // - (depth, Neye)
374 // ... and resolves them into a series of hits, using one of the
375 // algorithms specified below.
376 //
377 // index is used to fill in the HdxPickHit structure;
378 // pickTarget is used to determine what a valid hit is;
379 // viewMatrix, projectionMatrix, depthRange are used for unprojection
380 // to calculate the worldSpaceHitPosition and worldSpaceHitNormal.
381 // bufferSize is the size of the ID buffers, and subRect is the sub-region
382 // of the id buffers to iterate over in the resolution algorithm.
383 //
384 // All buffers need to be the same size, if passed in. It's legal for
385 // only the depth and primId buffers to be provided; everything else is
386 // optional but provides a richer picking result.
387 HDX_API
388 HdxPickResult(int const* primIds,
389 int const* instanceIds,
390 int const* elementIds,
391 int const* edgeIds,
392 int const* pointIds,
393 int const* neyes,
394 float const* depths,
395 HdRenderIndex const *index,
396 TfToken const& pickTarget,
397 GfMatrix4d const& viewMatrix,
398 GfMatrix4d const& projectionMatrix,
399 GfVec2f const& depthRange,
400 GfVec2i const& bufferSize,
401 GfVec4i const& subRect);
402
403 HDX_API
405
406 HDX_API
408 HDX_API
409 HdxPickResult& operator=(HdxPickResult &&);
410
412 HDX_API
413 bool IsValid() const;
414
418 HDX_API
419 void ResolveNearestToCamera(HdxPickHitVector* allHits) const;
420
424 HDX_API
425 void ResolveNearestToCenter(HdxPickHitVector* allHits) const;
426
429 HDX_API
430 void ResolveAll(HdxPickHitVector* allHits) const;
431
434 HDX_API
435 void ResolveUnique(HdxPickHitVector* allHits) const;
436
437private:
438 bool _ResolveHit(int index, int x, int y, float z, HdxPickHit* hit) const;
439
440 size_t _GetHash(int index) const;
441 bool _IsValidHit(int index) const;
442
443 // Provide accessors for all of the ID buffers. Since all but _primIds
444 // are optional, if the buffer doesn't exist just return -1 (== no hit).
445 int _GetPrimId(int index) const {
446 return _primIds ? _primIds[index] : -1;
447 }
448 int _GetInstanceId(int index) const {
449 return _instanceIds ? _instanceIds[index] : -1;
450 }
451 int _GetElementId(int index) const {
452 return _elementIds ? _elementIds[index] : -1;
453 }
454 int _GetEdgeId(int index) const {
455 return _edgeIds ? _edgeIds[index] : -1;
456 }
457 int _GetPointId(int index) const {
458 return _pointIds ? _pointIds[index] : -1;
459 }
460
461 // Provide an accessor for the normal buffer. If the normal buffer is
462 // provided, this function will unpack the normal. The fallback is
463 // GfVec3f(0.0f).
464 GfVec3f _GetNormal(int index) const;
465
466 int const* _primIds;
467 int const* _instanceIds;
468 int const* _elementIds;
469 int const* _edgeIds;
470 int const* _pointIds;
471 int const* _neyes;
472 float const* _depths;
473 HdRenderIndex const *_index;
474 TfToken _pickTarget;
475 GfMatrix4d _ndcToWorld;
476 GfMatrix4d _eyeToWorld;
477 GfVec2f _depthRange;
478 GfVec2i _bufferSize;
479 GfVec4i _subRect;
480};
481
482// For sorting, order hits by ndc depth.
483HDX_API
484bool operator<(HdxPickHit const& lhs, HdxPickHit const& rhs);
485
486// VtValue requirements
487HDX_API
488std::ostream& operator<<(std::ostream& out, const HdxPickHit& h);
489HDX_API
490bool operator==(const HdxPickHit& lhs,
491 const HdxPickHit& rhs);
492HDX_API
493bool operator!=(const HdxPickHit& lhs,
494 const HdxPickHit& rhs);
495
496HDX_API
497std::ostream& operator<<(std::ostream& out, const HdxPickTaskParams& pv);
498HDX_API
499bool operator==(const HdxPickTaskParams& lhs,
500 const HdxPickTaskParams& rhs);
501HDX_API
502bool operator!=(const HdxPickTaskParams& lhs,
503 const HdxPickTaskParams& rhs);
504
505HDX_API
506std::ostream& operator<<(std::ostream& out, const HdxPickTaskContextParams& pv);
507HDX_API
508bool operator==(const HdxPickTaskContextParams& lhs,
509 const HdxPickTaskContextParams& rhs);
510HDX_API
511bool operator!=(const HdxPickTaskContextParams& lhs,
512 const HdxPickTaskContextParams& rhs);
513PXR_NAMESPACE_CLOSE_SCOPE
514
515#endif // PXR_IMAGING_HDX_PICK_TASK_H
Provide architecture-specific memory-alignment information.
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:88
Basic type for a vector of 2 float components.
Definition: vec2f.h:63
Basic type for a vector of 2 int components.
Definition: vec2i.h:61
Basic type for a vector of 3 float components.
Definition: vec3f.h:63
Basic type for a vector of 4 int components.
Definition: vec4i.h:61
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:50
The Hydra render index is a flattened representation of the client scene graph, which may be composed...
Definition: renderIndex.h:121
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:367
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:276
static int DecodeIDRenderColor(unsigned char const idColor[4])
Utility: Given a UNorm8Vec4 pixel, unpack it into an int32 ID.
Definition: pickTask.h:303
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:111
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Definition: path.h:414
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:88
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:98
A renderpass AOV represents a binding of some output of the rendering process to an output buffer.
Definition: aov.h:117
Information about an instancer instancing a picked object (or an instancer instancing such an instanc...
Definition: pickTask.h:129
HdContainerDataSourceHandle instancerPrimOrigin
The prim origin data source of the instancer.
Definition: pickTask.h:133
HdContainerDataSourceHandle instancePrimOrigin
The prim origin data source of the picked (implicit) instance.
Definition: pickTask.h:156
int instanceId
Index of the picked instance.
Definition: pickTask.h:158
SdfPath instanceSceneIndexPath
For implicit instancing (native instancing in USD), the path of the picked instance in the scene inde...
Definition: pickTask.h:137
SdfPath instancerSceneIndexPath
The path of the instancer in the scene index.
Definition: pickTask.h:131
Picking hit structure.
Definition: pickTask.h:95
float normalizedDepth
normalizedDepth is in the range [0,1].
Definition: pickTask.h:114
SdfPath delegateId
delegateID of HdSceneDelegate that provided the picked prim.
Definition: pickTask.h:98
SdfPath objectId
Path computed from scenePath's in primOrigin data source of picked prim and instancers if provided by...
Definition: pickTask.h:102
SdfPath instancerId
Only supported for scene delegates, see HdxPrimOriginInfo for scene indices.
Definition: pickTask.h:105
Pick task context params.
Definition: pickTask.h:235
Pick task params.
Definition: pickTask.h:82
A helper to extract information about the picked prim that allows modern applications to identify a p...
Definition: pickTask.h:179
HdContainerDataSourceHandle primOrigin
The prim origin data source for the picked prim if provided by the scene index.
Definition: pickTask.h:203
std::vector< HdxInstancerContext > instancerContexts
Information about the instancers instancing the picked object.
Definition: pickTask.h:200
static HDX_API HdxPrimOriginInfo FromPickHit(HdRenderIndex *renderIndex, const HdxPickHit &hit)
Query terminal scene index of render index for information about picked prim.
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:457