Overte C++ Documentation
PickFilter.h
1 //
2 // Created by Sam Gondelman on December 7th, 2018.
3 // Copyright 2018 High Fidelity, Inc.
4 // Copyright 2025 Overte e.V.
5 //
6 // Distributed under the Apache License, Version 2.0.
7 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
8 //
9 
10 #ifndef hifi_PickFilter_h
11 #define hifi_PickFilter_h
12 
13 #include <bitset>
14 #include <iostream> // adebug
15 
16 class PickFilter {
17 public:
18 
19  /*@jsdoc
20  * <p>A set of flags for a pick filter. The value is constructed by using the <code>|</code> (bitwise OR) operator on the
21  * individual flag values.</p>
22  * <table>
23  * <thead>
24  * <tr><th>Flag Name</th><th>Value</th><th>Description</th></tr>
25  * </thead>
26  * <tbody>
27  * <tr><td>PICK_DOMAIN_ENTITIES</td><td><code>1</code></td><td>Include domain entities when intersecting.</td></tr>
28  * <tr><td>PICK_AVATAR_ENTITIES</td><td><code>2</code></td><td>Include avatar entities when intersecting.</td></tr>
29  * <tr><td>PICK_LOCAL_ENTITIES</td><td><code>4</code></td><td>Include local entities when intersecting.</td></tr>
30  * <tr><td>PICK_AVATARS</td><td><code>8</code></td><td>Include avatars when intersecting.</td></tr>
31  * <tr><td>PICK_HUD</td><td><code>16</code></td><td>Include the HUD surface when intersecting in HMD mode.</td></tr>
32  * <tr><td>PICK_INCLUDE_VISIBLE</td><td><code>32</code></td><td>Include visible objects when intersecting.</td></tr>
33  * <tr><td>PICK_INCLUDE_INVISIBLE</td><td><code>64</code></td><td>Include invisible objects when intersecting.</td></tr>
34  * <tr><td>PICK_INCLUDE_COLLIDABLE</td><td><code>128</code></td><td>Include collidable objects when
35  * intersecting.</td></tr>
36  * <tr><td>PICK_INCLUDE_NONCOLLIDABLE</td><td><code>256</code></td><td>Include non-collidable objects when
37  * intersecting.</td></tr>
38  * <tr><td>PICK_PRECISE</td><td><code>512</code></td><td>Pick against exact meshes.</td></tr>
39  * <tr><td>PICK_COARSE</td><td><code>1024</code></td><td>Pick against coarse meshes.</td></tr>
40  * <tr><td>PICK_ALL_INTERSECTIONS</td><td><code>2048</code></td><td>Return all intersections instead of just the
41  * closest.</td></tr>
42  * </tbody>
43  * </table>
44  * @typedef {number} FilterFlags
45  */
46  enum FlagBit {
47  DOMAIN_ENTITIES = 0,
48  AVATAR_ENTITIES,
49  LOCAL_ENTITIES,
50  AVATARS,
51  HUD,
52 
53  VISIBLE,
54  INVISIBLE,
55 
56  COLLIDABLE,
57  NONCOLLIDABLE,
58 
59  PRECISE,
60  COARSE,
61 
62  // NOT YET IMPLEMENTED
63  PICK_ALL_INTERSECTIONS, // if not set, returns closest intersection, otherwise, returns list of all intersections
64 
65  PICK_BYPASS_IGNORE, // for debug purposes
66 
67  NUM_FLAGS, // Not a valid flag
68  };
69  typedef std::bitset<NUM_FLAGS> Flags;
70 
71  // The key is the Flags
72  Flags _flags;
73 
74  PickFilter() {}
75  PickFilter(const Flags& flags) : _flags(flags) {}
76 
77  bool operator==(const PickFilter& rhs) const { return _flags == rhs._flags; }
78  bool operator!=(const PickFilter& rhs) const { return _flags != rhs._flags; }
79 
80  void setFlag(FlagBit flag, bool value) { _flags[flag] = value; }
81 
82  // There are different groups of related flags. If none of the flags in a group are set, the search filter includes them all.
83  bool doesPickDomainEntities() const { return _flags[DOMAIN_ENTITIES] || !(_flags[AVATAR_ENTITIES] || _flags[LOCAL_ENTITIES] || _flags[AVATARS] || _flags[HUD]); }
84  bool doesPickAvatarEntities() const { return _flags[AVATAR_ENTITIES] || !(_flags[DOMAIN_ENTITIES] || _flags[LOCAL_ENTITIES] || _flags[AVATARS] || _flags[HUD]); }
85  bool doesPickLocalEntities() const { return _flags[LOCAL_ENTITIES] || !(_flags[DOMAIN_ENTITIES] || _flags[AVATAR_ENTITIES] || _flags[AVATARS] || _flags[HUD]); }
86  bool doesPickAvatars() const { return _flags[AVATARS] || !(_flags[DOMAIN_ENTITIES] || _flags[AVATAR_ENTITIES] || _flags[LOCAL_ENTITIES] || _flags[HUD]); }
87  bool doesPickHUD() const { return _flags[HUD] || !(_flags[DOMAIN_ENTITIES] || _flags[AVATAR_ENTITIES] || _flags[LOCAL_ENTITIES] || _flags[AVATARS]); }
88 
89  bool doesPickVisible() const { return _flags[VISIBLE] || !_flags[INVISIBLE]; }
90  bool doesPickInvisible() const { return _flags[INVISIBLE] || !_flags[VISIBLE]; }
91 
92  bool doesPickCollidable() const { return _flags[COLLIDABLE] || !_flags[NONCOLLIDABLE]; }
93  bool doesPickNonCollidable() const { return _flags[NONCOLLIDABLE] || !_flags[COLLIDABLE]; }
94 
95  bool isPrecise() const { return _flags[PRECISE] || !_flags[COARSE]; }
96  bool isCoarse() const { return _flags[COARSE]; }
97 
98  bool doesWantAllIntersections() const { return _flags[PICK_ALL_INTERSECTIONS]; }
99 
100  bool bypassIgnore() const { return _flags[PICK_BYPASS_IGNORE]; }
101 
102  // Helpers for RayPickManager
103  Flags getEntityFlags() const {
104  unsigned int toReturn = 0;
105  for (int i = DOMAIN_ENTITIES; i <= LOCAL_ENTITIES; i++) {
106  if (_flags[i]) {
107  toReturn |= getBitMask(FlagBit(i));
108  }
109  }
110  for (int i = HUD + 1; i < NUM_FLAGS; i++) {
111  if (_flags[i]) {
112  toReturn |= getBitMask(FlagBit(i));
113  }
114  }
115  return Flags(toReturn);
116  }
117  Flags getAvatarFlags() const { return Flags(getBitMask(AVATARS)); }
118  Flags getHUDFlags() const { return Flags(getBitMask(HUD)); }
119 
120  static constexpr unsigned int getBitMask(FlagBit bit) { return 1 << bit; }
121 };
122 
123 #endif // hifi_PickFilter_h
124