From c1e2653526ee334e83cf8eee6b7e132abb893c47 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 8 Dec 2018 07:42:03 -0800 Subject: [PATCH] check for and break parenting loops in hasAncestorOfType, findAncestorOfType, isParentPathComplete --- libraries/shared/src/SpatiallyNestable.cpp | 52 +++++++++++++++------- libraries/shared/src/SpatiallyNestable.h | 8 ++-- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 97e20f5627..d704498143 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -748,6 +748,18 @@ const Transform SpatiallyNestable::getTransform() const { return result; } +void SpatiallyNestable::breakParentingLoop() const { + // someone created a loop. break it... + qCDebug(shared) << "Parenting loop detected: " << getID(); + SpatiallyNestablePointer _this = getThisPointer(); + _this->setParentID(QUuid()); + bool setPositionSuccess; + AACube aaCube = getQueryAACube(setPositionSuccess); + if (setPositionSuccess) { + _this->setWorldPosition(aaCube.calcCenter()); + } +} + const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, int depth) const { // this returns the world-space transform for this object. It finds its parent's transform (which may // cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it. @@ -755,15 +767,7 @@ const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, i if (depth > MAX_PARENTING_CHAIN_SIZE) { success = false; - // someone created a loop. break it... - qCDebug(shared) << "Parenting loop detected: " << getID(); - SpatiallyNestablePointer _this = getThisPointer(); - _this->setParentID(QUuid()); - bool setPositionSuccess; - AACube aaCube = getQueryAACube(setPositionSuccess); - if (setPositionSuccess) { - _this->setWorldPosition(aaCube.calcCenter()); - } + breakParentingLoop(); return jointInWorldFrame; } @@ -1208,8 +1212,12 @@ AACube SpatiallyNestable::getQueryAACube() const { return result; } -bool SpatiallyNestable::hasAncestorOfType(NestableType nestableType) const { - bool success; +bool SpatiallyNestable::hasAncestorOfType(NestableType nestableType, int depth) const { + if (depth > MAX_PARENTING_CHAIN_SIZE) { + breakParentingLoop(); + return false; + } + if (nestableType == NestableType::Avatar) { QUuid parentID = getParentID(); if (parentID == AVATAR_SELF_ID) { @@ -1217,6 +1225,7 @@ bool SpatiallyNestable::hasAncestorOfType(NestableType nestableType) const { } } + bool success; SpatiallyNestablePointer parent = getParentPointer(success); if (!success || !parent) { return false; @@ -1226,11 +1235,14 @@ bool SpatiallyNestable::hasAncestorOfType(NestableType nestableType) const { return true; } - return parent->hasAncestorOfType(nestableType); + return parent->hasAncestorOfType(nestableType, depth + 1); } -const QUuid SpatiallyNestable::findAncestorOfType(NestableType nestableType) const { - bool success; +const QUuid SpatiallyNestable::findAncestorOfType(NestableType nestableType, int depth) const { + if (depth > MAX_PARENTING_CHAIN_SIZE) { + breakParentingLoop(); + return QUuid(); + } if (nestableType == NestableType::Avatar) { QUuid parentID = getParentID(); @@ -1239,6 +1251,7 @@ const QUuid SpatiallyNestable::findAncestorOfType(NestableType nestableType) con } } + bool success; SpatiallyNestablePointer parent = getParentPointer(success); if (!success || !parent) { return QUuid(); @@ -1248,7 +1261,7 @@ const QUuid SpatiallyNestable::findAncestorOfType(NestableType nestableType) con return parent->getID(); } - return parent->findAncestorOfType(nestableType); + return parent->findAncestorOfType(nestableType, depth + 1); } void SpatiallyNestable::getLocalTransformAndVelocities( @@ -1336,7 +1349,12 @@ void SpatiallyNestable::dump(const QString& prefix) const { } } -bool SpatiallyNestable::isParentPathComplete() const { +bool SpatiallyNestable::isParentPathComplete(int depth) const { + if (depth > MAX_PARENTING_CHAIN_SIZE) { + breakParentingLoop(); + return false; + } + static const QUuid IDENTITY; QUuid parentID = getParentID(); if (parentID.isNull() || parentID == IDENTITY) { @@ -1349,5 +1367,5 @@ bool SpatiallyNestable::isParentPathComplete() const { return false; } - return parent->isParentPathComplete(); + return parent->isParentPathComplete(depth + 1); } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 03ed97afbd..aafcfa10eb 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -75,7 +75,7 @@ public: static QString nestableTypeToString(NestableType nestableType); - virtual bool isParentPathComplete() const; + virtual bool isParentPathComplete(int depth = 0) const; // world frame @@ -187,8 +187,8 @@ public: bool isParentIDValid() const { bool success = false; getParentPointer(success); return success; } virtual SpatialParentTree* getParentTree() const { return nullptr; } - bool hasAncestorOfType(NestableType nestableType) const; - const QUuid findAncestorOfType(NestableType nestableType) const; + bool hasAncestorOfType(NestableType nestableType, int depth = 0) const; + const QUuid findAncestorOfType(NestableType nestableType, int depth = 0) const; SpatiallyNestablePointer getParentPointer(bool& success) const; static SpatiallyNestablePointer findByID(QUuid id, bool& success); @@ -246,6 +246,8 @@ private: mutable bool _parentKnowsMe { false }; bool _isDead { false }; bool _queryAACubeIsPuffed { false }; + + void breakParentingLoop() const; };