diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 61e7b48976..a472e7ec39 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -252,7 +252,7 @@ int EntityItem::expectedBytes() { int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) { - bool wantDebug = true; + bool wantDebug = false; if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index e0071975a7..3a6fb70769 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "EntityTree.h" #include "AddEntityOperator.h" @@ -618,48 +620,54 @@ void EntityTree::updateChangingEntities(quint64 now, QSet& entitie } void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesToDelete) { + PerformanceTimer perfTimer("updateMovingEntities"); if (_movingEntities.size() > 0) { MovingEntitiesOperator moveOperator(this); QSet entitiesBecomingStatic; QSet entitiesBecomingMortal; QSet entitiesBecomingChanging; - - // TODO: switch these to iterators so we can remove items that get deleted - for (int i = 0; i < _movingEntities.size(); i++) { - EntityItem* thisEntity = _movingEntities[i]; - - // always check to see if the lifetime has expired, for immortal entities this is always false - if (thisEntity->lifetimeHasExpired()) { - qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID(); - entitiesToDelete << thisEntity->getEntityItemID(); - entitiesBecomingStatic << thisEntity; - } else { - AACube oldCube = thisEntity->getAACube(); - thisEntity->update(now); - AACube newCube = thisEntity->getAACube(); - // check to see if this movement has sent the entity outside of the domain. - AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), 1.0f); - if (!domainBounds.touches(newCube)) { + { + PerformanceTimer perfTimer("_movingEntities"); + + // TODO: switch these to iterators so we can remove items that get deleted + for (int i = 0; i < _movingEntities.size(); i++) { + EntityItem* thisEntity = _movingEntities[i]; + + // always check to see if the lifetime has expired, for immortal entities this is always false + if (thisEntity->lifetimeHasExpired()) { + qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID(); entitiesToDelete << thisEntity->getEntityItemID(); entitiesBecomingStatic << thisEntity; } else { - moveOperator.addEntityToMoveList(thisEntity, oldCube, newCube); - - // check to see if this entity is no longer moving - EntityItem::SimulationState newState = thisEntity->getSimulationState(); - if (newState == EntityItem::Changing) { - entitiesBecomingChanging << thisEntity; - } else if (newState == EntityItem::Mortal) { - entitiesBecomingMortal << thisEntity; - } else if (newState == EntityItem::Static) { + AACube oldCube = thisEntity->getAACube(); + thisEntity->update(now); + AACube newCube = thisEntity->getAACube(); + + // check to see if this movement has sent the entity outside of the domain. + AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), 1.0f); + if (!domainBounds.touches(newCube)) { + entitiesToDelete << thisEntity->getEntityItemID(); entitiesBecomingStatic << thisEntity; + } else { + moveOperator.addEntityToMoveList(thisEntity, oldCube, newCube); + + // check to see if this entity is no longer moving + EntityItem::SimulationState newState = thisEntity->getSimulationState(); + if (newState == EntityItem::Changing) { + entitiesBecomingChanging << thisEntity; + } else if (newState == EntityItem::Mortal) { + entitiesBecomingMortal << thisEntity; + } else if (newState == EntityItem::Static) { + entitiesBecomingStatic << thisEntity; + } } } } } if (moveOperator.hasMovingEntities()) { + PerformanceTimer perfTimer("recurseTreeWithOperator"); recurseTreeWithOperator(&moveOperator); } diff --git a/libraries/entities/src/MovingEntitiesOperator.cpp b/libraries/entities/src/MovingEntitiesOperator.cpp index d48a691de1..96e2abcb9b 100644 --- a/libraries/entities/src/MovingEntitiesOperator.cpp +++ b/libraries/entities/src/MovingEntitiesOperator.cpp @@ -29,17 +29,24 @@ MovingEntitiesOperator::~MovingEntitiesOperator() { void MovingEntitiesOperator::addEntityToMoveList(EntityItem* entity, const AACube& oldCube, const AACube& newCube) { - // check our tree, to determine if this entity is known - EntityToMoveDetails details; - details.oldContainingElement = _tree->getContainingElement(entity->getEntityItemID()); - details.entity = entity; - details.oldFound = false; - details.newFound = false; - details.oldCube = oldCube; - details.newCube = newCube; - details.newBox = newCube.clamp(0.0f, 1.0f); - _entitiesToMove << details; - _lookingCount++; + EntityTreeElement* oldContainingElement = _tree->getContainingElement(entity->getEntityItemID()); + AABox newBox = newCube.clamp(0.0f, 1.0f); + + // If the original containing element is the best fit for the requested newCube locations then + // we don't actually need to add the entity for moving and we can short circuit all this work + if (!oldContainingElement->bestFitBounds(newBox)) { + // check our tree, to determine if this entity is known + EntityToMoveDetails details; + details.oldContainingElement = oldContainingElement; + details.entity = entity; + details.oldFound = false; + details.newFound = false; + details.oldCube = oldCube; + details.newCube = newCube; + details.newBox = newBox; + _entitiesToMove << details; + _lookingCount++; + } } // does this entity tree element contain the old entity @@ -142,8 +149,7 @@ OctreeElement* MovingEntitiesOperator::PossiblyCreateChildAt(OctreeElement* elem // because if we need this branch for any one entity then it doesn't matter if it's // needed for more entities. if (childIndex == indexOfChildContainingNewEntity) { - OctreeElement* newChild = element->addChildAtIndex(childIndex); - return newChild; + return element->addChildAtIndex(childIndex); } } } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 992a168244..8e32a2f0c2 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -108,7 +108,8 @@ void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& " oneWayFlightTime: " << oneWayFlightTime << "\n" << " othersReplyTime: " << othersReplyTime << "\n" << " othersExprectedReply: " << othersExprectedReply << "\n" << - " clockSkew: " << clockSkew; + " clockSkew: " << clockSkew << "\n" << + " average clockSkew: " << sendingNode->getClockSkewUsec(); } } diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index 142ecb2aad..df24b663e2 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -1517,15 +1517,18 @@ int OctreeElement::getMyChildContaining(const AACube& cube) const { glm::vec3 cubeCornerMinimum = glm::clamp(cube.getCorner(), 0.0f, 1.0f); glm::vec3 cubeCornerMaximum = glm::clamp(cube.calcTopFarLeft(), 0.0f, 1.0f); - int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); - int childIndexCubeMaximum = getMyChildContainingPoint(cubeCornerMaximum); + if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) { + int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); + int childIndexCubeMaximum = getMyChildContainingPoint(cubeCornerMaximum); - // If the minimum and maximum corners of the cube are in two different children's cubes, then we are the containing element - if (childIndexCubeMinimum != childIndexCubeMaximum) { - return CHILD_UNKNOWN; - } + // If the minimum and maximum corners of the cube are in two different children's cubes, then we are the containing element + if (childIndexCubeMinimum != childIndexCubeMaximum) { + return CHILD_UNKNOWN; + } - return childIndexCubeMinimum; // either would do, they are the same + return childIndexCubeMinimum; // either would do, they are the same + } + return CHILD_UNKNOWN; // since cube is not contained in our element, it can't be in one of our children } int OctreeElement::getMyChildContaining(const AABox& box) const { @@ -1542,20 +1545,29 @@ int OctreeElement::getMyChildContaining(const AABox& box) const { glm::vec3 cubeCornerMinimum = box.getCorner(); glm::vec3 cubeCornerMaximum = box.calcTopFarLeft(); - int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); - int childIndexCubeMaximum = getMyChildContainingPoint(cubeCornerMaximum); + if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) { + int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); + int childIndexCubeMaximum = getMyChildContainingPoint(cubeCornerMaximum); - // If the minimum and maximum corners of the cube are in two different children's cubes, then we are the containing element - if (childIndexCubeMinimum != childIndexCubeMaximum) { - return CHILD_UNKNOWN; + // If the minimum and maximum corners of the cube are in two different children's cubes, + // then we are the containing element + if (childIndexCubeMinimum != childIndexCubeMaximum) { + return CHILD_UNKNOWN; + } + return childIndexCubeMinimum; // either would do, they are the same } - - return childIndexCubeMinimum; // either would do, they are the same + return CHILD_UNKNOWN; // since box is not contained in our element, it can't be in one of our children } int OctreeElement::getMyChildContainingPoint(const glm::vec3& point) const { glm::vec3 ourCenter = _cube.calcCenter(); int childIndex = CHILD_UNKNOWN; + + // since point is not contained in our element, it can't be in one of our children + if (!_cube.contains(point)) { + return CHILD_UNKNOWN; + } + // left half if (point.x > ourCenter.x) { if (point.y > ourCenter.y) { diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index e585c8dfe6..82a874a680 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -854,7 +854,8 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, const int MAX_RESONABLE_FLIGHT_TIME = 200 * USECS_PER_SECOND; // 200 seconds is more than enough time for a packet to arrive const int MIN_RESONABLE_FLIGHT_TIME = 0; if (flightTime > MAX_RESONABLE_FLIGHT_TIME || flightTime < MIN_RESONABLE_FLIGHT_TIME) { - qDebug() << "ignoring unreasonable packet... flightTime:" << flightTime; + qDebug() << "ignoring unreasonable packet... flightTime:" << flightTime + << " nodeClockSkewUsec:" << nodeClockSkewUsec << " usecs";; return; // ignore any packets that are unreasonable }