mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 09:50:06 +02:00
fix but in getMyChildContaining and performance improvement to moving entities
This commit is contained in:
parent
446daa81a5
commit
0acbefb6a2
6 changed files with 84 additions and 56 deletions
|
@ -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) {
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue