fix but in getMyChildContaining and performance improvement to moving entities

This commit is contained in:
ZappoMan 2014-09-03 08:06:42 -07:00
parent 446daa81a5
commit 0acbefb6a2
6 changed files with 84 additions and 56 deletions

View file

@ -252,7 +252,7 @@ int EntityItem::expectedBytes() {
int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) { 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) { if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) {

View file

@ -9,6 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <PerfStat.h>
#include "EntityTree.h" #include "EntityTree.h"
#include "AddEntityOperator.h" #include "AddEntityOperator.h"
@ -618,48 +620,54 @@ void EntityTree::updateChangingEntities(quint64 now, QSet<EntityItemID>& entitie
} }
void EntityTree::updateMovingEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete) { void EntityTree::updateMovingEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete) {
PerformanceTimer perfTimer("updateMovingEntities");
if (_movingEntities.size() > 0) { if (_movingEntities.size() > 0) {
MovingEntitiesOperator moveOperator(this); MovingEntitiesOperator moveOperator(this);
QSet<EntityItem*> entitiesBecomingStatic; QSet<EntityItem*> entitiesBecomingStatic;
QSet<EntityItem*> entitiesBecomingMortal; QSet<EntityItem*> entitiesBecomingMortal;
QSet<EntityItem*> entitiesBecomingChanging; QSet<EntityItem*> 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); PerformanceTimer perfTimer("_movingEntities");
if (!domainBounds.touches(newCube)) {
// 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(); entitiesToDelete << thisEntity->getEntityItemID();
entitiesBecomingStatic << thisEntity; entitiesBecomingStatic << thisEntity;
} else { } else {
moveOperator.addEntityToMoveList(thisEntity, oldCube, newCube); AACube oldCube = thisEntity->getAACube();
thisEntity->update(now);
// check to see if this entity is no longer moving AACube newCube = thisEntity->getAACube();
EntityItem::SimulationState newState = thisEntity->getSimulationState();
if (newState == EntityItem::Changing) { // check to see if this movement has sent the entity outside of the domain.
entitiesBecomingChanging << thisEntity; AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), 1.0f);
} else if (newState == EntityItem::Mortal) { if (!domainBounds.touches(newCube)) {
entitiesBecomingMortal << thisEntity; entitiesToDelete << thisEntity->getEntityItemID();
} else if (newState == EntityItem::Static) {
entitiesBecomingStatic << thisEntity; 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()) { if (moveOperator.hasMovingEntities()) {
PerformanceTimer perfTimer("recurseTreeWithOperator");
recurseTreeWithOperator(&moveOperator); recurseTreeWithOperator(&moveOperator);
} }

View file

@ -29,17 +29,24 @@ MovingEntitiesOperator::~MovingEntitiesOperator() {
void MovingEntitiesOperator::addEntityToMoveList(EntityItem* entity, const AACube& oldCube, const AACube& newCube) { void MovingEntitiesOperator::addEntityToMoveList(EntityItem* entity, const AACube& oldCube, const AACube& newCube) {
// check our tree, to determine if this entity is known EntityTreeElement* oldContainingElement = _tree->getContainingElement(entity->getEntityItemID());
EntityToMoveDetails details; AABox newBox = newCube.clamp(0.0f, 1.0f);
details.oldContainingElement = _tree->getContainingElement(entity->getEntityItemID());
details.entity = entity; // If the original containing element is the best fit for the requested newCube locations then
details.oldFound = false; // we don't actually need to add the entity for moving and we can short circuit all this work
details.newFound = false; if (!oldContainingElement->bestFitBounds(newBox)) {
details.oldCube = oldCube; // check our tree, to determine if this entity is known
details.newCube = newCube; EntityToMoveDetails details;
details.newBox = newCube.clamp(0.0f, 1.0f); details.oldContainingElement = oldContainingElement;
_entitiesToMove << details; details.entity = entity;
_lookingCount++; 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 // 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 // because if we need this branch for any one entity then it doesn't matter if it's
// needed for more entities. // needed for more entities.
if (childIndex == indexOfChildContainingNewEntity) { if (childIndex == indexOfChildContainingNewEntity) {
OctreeElement* newChild = element->addChildAtIndex(childIndex); return element->addChildAtIndex(childIndex);
return newChild;
} }
} }
} }

View file

@ -108,7 +108,8 @@ void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer&
" oneWayFlightTime: " << oneWayFlightTime << "\n" << " oneWayFlightTime: " << oneWayFlightTime << "\n" <<
" othersReplyTime: " << othersReplyTime << "\n" << " othersReplyTime: " << othersReplyTime << "\n" <<
" othersExprectedReply: " << othersExprectedReply << "\n" << " othersExprectedReply: " << othersExprectedReply << "\n" <<
" clockSkew: " << clockSkew; " clockSkew: " << clockSkew << "\n" <<
" average clockSkew: " << sendingNode->getClockSkewUsec();
} }
} }

View file

@ -1517,15 +1517,18 @@ int OctreeElement::getMyChildContaining(const AACube& cube) const {
glm::vec3 cubeCornerMinimum = glm::clamp(cube.getCorner(), 0.0f, 1.0f); glm::vec3 cubeCornerMinimum = glm::clamp(cube.getCorner(), 0.0f, 1.0f);
glm::vec3 cubeCornerMaximum = glm::clamp(cube.calcTopFarLeft(), 0.0f, 1.0f); glm::vec3 cubeCornerMaximum = glm::clamp(cube.calcTopFarLeft(), 0.0f, 1.0f);
int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) {
int childIndexCubeMaximum = getMyChildContainingPoint(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 the minimum and maximum corners of the cube are in two different children's cubes, then we are the containing element
if (childIndexCubeMinimum != childIndexCubeMaximum) { if (childIndexCubeMinimum != childIndexCubeMaximum) {
return CHILD_UNKNOWN; 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 { 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 cubeCornerMinimum = box.getCorner();
glm::vec3 cubeCornerMaximum = box.calcTopFarLeft(); glm::vec3 cubeCornerMaximum = box.calcTopFarLeft();
int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) {
int childIndexCubeMaximum = getMyChildContainingPoint(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 the minimum and maximum corners of the cube are in two different children's cubes,
if (childIndexCubeMinimum != childIndexCubeMaximum) { // then we are the containing element
return CHILD_UNKNOWN; if (childIndexCubeMinimum != childIndexCubeMaximum) {
return CHILD_UNKNOWN;
}
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
return childIndexCubeMinimum; // either would do, they are the same
} }
int OctreeElement::getMyChildContainingPoint(const glm::vec3& point) const { int OctreeElement::getMyChildContainingPoint(const glm::vec3& point) const {
glm::vec3 ourCenter = _cube.calcCenter(); glm::vec3 ourCenter = _cube.calcCenter();
int childIndex = CHILD_UNKNOWN; 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 // left half
if (point.x > ourCenter.x) { if (point.x > ourCenter.x) {
if (point.y > ourCenter.y) { if (point.y > ourCenter.y) {

View file

@ -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 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; const int MIN_RESONABLE_FLIGHT_TIME = 0;
if (flightTime > MAX_RESONABLE_FLIGHT_TIME || flightTime < MIN_RESONABLE_FLIGHT_TIME) { 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 return; // ignore any packets that are unreasonable
} }