Overte C++ Documentation
SpatiallyNestable.h
1 //
2 // SpatiallyNestable.h
3 // libraries/shared/src/
4 //
5 // Created by Seth Alves on 2015-10-18
6 // Copyright 2015 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_SpatiallyNestable_h
13 #define hifi_SpatiallyNestable_h
14 
15 #include <QUuid>
16 
17 #include "Transform.h"
18 #include "AACube.h"
19 #include "SpatialParentFinder.h"
20 #include "shared/ReadWriteLockable.h"
21 #include "Grab.h"
22 
23 class SpatiallyNestable;
24 using SpatiallyNestableWeakPointer = std::weak_ptr<SpatiallyNestable>;
25 using SpatiallyNestableWeakConstPointer = std::weak_ptr<const SpatiallyNestable>;
26 using SpatiallyNestablePointer = std::shared_ptr<SpatiallyNestable>;
27 using SpatiallyNestableConstPointer = std::shared_ptr<const SpatiallyNestable>;
28 
29 static const uint16_t INVALID_JOINT_INDEX = -1;
30 
31 enum class NestableType {
32  Entity,
33  Avatar
34 };
35 
36 class SpatiallyNestable : public std::enable_shared_from_this<SpatiallyNestable> {
37 public:
38  SpatiallyNestable(NestableType nestableType, QUuid id);
39  virtual ~SpatiallyNestable();
40 
41  virtual const QUuid getID() const;
42  virtual void setID(const QUuid& id);
43 
44  virtual QString getName() const { return "SpatiallyNestable"; }
45 
46  virtual const QUuid getParentID() const;
47  virtual void setParentID(const QUuid& parentID);
48 
49  virtual bool isMyAvatar() const { return false; }
50 
51  virtual quint16 getParentJointIndex() const { return _parentJointIndex; }
52  virtual void setParentJointIndex(quint16 parentJointIndex);
53 
54  static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex,
55  bool scalesWithParent, bool& success);
56  static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex,
57  bool scalesWithParent, bool& success);
58  static glm::vec3 worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID,
59  int parentJointIndex, bool scalesWithParent, bool& success);
60  static glm::vec3 worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
61  int parentJointIndex, bool scalesWithParent, bool& success);
62  static glm::vec3 worldToLocalDimensions(const glm::vec3& dimensions, const QUuid& parentID,
63  int parentJointIndex, bool scalesWithParent, bool& success);
64 
65  static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex,
66  bool scalesWithParent, bool& success);
67  static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex,
68  bool scalesWithParent, bool& success);
69  static glm::vec3 localToWorldVelocity(const glm::vec3& velocity,
70  const QUuid& parentID, int parentJointIndex, bool scalesWithParent, bool& success);
71  static glm::vec3 localToWorldAngularVelocity(const glm::vec3& angularVelocity,
72  const QUuid& parentID, int parentJointIndex,
73  bool scalesWithParent, bool& success);
74  static glm::vec3 localToWorldDimensions(const glm::vec3& dimensions, const QUuid& parentID,
75  int parentJointIndex, bool scalesWithParent, bool& success);
76 
77  static QString nestableTypeToString(NestableType nestableType);
78 
79 
80  virtual bool isParentPathComplete(int depth = 0) const;
81 
82 
83  // world frame
84  virtual const Transform getTransform(bool& success, int depth = 0) const;
85  virtual const Transform getTransformWithOnlyLocalRotation(bool& success, int depth = 0) const;
86  virtual const Transform getTransform() const;
87  virtual void setTransform(const Transform& transform, bool& success);
88  virtual bool setTransform(const Transform& transform);
89 
90  virtual Transform getParentTransform(bool& success, int depth = 0) const;
91 
92  void setWorldTransform(const glm::vec3& position, const glm::quat& orientation);
93  virtual glm::vec3 getWorldPosition(bool& success) const;
94  virtual glm::vec3 getWorldPosition() const;
95  virtual void setWorldPosition(const glm::vec3& position, bool& success, bool tellPhysics = true);
96  virtual void setWorldPosition(const glm::vec3& position);
97 
98  virtual glm::quat getWorldOrientation(bool& success) const;
99  virtual glm::quat getWorldOrientation() const;
100  virtual glm::quat getWorldOrientation(int jointIndex, bool& success) const;
101  virtual void setWorldOrientation(const glm::quat& orientation, bool& success, bool tellPhysics = true);
102  virtual void setWorldOrientation(const glm::quat& orientation);
103 
104  virtual glm::vec3 getWorldVelocity(bool& success) const;
105  virtual glm::vec3 getWorldVelocity() const;
106  virtual void setWorldVelocity(const glm::vec3& velocity, bool& success);
107  virtual void setWorldVelocity(const glm::vec3& velocity);
108  virtual glm::vec3 getParentVelocity(bool& success) const;
109 
110  virtual glm::vec3 getWorldAngularVelocity(bool& success) const;
111  virtual glm::vec3 getWorldAngularVelocity() const;
112  virtual void setWorldAngularVelocity(const glm::vec3& angularVelocity, bool& success);
113  virtual void setWorldAngularVelocity(const glm::vec3& angularVelocity);
114  virtual glm::vec3 getParentAngularVelocity(bool& success) const;
115 
116  virtual AACube getMaximumAACube(bool& success) const;
117  virtual AACube calculateInitialQueryAACube(bool& success);
118 
119  virtual void setQueryAACube(const AACube& queryAACube);
120  virtual bool queryAACubeNeedsUpdate() const;
121  virtual bool queryAACubeNeedsUpdateWithDescendantAACube(const AACube& descendantAACube) const;
122  virtual bool shouldPuffQueryAACube() const { return false; }
123  bool updateQueryAACube(bool updateParent = true);
124  bool updateQueryAACubeWithDescendantAACube(const AACube& descendentAACube, bool updateParent = true);
125  void forceQueryAACubeUpdate() { _queryAACubeSet = false; }
126  virtual AACube getQueryAACube(bool& success) const;
127  virtual AACube getQueryAACube() const;
128 
129  virtual glm::vec3 getSNScale() const;
130  virtual glm::vec3 getSNScale(bool& success) const;
131  virtual void setSNScale(const glm::vec3& scale);
132  virtual void setSNScale(const glm::vec3& scale, bool& success);
133 
134  // get world-frame values for a specific joint
135  virtual const Transform getJointTransform(int jointIndex, bool& success, int depth = 0) const;
136  virtual glm::vec3 getJointWorldPosition(int jointIndex, bool& success) const;
137  virtual glm::vec3 getJointSNScale(int jointIndex, bool& success) const;
138 
139  // object's parent's frame
140  virtual Transform getLocalTransform() const;
141  virtual void setLocalTransform(const Transform& transform);
142 
143  virtual glm::vec3 getLocalPosition() const;
144  virtual void setLocalPosition(const glm::vec3& position, bool tellPhysics = true);
145 
146  virtual glm::quat getLocalOrientation() const;
147  virtual void setLocalOrientation(const glm::quat& orientation);
148 
149  virtual glm::vec3 getLocalVelocity() const;
150  virtual void setLocalVelocity(const glm::vec3& velocity);
151 
152  virtual glm::vec3 getLocalAngularVelocity() const;
153  virtual void setLocalAngularVelocity(const glm::vec3& angularVelocity);
154 
155  virtual glm::vec3 getLocalSNScale() const;
156  virtual void setLocalSNScale(const glm::vec3& scale);
157 
158  virtual bool getScalesWithParent() const { return false; }
159  virtual glm::vec3 scaleForChildren() const { return glm::vec3(1.0f); }
160 
161  QList<SpatiallyNestablePointer> getChildren() const;
162  bool hasChildren() const;
163 
164  NestableType getNestableType() const { return _nestableType; }
165 
166  // this object's frame
167  virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const;
168  virtual glm::vec3 getAbsoluteJointScaleInObjectFrame(int index) const { return glm::vec3(1.0f); }
169  virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { return glm::quat(); }
170  virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { return glm::vec3(); }
171  virtual int getJointParent(int index) const { return -1; }
172 
173  virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { return false; }
174  virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) {return false; }
175 
176  virtual glm::quat getLocalJointRotation(int index) const {return glm::quat(); }
177  virtual glm::vec3 getLocalJointTranslation(int index) const {return glm::vec3(); }
178  virtual bool setLocalJointRotation(int index, const glm::quat& rotation) { return false; }
179  virtual bool setLocalJointTranslation(int index, const glm::vec3& translation) { return false; }
180 
181  SpatiallyNestablePointer getThisPointer() const;
182 
183  using ChildLambda = std::function<void(const SpatiallyNestablePointer&)>;
184  using ChildLambdaTest = std::function<bool(const SpatiallyNestablePointer&)>;
185 
186  void forEachChild(const ChildLambda& actor) const;
187  void forEachDescendant(const ChildLambda& actor) const;
188  void forEachChildTest(const ChildLambdaTest& actor) const;
189  void forEachDescendantTest(const ChildLambdaTest& actor) const;
190 
191  void die() { _isDead = true; }
192  bool isDead() const { return _isDead; }
193 
194  bool isParentIDValid() const { bool success = false; getParentPointer(success); return success; }
195  virtual SpatialParentTree* getParentTree() const { return nullptr; }
196 
197  bool hasAncestorOfType(NestableType nestableType, int depth = 0) const;
198  const QUuid findAncestorOfType(NestableType nestableType, int depth = 0) const;
199  SpatiallyNestablePointer getParentPointer(bool& success) const;
200  static SpatiallyNestablePointer findByID(QUuid id, bool& success);
201 
202  void getLocalTransformAndVelocities(Transform& localTransform,
203  glm::vec3& localVelocity,
204  glm::vec3& localAngularVelocity) const;
205 
206  void setLocalTransformAndVelocities(
207  const Transform& localTransform,
208  const glm::vec3& localVelocity,
209  const glm::vec3& localAngularVelocity);
210 
211  bool scaleChangedSince(quint64 time) const { return _scaleChanged > time; }
212  bool tranlationChangedSince(quint64 time) const { return _translationChanged > time; }
213  bool rotationChangedSince(quint64 time) const { return _rotationChanged > time; }
214 
215  void dump(const QString& prefix = "") const;
216 
217  virtual void locationChanged(bool tellPhysics = true, bool tellChildren = true); // called when a this object's location has changed
218  virtual void dimensionsChanged() { _queryAACubeSet = false; } // called when a this object's dimensions have changed
219  virtual void parentDeleted() { } // called on children of a deleted parent
220 
221  virtual void addGrab(GrabPointer grab);
222  virtual void removeGrab(GrabPointer grab);
223  virtual void disableGrab(GrabPointer grab) {};
224  bool hasGrabs();
225  virtual QUuid getEditSenderID();
226 
227  void bumpAncestorChainRenderableVersion(int depth = 0) const;
228 
229 protected:
230  QUuid _id;
231  mutable SpatiallyNestableWeakPointer _parent;
232 
233  virtual void beParentOfChild(SpatiallyNestablePointer newChild) const;
234  virtual void forgetChild(SpatiallyNestablePointer newChild) const;
235  virtual void recalculateChildCauterization() const { }
236 
237  mutable ReadWriteLockable _childrenLock;
238  mutable QHash<QUuid, SpatiallyNestableWeakPointer> _children;
239 
240  // _queryAACube is used to decide where something lives in the octree
241  mutable AACube _queryAACube;
242  mutable bool _queryAACubeSet { false };
243 
244  quint64 _scaleChanged { 0 };
245  quint64 _translationChanged { 0 };
246  quint64 _rotationChanged { 0 };
247 
248  mutable ReadWriteLockable _grabsLock;
249  QSet<GrabPointer> _grabs; // upon this thing
250 
251  mutable std::atomic<uint32_t> _ancestorChainRenderableVersion { 0 };
252 
253 private:
254  SpatiallyNestable() = delete;
255  const NestableType _nestableType; // EntityItem or an AvatarData
256  QUuid _parentID; // what is this thing's transform relative to?
257  quint16 _parentJointIndex { INVALID_JOINT_INDEX }; // which joint of the parent is this relative to?
258 
259  mutable ReadWriteLockable _transformLock;
260  mutable ReadWriteLockable _idLock;
261  mutable ReadWriteLockable _velocityLock;
262  mutable ReadWriteLockable _angularVelocityLock;
263  Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform.
264  glm::vec3 _velocity;
265  glm::vec3 _angularVelocity;
266  mutable bool _parentKnowsMe { false };
267  bool _isDead { false };
268  bool _queryAACubeIsPuffed { false };
269 
270  void breakParentingLoop() const;
271 };
272 
273 
274 #endif // hifi_SpatiallyNestable_h