mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 20:34:07 +02:00
Merge pull request #11009 from AndrewMeadows/fix-QueryAACube
update EntityItem bounding cube when on changed dimensions
This commit is contained in:
commit
d572510770
10 changed files with 86 additions and 75 deletions
|
@ -613,7 +613,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
MovingEntitiesOperator moveOperator(entityTree);
|
||||
forEachDescendant([&](SpatiallyNestablePointer object) {
|
||||
// if the queryBox has changed, tell the entity-server
|
||||
if (object->computePuffedQueryAACube() && object->getNestableType() == NestableType::Entity) {
|
||||
if (object->getNestableType() == NestableType::Entity && object->checkAndMaybeUpdateQueryAACube()) {
|
||||
EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object);
|
||||
bool success;
|
||||
AACube newCube = entity->getQueryAACube(success);
|
||||
|
|
|
@ -1355,8 +1355,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lastEditedBy, setLastEditedBy);
|
||||
|
||||
AACube saveQueryAACube = _queryAACube;
|
||||
checkAndAdjustQueryAACube();
|
||||
if (saveQueryAACube != _queryAACube) {
|
||||
if (checkAndMaybeUpdateQueryAACube() && saveQueryAACube != _queryAACube) {
|
||||
somethingChanged = true;
|
||||
}
|
||||
|
||||
|
@ -1424,26 +1423,20 @@ void EntityItem::setDimensions(const glm::vec3& value) {
|
|||
///
|
||||
AACube EntityItem::getMaximumAACube(bool& success) const {
|
||||
if (_recalcMaxAACube) {
|
||||
// * we know that the position is the center of rotation
|
||||
glm::vec3 centerOfRotation = getPosition(success); // also where _registration point is
|
||||
if (success) {
|
||||
_recalcMaxAACube = false;
|
||||
// * we know that the registration point is the center of rotation
|
||||
// * we can calculate the length of the furthest extent from the registration point
|
||||
// as the dimensions * max (registrationPoint, (1.0,1.0,1.0) - registrationPoint)
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::vec3 registrationPoint = (dimensions * _registrationPoint);
|
||||
glm::vec3 registrationRemainder = (dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint));
|
||||
glm::vec3 furthestExtentFromRegistration = glm::max(registrationPoint, registrationRemainder);
|
||||
// we want to compute the furthestExtent that an entity can extend out from its "position"
|
||||
// to do this we compute the max of these two vec3s: registration and 1-registration
|
||||
// and then scale by dimensions
|
||||
glm::vec3 maxExtents = getDimensions() * glm::max(_registrationPoint, glm::vec3(1.0f) - _registrationPoint);
|
||||
|
||||
// * we know that if you rotate in any direction you would create a sphere
|
||||
// that has a radius of the length of furthest extent from registration point
|
||||
float radius = glm::length(furthestExtentFromRegistration);
|
||||
// there exists a sphere that contains maxExtents for all rotations
|
||||
float radius = glm::length(maxExtents);
|
||||
|
||||
// * we know that the minimum bounding cube of this maximum possible sphere is
|
||||
// (center - radius) to (center + radius)
|
||||
// put a cube around the sphere
|
||||
// TODO? replace _maxAACube with _boundingSphereRadius
|
||||
glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius);
|
||||
|
||||
_maxAACube = AACube(minimumCorner, radius * 2.0f);
|
||||
}
|
||||
} else {
|
||||
|
@ -1635,6 +1628,8 @@ void EntityItem::updateDimensions(const glm::vec3& value) {
|
|||
if (getDimensions() != value) {
|
||||
setDimensions(value);
|
||||
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||
_queryAACubeSet = false;
|
||||
dimensionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2157,12 +2157,17 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
return out;
|
||||
}
|
||||
|
||||
bool EntityItemProperties::parentDependentPropertyChanged() const {
|
||||
return localPositionChanged() || positionChanged() ||
|
||||
localRotationChanged() || rotationChanged() ||
|
||||
localVelocityChanged() || localAngularVelocityChanged();
|
||||
bool EntityItemProperties::transformChanged() const {
|
||||
return positionChanged() || rotationChanged() ||
|
||||
localPositionChanged() || localRotationChanged();
|
||||
}
|
||||
|
||||
bool EntityItemProperties::parentRelatedPropertyChanged() const {
|
||||
return parentDependentPropertyChanged() || parentIDChanged() || parentJointIndexChanged();
|
||||
return positionChanged() || rotationChanged() ||
|
||||
localPositionChanged() || localRotationChanged() ||
|
||||
parentIDChanged() || parentJointIndexChanged();
|
||||
}
|
||||
|
||||
bool EntityItemProperties::queryAACubeRelatedPropertyChanged() const {
|
||||
return parentRelatedPropertyChanged() || dimensionsChanged();
|
||||
}
|
||||
|
|
|
@ -86,8 +86,9 @@ public:
|
|||
|
||||
EntityPropertyFlags getChangedProperties() const;
|
||||
|
||||
bool parentDependentPropertyChanged() const; // was there a changed in a property that requires parent info to interpret?
|
||||
bool parentRelatedPropertyChanged() const; // parentDependentPropertyChanged or parentID or parentJointIndex
|
||||
bool transformChanged() const;
|
||||
bool parentRelatedPropertyChanged() const;
|
||||
bool queryAACubeRelatedPropertyChanged() const;
|
||||
|
||||
AABox getAABox() const;
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
|||
_entityTree->withWriteLock([&] {
|
||||
EntityItemPointer entity = _entityTree->addEntity(id, propertiesWithSimID);
|
||||
if (entity) {
|
||||
if (propertiesWithSimID.parentRelatedPropertyChanged()) {
|
||||
if (propertiesWithSimID.queryAACubeRelatedPropertyChanged()) {
|
||||
// due to parenting, the server may not know where something is in world-space, so include the bounding cube.
|
||||
bool success;
|
||||
AACube queryAACube = entity->getQueryAACube(success);
|
||||
|
@ -435,7 +435,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
|||
entity->rememberHasSimulationOwnershipBid();
|
||||
}
|
||||
}
|
||||
if (properties.parentRelatedPropertyChanged() && entity->computePuffedQueryAACube()) {
|
||||
if (properties.queryAACubeRelatedPropertyChanged()) {
|
||||
properties.setQueryAACube(entity->getQueryAACube());
|
||||
}
|
||||
entity->setLastBroadcast(usecTimestampNow());
|
||||
|
@ -445,7 +445,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
|||
// if they've changed.
|
||||
entity->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||
if (descendant->getNestableType() == NestableType::Entity) {
|
||||
if (descendant->computePuffedQueryAACube()) {
|
||||
if (descendant->checkAndMaybeUpdateQueryAACube()) {
|
||||
EntityItemPointer entityDescendant = std::static_pointer_cast<EntityItem>(descendant);
|
||||
EntityItemProperties newQueryCubeProperties;
|
||||
newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube());
|
||||
|
|
|
@ -1675,6 +1675,7 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
|
|||
addToNeedsParentFixupList(entity);
|
||||
}
|
||||
entity->forceQueryAACubeUpdate();
|
||||
entity->checkAndMaybeUpdateQueryAACube();
|
||||
moveOperator.addEntityToMoveList(entity, entity->getQueryAACube());
|
||||
i++;
|
||||
} else {
|
||||
|
@ -1693,7 +1694,7 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
|
|||
EntityItemPointer entity = localTree->findEntityByEntityItemID(newID);
|
||||
if (entity) {
|
||||
// queue the packet to send to the server
|
||||
entity->computePuffedQueryAACube();
|
||||
entity->updateQueryAACube();
|
||||
EntityItemProperties properties = entity->getProperties();
|
||||
properties.markAllChanged(); // so the entire property set is considered new, since we're making a new entity
|
||||
packetSender->queueEditEntityMessage(PacketType::EntityAdd, localTree, newID, properties);
|
||||
|
|
|
@ -136,7 +136,7 @@ void SimpleEntitySimulation::sortEntitiesThatMoved() {
|
|||
SetOfEntities::iterator itemItr = _entitiesToSort.begin();
|
||||
while (itemItr != _entitiesToSort.end()) {
|
||||
EntityItemPointer entity = *itemItr;
|
||||
entity->computePuffedQueryAACube();
|
||||
entity->checkAndMaybeUpdateQueryAACube();
|
||||
++itemItr;
|
||||
}
|
||||
EntitySimulation::sortEntitiesThatMoved();
|
||||
|
|
|
@ -484,11 +484,7 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (_entity->dynamicDataNeedsTransmit()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_entity->queryAABoxNeedsUpdate()) {
|
||||
if (_entity->dynamicDataNeedsTransmit() || _entity->queryAACubeNeedsUpdate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -577,9 +573,11 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
|||
properties.setActionData(_serverActionData);
|
||||
}
|
||||
|
||||
if (properties.parentRelatedPropertyChanged() && _entity->computePuffedQueryAACube()) {
|
||||
// due to parenting, the server may not know where something is in world-space, so include the bounding cube.
|
||||
properties.setQueryAACube(_entity->getQueryAACube());
|
||||
if (properties.transformChanged()) {
|
||||
if (_entity->checkAndMaybeUpdateQueryAACube()) {
|
||||
// due to parenting, the server may not know where something is in world-space, so include the bounding cube.
|
||||
properties.setQueryAACube(_entity->getQueryAACube());
|
||||
}
|
||||
}
|
||||
|
||||
// set the LastEdited of the properties but NOT the entity itself
|
||||
|
@ -643,7 +641,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
|||
_entity->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||
if (descendant->getNestableType() == NestableType::Entity) {
|
||||
EntityItemPointer entityDescendant = std::static_pointer_cast<EntityItem>(descendant);
|
||||
if (descendant->computePuffedQueryAACube()) {
|
||||
if (descendant->checkAndMaybeUpdateQueryAACube()) {
|
||||
EntityItemProperties newQueryCubeProperties;
|
||||
newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube());
|
||||
newQueryCubeProperties.setLastEdited(properties.getLastEdited());
|
||||
|
|
|
@ -946,11 +946,35 @@ AACube SpatiallyNestable::getMaximumAACube(bool& success) const {
|
|||
return AACube(getPosition(success) - glm::vec3(defaultAACubeSize / 2.0f), defaultAACubeSize);
|
||||
}
|
||||
|
||||
bool SpatiallyNestable::checkAndAdjustQueryAACube() {
|
||||
bool success;
|
||||
const float PARENTED_EXPANSION_FACTOR = 3.0f;
|
||||
|
||||
bool SpatiallyNestable::checkAndMaybeUpdateQueryAACube() {
|
||||
bool success = false;
|
||||
AACube maxAACube = getMaximumAACube(success);
|
||||
if (success && (!_queryAACubeSet || !_queryAACube.contains(maxAACube))) {
|
||||
setQueryAACube(maxAACube);
|
||||
if (success) {
|
||||
// maybe update _queryAACube
|
||||
if (!_queryAACubeSet || (_parentID.isNull() && _children.size() == 0) || !_queryAACube.contains(maxAACube)) {
|
||||
if (_parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) {
|
||||
// make an expanded AACube centered on the object
|
||||
float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale();
|
||||
_queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale);
|
||||
} else {
|
||||
_queryAACube = maxAACube;
|
||||
}
|
||||
|
||||
getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||
bool childSuccess;
|
||||
AACube descendantAACube = descendant->getQueryAACube(childSuccess);
|
||||
if (childSuccess) {
|
||||
if (_queryAACube.contains(descendantAACube)) {
|
||||
return;
|
||||
}
|
||||
_queryAACube += descendantAACube.getMinimumPoint();
|
||||
_queryAACube += descendantAACube.getMaximumPoint();
|
||||
}
|
||||
});
|
||||
_queryAACubeSet = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -961,46 +985,34 @@ void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) {
|
|||
return;
|
||||
}
|
||||
_queryAACube = queryAACube;
|
||||
if (queryAACube.getScale() > 0.0f) {
|
||||
_queryAACubeSet = true;
|
||||
}
|
||||
_queryAACubeSet = true;
|
||||
}
|
||||
|
||||
bool SpatiallyNestable::queryAABoxNeedsUpdate() const {
|
||||
bool success;
|
||||
AACube currentAACube = getMaximumAACube(success);
|
||||
if (!success) {
|
||||
qCDebug(shared) << "can't getMaximumAACube for" << getID();
|
||||
return false;
|
||||
bool SpatiallyNestable::queryAACubeNeedsUpdate() const {
|
||||
if (!_queryAACubeSet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// make sure children are still in their boxes, also.
|
||||
bool childNeedsUpdate = false;
|
||||
getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||
if (!childNeedsUpdate && descendant->queryAABoxNeedsUpdate()) {
|
||||
if (!childNeedsUpdate && descendant->queryAACubeNeedsUpdate()) {
|
||||
childNeedsUpdate = true;
|
||||
}
|
||||
});
|
||||
if (childNeedsUpdate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_queryAACubeSet && _queryAACube.contains(currentAACube)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return childNeedsUpdate;
|
||||
}
|
||||
|
||||
bool SpatiallyNestable::computePuffedQueryAACube() {
|
||||
if (!queryAABoxNeedsUpdate()) {
|
||||
return false;
|
||||
}
|
||||
void SpatiallyNestable::updateQueryAACube() {
|
||||
bool success;
|
||||
AACube currentAACube = getMaximumAACube(success);
|
||||
// make an AACube with edges thrice as long and centered on the object
|
||||
_queryAACube = AACube(currentAACube.getCorner() - glm::vec3(currentAACube.getScale()), currentAACube.getScale() * 3.0f);
|
||||
_queryAACubeSet = true;
|
||||
AACube maxAACube = getMaximumAACube(success);
|
||||
if (_parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) {
|
||||
// make an expanded AACube centered on the object
|
||||
float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale();
|
||||
_queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale);
|
||||
} else {
|
||||
_queryAACube = maxAACube;
|
||||
}
|
||||
|
||||
getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||
bool success;
|
||||
|
@ -1013,8 +1025,7 @@ bool SpatiallyNestable::computePuffedQueryAACube() {
|
|||
_queryAACube += descendantAACube.getMaximumPoint();
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
_queryAACubeSet = true;
|
||||
}
|
||||
|
||||
AACube SpatiallyNestable::getQueryAACube(bool& success) const {
|
||||
|
|
|
@ -102,11 +102,11 @@ public:
|
|||
virtual glm::vec3 getParentAngularVelocity(bool& success) const;
|
||||
|
||||
virtual AACube getMaximumAACube(bool& success) const;
|
||||
virtual bool checkAndAdjustQueryAACube();
|
||||
virtual bool computePuffedQueryAACube();
|
||||
bool checkAndMaybeUpdateQueryAACube();
|
||||
void updateQueryAACube();
|
||||
|
||||
virtual void setQueryAACube(const AACube& queryAACube);
|
||||
virtual bool queryAABoxNeedsUpdate() const;
|
||||
virtual bool queryAACubeNeedsUpdate() const;
|
||||
void forceQueryAACubeUpdate() { _queryAACubeSet = false; }
|
||||
virtual AACube getQueryAACube(bool& success) const;
|
||||
virtual AACube getQueryAACube() const;
|
||||
|
@ -197,7 +197,7 @@ protected:
|
|||
mutable QHash<QUuid, SpatiallyNestableWeakPointer> _children;
|
||||
|
||||
virtual void locationChanged(bool tellPhysics = true); // called when a this object's location has changed
|
||||
virtual void dimensionsChanged() { } // called when a this object's dimensions have changed
|
||||
virtual void dimensionsChanged() { _queryAACubeSet = false; } // called when a this object's dimensions have changed
|
||||
virtual void parentDeleted() { } // called on children of a deleted parent
|
||||
|
||||
// _queryAACube is used to decide where something lives in the octree
|
||||
|
|
Loading…
Reference in a new issue