From 24fb43e8cde597dc77d694b964fc5955f96acf1b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Dec 2015 12:33:14 -0800 Subject: [PATCH] first steps toward a puffed-out query-box for child entities --- libraries/entities/src/AddEntityOperator.cpp | 2 +- .../src/BoundingBoxRelatedProperties.cpp | 83 ------------------- .../src/BoundingBoxRelatedProperties.h | 30 ------- libraries/entities/src/EntityItem.cpp | 14 ++++ libraries/entities/src/EntityItem.h | 2 + .../entities/src/EntityItemProperties.cpp | 31 ++----- libraries/entities/src/EntityItemProperties.h | 3 +- .../entities/src/EntityItemPropertiesMacros.h | 3 + libraries/entities/src/EntityPropertyFlags.h | 2 + libraries/entities/src/EntitySimulation.cpp | 4 +- libraries/entities/src/EntityTree.cpp | 12 ++- libraries/entities/src/EntityTreeElement.cpp | 10 +-- .../entities/src/UpdateEntityOperator.cpp | 7 +- libraries/entities/src/UpdateEntityOperator.h | 6 +- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + libraries/octree/src/OctreePacketData.cpp | 13 +++ libraries/octree/src/OctreePacketData.h | 4 + libraries/shared/src/GLMHelpers.cpp | 2 + libraries/shared/src/RegisteredMetaTypes.cpp | 22 ++++- libraries/shared/src/RegisteredMetaTypes.h | 5 ++ libraries/shared/src/SpatiallyNestable.cpp | 13 +++ libraries/shared/src/SpatiallyNestable.h | 10 ++- 23 files changed, 116 insertions(+), 165 deletions(-) delete mode 100644 libraries/entities/src/BoundingBoxRelatedProperties.cpp delete mode 100644 libraries/entities/src/BoundingBoxRelatedProperties.h diff --git a/libraries/entities/src/AddEntityOperator.cpp b/libraries/entities/src/AddEntityOperator.cpp index 2bfbbe2fd9..9fd1de74fe 100644 --- a/libraries/entities/src/AddEntityOperator.cpp +++ b/libraries/entities/src/AddEntityOperator.cpp @@ -25,7 +25,7 @@ AddEntityOperator::AddEntityOperator(EntityTreePointer tree, EntityItemPointer n // caller must have verified existence of newEntity assert(_newEntity); - _newEntityBox = _newEntity->getMaximumAACube().clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE); + _newEntityBox = _newEntity->getQueryAACube().clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE); } bool AddEntityOperator::preRecursion(OctreeElementPointer element) { diff --git a/libraries/entities/src/BoundingBoxRelatedProperties.cpp b/libraries/entities/src/BoundingBoxRelatedProperties.cpp deleted file mode 100644 index e9ee302300..0000000000 --- a/libraries/entities/src/BoundingBoxRelatedProperties.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// BoundingBoxRelatedProperties.cpp -// libraries/entities/src -// -// Created by Seth Alves on 2015-9-24 -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "EntityItemProperties.h" -#include "BoundingBoxRelatedProperties.h" -#include "EntityTree.h" - -BoundingBoxRelatedProperties::BoundingBoxRelatedProperties(EntityItemPointer entity) : - position(entity->getPosition()), - rotation(entity->getRotation()), - registrationPoint(entity->getRegistrationPoint()), - dimensions(entity->getDimensions()), - parentID(entity->getParentID()) { -} - -BoundingBoxRelatedProperties::BoundingBoxRelatedProperties(EntityItemPointer entity, - const EntityItemProperties& propertiesWithUpdates) : - BoundingBoxRelatedProperties(entity) { - - if (propertiesWithUpdates.parentIDChanged()) { - parentID = propertiesWithUpdates.getParentID(); - } - - bool parentFound = false; - if (parentID != UNKNOWN_ENTITY_ID) { - EntityTreePointer tree = entity->getTree(); - EntityItemPointer parentZone = tree->findEntityByID(parentID); - if (parentZone) { - parentFound = true; - glm::vec3 localPosition = propertiesWithUpdates.containsPositionChange() ? - propertiesWithUpdates.getPosition() : - entity->getLocalPosition(); - - glm::quat localRotation = propertiesWithUpdates.rotationChanged() ? - propertiesWithUpdates.getRotation() : - entity->getLocalOrientation(); - - const Transform parentTransform = parentZone->getTransformToCenter(); - Transform parentDescaled(parentTransform.getRotation(), glm::vec3(1.0f), parentTransform.getTranslation()); - - Transform localTransform(localRotation, glm::vec3(1.0f), localPosition); - Transform result; - Transform::mult(result, parentDescaled, localTransform); - position = result.getTranslation(); - rotation = result.getRotation(); - } - } - - if (!parentFound) { - if (propertiesWithUpdates.containsPositionChange()) { - position = propertiesWithUpdates.getPosition(); - } - if (propertiesWithUpdates.rotationChanged()) { - rotation = propertiesWithUpdates.getRotation(); - } - } - - if (propertiesWithUpdates.registrationPointChanged()) { - registrationPoint = propertiesWithUpdates.getRegistrationPoint(); - } - - if (propertiesWithUpdates.dimensionsChanged()) { - dimensions = propertiesWithUpdates.getDimensions(); - } -} - -AACube BoundingBoxRelatedProperties::getMaximumAACube() const { - // see EntityItem::getMaximumAACube for comments which explain the following. - glm::vec3 scaledRegistrationPoint = (dimensions * registrationPoint); - glm::vec3 registrationRemainder = (dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - registrationPoint)); - glm::vec3 furthestExtentFromRegistration = glm::max(scaledRegistrationPoint, registrationRemainder); - float radius = glm::length(furthestExtentFromRegistration); - glm::vec3 minimumCorner = position - glm::vec3(radius, radius, radius); - return AACube(minimumCorner, radius * 2.0f); -} diff --git a/libraries/entities/src/BoundingBoxRelatedProperties.h b/libraries/entities/src/BoundingBoxRelatedProperties.h deleted file mode 100644 index 811c885fd2..0000000000 --- a/libraries/entities/src/BoundingBoxRelatedProperties.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// BoundingBoxRelatedProperties.h -// libraries/entities/src -// -// Created by Seth Alves on 2015-9-24 -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "EntityItem.h" - -#ifndef hifi_BoundingBoxRelatedProperties_h -#define hifi_BoundingBoxRelatedProperties_h - -class BoundingBoxRelatedProperties { - public: - BoundingBoxRelatedProperties(EntityItemPointer entity); - BoundingBoxRelatedProperties(EntityItemPointer entity, const EntityItemProperties& propertiesWithUpdates); - AACube getMaximumAACube() const; - - glm::vec3 position; - glm::quat rotation; - glm::vec3 registrationPoint; - glm::vec3 dimensions; - EntityItemID parentID; -}; - -#endif // hifi_BoundingBoxRelatedProperties_h diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f74cdedb9d..70cecbc357 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -133,6 +133,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param requestedProperties += PROP_ACTION_DATA; requestedProperties += PROP_PARENT_ID; requestedProperties += PROP_PARENT_JOINT_INDEX; + requestedProperties += PROP_QUERY_AA_CUBE; return requestedProperties; } @@ -269,6 +270,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, getActionData()); APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, getParentID()); APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, getParentJointIndex()); + APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, getQueryAACube()); appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, @@ -693,6 +695,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_PARENT_ID, QUuid, setParentID); READ_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex); + READ_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, AACube, setQueryAACube); + bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, somethingChanged); @@ -1245,6 +1249,16 @@ const AABox& EntityItem::getAABox() const { return _cachedAABox; } +AACube EntityItem::getQueryAACube() const { + // XXX + if (!_queryAACubeSet) { + _queryAACube = getMaximumAACube(); + _queryAACubeSet = true; + } + return SpatiallyNestable::getQueryAACube(); +} + + // NOTE: This should only be used in cases of old bitstreams which only contain radius data // 0,0,0 --> maxDimension,maxDimension,maxDimension // ... has a corner to corner distance of glm::length(maxDimension,maxDimension,maxDimension) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index a1fc89c5e0..1b4d86850b 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -236,6 +236,8 @@ public: const AACube& getMinimumAACube() const; const AABox& getAABox() const; /// axis aligned bounding box in world-frame (meters) + virtual AACube getQueryAACube() const; + const QString& getScript() const { return _script; } void setScript(const QString& value) { _script = value; } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 2e785519da..d73308462f 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -262,6 +262,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID); CHECK_PROPERTY_CHANGE(PROP_PARENT_ID, parentID); CHECK_PROPERTY_CHANGE(PROP_PARENT_JOINT_INDEX, parentJointIndex); + CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube); changedProperties += _animation.getChangedProperties(); changedProperties += _keyLight.getChangedProperties(); @@ -477,6 +478,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_QUERY_AA_CUBE, queryAACube); + // FIXME - I don't think these properties are supported any more //COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel); //COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha); @@ -922,6 +925,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, properties.getDescription()); APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, properties.getParentID()); APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, properties.getParentJointIndex()); + APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, properties.getQueryAACube()); if (properties.getType() == EntityTypes::Web) { APPEND_ENTITY_PROPERTY(PROP_SOURCE_URL, properties.getSourceUrl()); @@ -1208,6 +1212,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DESCRIPTION, QString, setDescription); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_ID, QUuid, setParentID); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_QUERY_AA_CUBE, AACube, setQueryAACube); if (properties.getType() == EntityTypes::Web) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SOURCE_URL, QString, setSourceUrl); @@ -1462,32 +1467,6 @@ void EntityItemProperties::markAllChanged() { _parentJointIndexChanged = true; } -/// The maximum bounding cube for the entity, independent of it's rotation. -/// This accounts for the registration point (upon which rotation occurs around). -/// -AACube EntityItemProperties::getMaximumAACube() const { - // * we know that the position is the center of rotation - glm::vec3 centerOfRotation = _position; // also where _registration point is - - // * 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 registrationPoint = (_dimensions * _registrationPoint); - glm::vec3 registrationRemainder = (_dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint)); - glm::vec3 furthestExtentFromRegistration = glm::max(registrationPoint, registrationRemainder); - - // * 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); - - // * we know that the minimum bounding cube of this maximum possible sphere is - // (center - radius) to (center + radius) - glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius); - float diameter = radius * 2.0f; - - return AACube(minimumCorner, diameter); -} - // The minimum bounding box for the entity. AABox EntityItemProperties::getAABox() const { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index c13519996a..500f0d45db 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -85,7 +85,6 @@ public: bool parentDependentPropertyChanged() const; // was there a changed in a property that requires parent info to interpret? - AACube getMaximumAACube() const; AABox getAABox() const; void debugDump() const; @@ -193,6 +192,7 @@ public: DEFINE_PROPERTY_REF(PROP_Z_P_NEIGHBOR_ID, ZPNeighborID, zPNeighborID, EntityItemID, UNKNOWN_ENTITY_ID); DEFINE_PROPERTY_REF(PROP_PARENT_ID, ParentID, parentID, QUuid, UNKNOWN_ENTITY_ID); DEFINE_PROPERTY_REF(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, 0); + DEFINE_PROPERTY_REF(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube, AACube()); // these are used when bouncing location data into and out of scripts DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, glmVec3, ENTITY_ITEM_ZERO_VEC3); @@ -397,6 +397,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParentID, parentID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParentJointIndex, parentJointIndex, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, QueryAACube, queryAACube, ""); properties.getAnimation().debugDump(); properties.getAtmosphere().debugDump(); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 304e6f672c..2236245d26 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -122,6 +122,9 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) { inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) { return QScriptValue(QUuid(v).toString()); } +inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { return aaCubeToScriptValue(e, v); } + + #define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(X,G,g,P,p) \ if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \ diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 3bca911a56..ae0b0b4789 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -157,6 +157,8 @@ enum EntityPropertyList { PROP_LOCAL_POSITION, // only used to convert values to and from scripts PROP_LOCAL_ROTATION, // only used to convert values to and from scripts + PROP_QUERY_AA_CUBE, // how the EntityTree considers the size and position on an entity + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/EntitySimulation.cpp b/libraries/entities/src/EntitySimulation.cpp index 70b973e672..86536315b8 100644 --- a/libraries/entities/src/EntitySimulation.cpp +++ b/libraries/entities/src/EntitySimulation.cpp @@ -119,7 +119,7 @@ void EntitySimulation::sortEntitiesThatMoved() { while (itemItr != _entitiesToSort.end()) { EntityItemPointer entity = *itemItr; // check to see if this movement has sent the entity outside of the domain. - AACube newCube = entity->getMaximumAACube(); + AACube newCube = entity->getQueryAACube(); if (!domainBounds.touches(newCube)) { qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds."; _entitiesToDelete.insert(entity); @@ -200,7 +200,7 @@ void EntitySimulation::changeEntity(EntityItemPointer entity) { uint32_t dirtyFlags = entity->getDirtyFlags(); if (dirtyFlags & Simulation::DIRTY_POSITION) { AACube domainBounds(glm::vec3((float)-HALF_TREE_SCALE), (float)TREE_SCALE); - AACube newCube = entity->getMaximumAACube(); + AACube newCube = entity->getQueryAACube(); if (!domainBounds.touches(newCube)) { qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds."; _entitiesToDelete.insert(entity); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index ff7b9169ab..3873bad014 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -18,7 +18,7 @@ #include "VariantMapToScriptValue.h" #include "AddEntityOperator.h" -#include "MovingEntitiesOperator.h" +// #include "MovingEntitiesOperator.h" #include "UpdateEntityOperator.h" #include "QVariantGLM.h" #include "EntitiesLogging.h" @@ -142,9 +142,9 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI EntityItemProperties tempProperties; tempProperties.setLocked(wantsLocked); - BoundingBoxRelatedProperties newBBRelProperties(entity, tempProperties); - UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newBBRelProperties); + UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, entity->getQueryAACube()); recurseTreeWithOperator(&theOperator); + entity->setProperties(tempProperties); _isDirty = true; } @@ -211,8 +211,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI QString collisionSoundURLBefore = entity->getCollisionSoundURL(); uint32_t preFlags = entity->getDirtyFlags(); - BoundingBoxRelatedProperties newBBRelProperties(entity, properties); - UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newBBRelProperties); + UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, properties.getQueryAACube()); recurseTreeWithOperator(&theOperator); entity->setProperties(properties); @@ -226,10 +225,9 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI while (!toProcess.empty()) { EntityItemPointer childEntity = std::static_pointer_cast(toProcess.dequeue()); - BoundingBoxRelatedProperties newChildBBRelProperties(childEntity); UpdateEntityOperator theChildOperator(getThisPointer(), childEntity->getElement(), - childEntity, newChildBBRelProperties); + childEntity, childEntity->getQueryAACube()); recurseTreeWithOperator(&theChildOperator); foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) { if (childChild && childChild->getNestableType() == NestableType::Entity) { diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index ff2e97e8fe..7154e6fce0 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -302,7 +302,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData // simulation changing what's visible. consider the case where the entity contains an angular velocity // the entity may not be in view and then in view a frame later, let the client side handle it's view // frustum culling on rendering. - AACube entityCube = entity->getMaximumAACube(); + AACube entityCube = entity->getQueryAACube(); if (params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) { includeThisEntity = false; // out of view, don't include it } @@ -413,19 +413,19 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData } bool EntityTreeElement::containsEntityBounds(EntityItemPointer entity) const { - return containsBounds(entity->getMaximumAACube()); + return containsBounds(entity->getQueryAACube()); } bool EntityTreeElement::bestFitEntityBounds(EntityItemPointer entity) const { - return bestFitBounds(entity->getMaximumAACube()); + return bestFitBounds(entity->getQueryAACube()); } bool EntityTreeElement::containsBounds(const EntityItemProperties& properties) const { - return containsBounds(properties.getMaximumAACube()); + return containsBounds(properties.getQueryAACube()); } bool EntityTreeElement::bestFitBounds(const EntityItemProperties& properties) const { - return bestFitBounds(properties.getMaximumAACube()); + return bestFitBounds(properties.getQueryAACube()); } bool EntityTreeElement::containsBounds(const AACube& bounds) const { diff --git a/libraries/entities/src/UpdateEntityOperator.cpp b/libraries/entities/src/UpdateEntityOperator.cpp index 4acc386333..94599496b0 100644 --- a/libraries/entities/src/UpdateEntityOperator.cpp +++ b/libraries/entities/src/UpdateEntityOperator.cpp @@ -14,12 +14,11 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree, EntityTreeElementPointer containingElement, EntityItemPointer existingEntity, - const BoundingBoxRelatedProperties& newProperties) : + const AACube newQueryAACube) : _tree(tree), _existingEntity(existingEntity), _containingElement(containingElement), _containingElementCube(containingElement->getAACube()), - _newProperties(newProperties), _entityItemID(existingEntity->getEntityItemID()), _foundOld(false), _foundNew(false), @@ -41,13 +40,13 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree, // entity into the the element, or do we want to use the entities "relaxed" bounds // which can handle all potential rotations? // the getMaximumAACube is the relaxed form. - _oldEntityCube = _existingEntity->getMaximumAACube(); + _oldEntityCube = _existingEntity->getQueryAACube(); _oldEntityBox = _oldEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds // If our new properties don't have bounds details (no change to position, etc) or if this containing element would // be the best fit for our new properties, then just do the new portion of the store pass, since the change path will // be the same for both parts of the update - bool oldElementBestFit = _containingElement->bestFitBounds(newProperties.getMaximumAACube()); + bool oldElementBestFit = _containingElement->bestFitBounds(newQueryAACube); // For some reason we've seen a case where the original containing element isn't a best fit for the old properties // in this case we want to move it, even if the properties haven't changed. diff --git a/libraries/entities/src/UpdateEntityOperator.h b/libraries/entities/src/UpdateEntityOperator.h index aac442d415..12d90118e5 100644 --- a/libraries/entities/src/UpdateEntityOperator.h +++ b/libraries/entities/src/UpdateEntityOperator.h @@ -12,7 +12,7 @@ #ifndef hifi_UpdateEntityOperator_h #define hifi_UpdateEntityOperator_h -#include "BoundingBoxRelatedProperties.h" +// #include "BoundingBoxRelatedProperties.h" #include "EntitiesLogging.h" #include "EntityItem.h" #include "EntityItemProperties.h" @@ -22,7 +22,7 @@ class UpdateEntityOperator : public RecurseOctreeOperator { public: UpdateEntityOperator(EntityTreePointer tree, EntityTreeElementPointer containingElement, - EntityItemPointer existingEntity, const BoundingBoxRelatedProperties& newProperties); + EntityItemPointer existingEntity, const AACube newQueryAACube); ~UpdateEntityOperator(); @@ -34,7 +34,7 @@ private: EntityItemPointer _existingEntity; EntityTreeElementPointer _containingElement; AACube _containingElementCube; // we temporarily store our cube here in case we need to delete the containing element - BoundingBoxRelatedProperties _newProperties; + // BoundingBoxRelatedProperties _newProperties; EntityItemID _entityItemID; bool _foundOld; bool _foundNew; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 81aae796c1..090fd1ae5c 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -41,7 +41,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP; + return VERSION_ENTITITES_HAVE_QUERY_BOX; case PacketType::AvatarData: case PacketType::BulkAvatarData: return 17; diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index ba48c4ccf1..671d61f831 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -162,5 +162,6 @@ const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49; const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50; const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51; const PacketVersion VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52; +const PacketVersion VERSION_ENTITITES_HAVE_QUERY_BOX = 53; #endif // hifi_PacketHeaders_h diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 811e96fcf4..1f7c73bb1c 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -461,6 +461,10 @@ bool OctreePacketData::appendValue(const QByteArray& bytes) { return success; } +bool OctreePacketData::appendValue(const AACube& aaCube) { + bool success = appendValue(aaCube.getCorner()); + return success & appendValue(aaCube.getScale()); +} bool OctreePacketData::appendPosition(const glm::vec3& value) { const unsigned char* data = (const unsigned char*)&value; @@ -638,3 +642,12 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteA result = value; return sizeof(length) + length; } + +int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, AACube& result) { + glm::vec3 corner; + float scale; + int bytes = unpackDataFromBytes(dataBytes, corner); + bytes += unpackDataFromBytes(dataBytes + bytes, scale); + result = AACube(corner, scale); + return bytes; +} diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 2c86d518ad..8d7039e473 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -187,6 +187,9 @@ public: /// appends a QByteArray value to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const QByteArray& bytes); + /// appends an AACube value to the end of the stream, may fail if new data stream is too long to fit in packet + bool appendValue(const AACube& aaCube); + /// appends a position to the end of the stream, may fail if new data stream is too long to fit in packet bool appendPosition(const glm::vec3& value); @@ -253,6 +256,7 @@ public: static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result); + static int unpackDataFromBytes(const unsigned char* dataBytes, AACube& result); private: /// appends raw bytes, might fail if byte would cause packet to be too large diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 101412bbf7..221e613b8b 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -135,6 +135,8 @@ int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatO return sizeof(quatParts); } + + // Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's // http://www.geometrictools.com/Documentation/EulerAngles.pdf (via Clyde, // https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java) diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 008ac238d5..e55e74c691 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -42,7 +42,7 @@ void registerMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue); qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue); qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue); - + qScriptRegisterMetaType(engine, aaCubeToScriptValue, aaCubeFromScriptValue); } QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) { @@ -238,6 +238,26 @@ QScriptValue qColorToScriptValue(QScriptEngine* engine, const QColor& color) { return object; } +QScriptValue aaCubeToScriptValue(QScriptEngine* engine, const AACube& aaCube) { + QScriptValue obj = engine->newObject(); + const glm::vec3& corner = aaCube.getCorner(); + obj.setProperty("x", corner.x); + obj.setProperty("y", corner.y); + obj.setProperty("z", corner.z); + obj.setProperty("scale", aaCube.getScale()); + return obj; +} + +void aaCubeFromScriptValue(const QScriptValue &object, AACube& aaCube) { + glm::vec3 corner; + corner.x = object.property("x").toVariant().toFloat(); + corner.y = object.property("y").toVariant().toFloat(); + corner.z = object.property("z").toVariant().toFloat(); + float scale = object.property("scale").toVariant().toFloat(); + + aaCube.setBox(corner, scale); +} + void qColorFromScriptValue(const QScriptValue& object, QColor& color) { if (object.isNumber()) { color.setRgb(object.toUInt32()); diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index cd1e3b0d3e..61775a2762 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -18,6 +18,7 @@ #include #include +#include "AACube.h" #include "SharedUtil.h" class QColor; @@ -30,6 +31,7 @@ Q_DECLARE_METATYPE(glm::quat) Q_DECLARE_METATYPE(xColor) Q_DECLARE_METATYPE(QVector) Q_DECLARE_METATYPE(QVector) +Q_DECLARE_METATYPE(AACube) void registerMetaTypes(QScriptEngine* engine); @@ -67,6 +69,9 @@ QVector qVectorFloatFromScriptValue(const QScriptValue& array); QVector qVectorQUuidFromScriptValue(const QScriptValue& array); +QScriptValue aaCubeToScriptValue(QScriptEngine* engine, const AACube& aaCube); +void aaCubeFromScriptValue(const QScriptValue &object, AACube& aaCube); + class PickRay { public: PickRay() : origin(0.0f), direction(0.0f) { } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 6bd3e0d9fd..42b4c9ead3 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -385,3 +385,16 @@ void SpatiallyNestable::locationChanged() { object->locationChanged(); }); } + +void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { + _queryAACube = queryAACube; + _queryAACubeSet = true; +} + +AACube SpatiallyNestable::getQueryAACube() const { + if (!_queryAACubeSet) { + _queryAACube = AACube(getPosition() - glm::vec3(0.5f), 1.0f); // XXX + _queryAACubeSet = true; + } + return _queryAACube; +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 4a1808c6e0..8aa97ac77f 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -15,6 +15,7 @@ #include #include "Transform.h" +#include "AACube.h" #include "SpatialParentFinder.h" #include "shared/ReadWriteLockable.h" @@ -63,6 +64,9 @@ public: virtual glm::quat getOrientation(int jointIndex) const; virtual void setOrientation(const glm::quat& orientation); + virtual void setQueryAACube(const AACube& queryAACube); + virtual AACube getQueryAACube() const; + virtual glm::vec3 getScale() const; virtual void setScale(const glm::vec3& scale); @@ -91,7 +95,7 @@ public: virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const; virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { assert(false); return glm::quat(); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { assert(false); return glm::vec3(); } - + SpatiallyNestablePointer getThisPointer() const; protected: @@ -115,6 +119,10 @@ protected: void forEachChild(std::function actor); void forEachDescendant(std::function actor); + // _queryAACube is used to decide where something lives in the octree + mutable AACube _queryAACube; + mutable bool _queryAACubeSet { false }; + private: mutable ReadWriteLockable _transformLock; Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform.