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) {
bool wantDebug = true;
bool wantDebug = false;
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
//
#include <PerfStat.h>
#include "EntityTree.h"
#include "AddEntityOperator.h"
@ -618,48 +620,54 @@ void EntityTree::updateChangingEntities(quint64 now, QSet<EntityItemID>& entitie
}
void EntityTree::updateMovingEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete) {
PerformanceTimer perfTimer("updateMovingEntities");
if (_movingEntities.size() > 0) {
MovingEntitiesOperator moveOperator(this);
QSet<EntityItem*> entitiesBecomingStatic;
QSet<EntityItem*> entitiesBecomingMortal;
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);
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);
}

View file

@ -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);
}
}
}

View file

@ -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();
}
}

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 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) {

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 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
}