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