Overte C++ Documentation
EntityTreeElement.h
1 //
2 // EntityTreeElement.h
3 // libraries/entities/src
4 //
5 // Created by Brad Hefta-Gaub on 12/4/13.
6 // Copyright 2013 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_EntityTreeElement_h
13 #define hifi_EntityTreeElement_h
14 
15 #include <memory>
16 
17 #include <OctreeElement.h>
18 #include <QList>
19 
20 #include "EntityEditPacketSender.h"
21 #include "EntityItem.h"
22 
23 #include <PickFilter.h>
24 
25 class EntityTree;
26 class EntityTreeElement;
27 
28 using EntityItems = QVector<EntityItemPointer>;
29 using EntityTreeElementWeakPointer = std::weak_ptr<EntityTreeElement>;
30 using EntityTreeElementPointer = std::shared_ptr<EntityTreeElement>;
31 using EntityItemFilter = std::function<bool(EntityItemPointer&)>;
32 
33 class EntityTreeUpdateArgs {
34 public:
35  EntityTreeUpdateArgs() :
36  _totalElements(0),
37  _totalItems(0),
38  _movingItems(0)
39  { }
40 
41  QList<EntityItemPointer> _movingEntities;
42  int _totalElements;
43  int _totalItems;
44  int _movingItems;
45 };
46 
47 class EntityTreeElementExtraEncodeData : public OctreeElementExtraEncodeDataBase {
48 public:
49  EntityTreeElementExtraEncodeData() :
50  elementCompleted(false),
51  subtreeCompleted(false),
52  entities() {
53  memset(childCompleted, 0, sizeof(childCompleted));
54  }
55  bool elementCompleted;
56  bool subtreeCompleted;
57  bool childCompleted[NUMBER_OF_CHILDREN];
58  QMap<EntityItemID, EntityPropertyFlags> entities;
59 };
60 using EntityTreeElementExtraEncodeDataPointer = std::shared_ptr<EntityTreeElementExtraEncodeData>;
61 
62 inline QDebug operator<<(QDebug debug, const EntityTreeElementExtraEncodeDataPointer data) {
63  debug << "{";
64  debug << " elementCompleted: " << data->elementCompleted << ", ";
65  debug << " subtreeCompleted: " << data->subtreeCompleted << ", ";
66  debug << " childCompleted[]: ";
67  for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
68  debug << " " << i << ":" << data->childCompleted[i] << ", ";
69  }
70  debug << " entities.size: " << data->entities.size() << "}";
71  return debug;
72 }
73 
74 
75 class SendModelsOperationArgs {
76 public:
77  glm::vec3 root;
78  EntityEditPacketSender* packetSender;
79 };
80 
81 class EntityTreeElement : public OctreeElement, ReadWriteLockable {
82  friend class EntityTree; // to allow createElement to new us...
83 
84  EntityTreeElement(unsigned char* octalCode = NULL);
85 
86  virtual OctreeElementPointer createNewElement(unsigned char* octalCode = NULL) override;
87 
88 public:
89  virtual ~EntityTreeElement();
90 
91  // type safe versions of OctreeElement methods
92  EntityTreeElementPointer getChildAtIndex(int index) const {
93  return std::static_pointer_cast<EntityTreeElement>(OctreeElement::getChildAtIndex(index));
94  }
95 
96  // methods you can and should override to implement your tree functionality
97 
99  virtual OctreeElementPointer addChildAtIndex(int index) override;
100 
102  virtual void calculateAverageFromChildren() override;
103 
105  virtual bool collapseChildren() override;
106 
109  virtual bool hasContent() const override { return hasEntities(); }
110 
113  virtual bool hasDetailedContent() const override { return hasEntities(); }
114 
118  virtual void splitChildren() override { }
119 
121  virtual bool requiresSplit() const override { return false; }
122 
123  virtual void debugExtraEncodeData(EncodeBitstreamParams& params) const override;
124 
127  virtual int readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
128  ReadBitstreamToTreeParams& args) override;
129 
134  virtual bool isRendered() const override { return getShouldRender(); }
135  virtual bool deleteApproved() const override { return !hasEntities(); }
136 
137  static bool checkFilterSettings(const EntityItemPointer& entity, PickFilter searchFilter);
138  virtual bool canPickIntersect() const override { return hasEntities(); }
139  virtual EntityItemID evalRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& viewFrustumPos,
140  OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
141  const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIdsToDiscard,
142  PickFilter searchFilter, QVariantMap& extraInfo);
143  virtual EntityItemID evalDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
144  const glm::vec3& viewFrustumPos, OctreeElementPointer& element, float& distance,
145  BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
146  const QVector<EntityItemID>& entityIdsToDiscard, PickFilter searchFilter, QVariantMap& extraInfo);
147  virtual bool findSpherePenetration(const glm::vec3& center, float radius,
148  glm::vec3& penetration, void** penetratedObject) const override;
149 
150  virtual EntityItemID evalParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity,
151  const glm::vec3& acceleration, const glm::vec3& viewFrustumPos, OctreeElementPointer& element, float& parabolicDistance,
152  BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
153  const QVector<EntityItemID>& entityIdsToDiscard, PickFilter searchFilter, QVariantMap& extraInfo);
154  virtual EntityItemID evalDetailedParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity,
155  const glm::vec3& normal, const glm::vec3& acceleration, const glm::vec3& viewFrustumPos, OctreeElementPointer& element,
156  float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
157  const QVector<EntityItemID>& entityIdsToDiscard, PickFilter searchFilter, QVariantMap& extraInfo);
158 
159  template <typename F>
160  void forEachEntity(F f) const {
161  withReadLock([&] {
162  foreach(EntityItemPointer entityItem, _entityItems) {
163  f(entityItem);
164  }
165  });
166  }
167 
168  virtual uint16_t size() const;
169  bool hasEntities() const { return size() > 0; }
170 
171  void setTree(EntityTreePointer tree) { _myTree = tree; }
172  EntityTreePointer getTree() const { return _myTree; }
173 
174  void addEntityItem(EntityItemPointer entity);
175 
176  QUuid evalClosetEntity(const glm::vec3& position, PickFilter searchFilter, float& closestDistanceSquared) const;
177  void evalEntitiesInSphere(const glm::vec3& position, float radius, PickFilter searchFilter, QVector<QUuid>& foundEntities) const;
178  void evalEntitiesInSphereWithType(const glm::vec3& position, float radius, EntityTypes::EntityType type, PickFilter searchFilter, QVector<QUuid>& foundEntities) const;
179  void evalEntitiesInSphereWithName(const glm::vec3& position, float radius, const QString& name, bool caseSensitive, PickFilter searchFilter, QVector<QUuid>& foundEntities) const;
180  void evalEntitiesInCube(const AACube& cube, PickFilter searchFilter, QVector<QUuid>& foundEntities) const;
181  void evalEntitiesInBox(const AABox& box, PickFilter searchFilter, QVector<QUuid>& foundEntities) const;
182  void evalEntitiesInFrustum(const ViewFrustum& frustum, PickFilter searchFilter, QVector<QUuid>& foundEntities) const;
183 
187  void getEntities(EntityItemFilter& filter, QVector<EntityItemPointer>& foundEntities);
188 
189  EntityItemPointer getEntityWithID(uint32_t id) const;
190  EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
191  void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
192 
193  void cleanupDomainAndNonOwnedEntities();
194  void cleanupEntities();
195  bool removeEntityItem(EntityItemPointer entity, bool deletion = false);
196 
197  bool containsEntityBounds(EntityItemPointer entity) const;
198  bool bestFitEntityBounds(EntityItemPointer entity) const;
199 
200  bool containsBounds(const EntityItemProperties& properties) const; // NOTE: property units in meters
201  bool bestFitBounds(const EntityItemProperties& properties) const; // NOTE: property units in meters
202 
203  bool containsBounds(const AACube& bounds) const; // NOTE: units in tree units
204  bool bestFitBounds(const AACube& bounds) const; // NOTE: units in tree units
205 
206  bool containsBounds(const AABox& bounds) const; // NOTE: units in tree units
207  bool bestFitBounds(const AABox& bounds) const; // NOTE: units in tree units
208 
209  bool containsBounds(const glm::vec3& minPoint, const glm::vec3& maxPoint) const; // NOTE: units in tree units
210  bool bestFitBounds(const glm::vec3& minPoint, const glm::vec3& maxPoint) const; // NOTE: units in tree units
211 
212  void debugDump();
213 
214  bool pruneChildren();
215 
216  void expandExtentsToContents(Extents& extents);
217 
218  EntityTreeElementPointer getThisPointer() {
219  return std::static_pointer_cast<EntityTreeElement>(shared_from_this());
220  }
221  OctreeElementPointer getThisOctreeElementPointer() {
222  return std::static_pointer_cast<OctreeElement>(shared_from_this());
223  }
224  const ConstOctreeElementPointer getConstThisOctreeElementPointer() const {
225  return std::static_pointer_cast<const OctreeElement>(shared_from_this());
226  }
227 
228 protected:
229  virtual void init(unsigned char * octalCode) override;
230  EntityTreePointer _myTree;
231  EntityItems _entityItems;
232 };
233 
234 #endif // hifi_EntityTreeElement_h
Utility for processing, packing, queueing and sending of outbound edit voxel messages.
Definition: EntityEditPacketSender.h:25
Abstract ID for editing model items. Used in EntityItem JS API.
Definition: EntityItemID.h:28
Definition: EntityItemProperties.h:106