From 6c033d9603576dcf0b24c570f63b17d42997e47f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 11 Dec 2015 11:35:42 -0800 Subject: [PATCH 01/54] call locationChanged when receiving changing avatar joints over the network. RenderableModelEntityItem uses locationChanged to relay updates to _model --- interface/src/avatar/Avatar.cpp | 3 +++ .../entities-renderer/src/RenderableModelEntityItem.cpp | 8 ++++++++ .../entities-renderer/src/RenderableModelEntityItem.h | 1 + libraries/entities/src/EntityTree.cpp | 8 ++++++++ libraries/render-utils/src/Model.cpp | 5 ++++- libraries/shared/src/SpatiallyNestable.cpp | 5 +++++ libraries/shared/src/SpatiallyNestable.h | 4 ++-- 7 files changed, 31 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 218d679898..499ce86afa 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -994,6 +994,9 @@ int Avatar::parseDataFromBuffer(const QByteArray& buffer) { if (_moving && _motionState) { _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); } + if (_moving || _hasNewJointRotations || _hasNewJointTranslations) { + locationChanged(); + } endUpdate(); return bytesRead; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index f2826db43f..3dcb86fc50 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -624,3 +624,11 @@ glm::vec3 RenderableModelEntityItem::getAbsoluteJointTranslationInObjectFrame(in } return glm::vec3(0.0f); } + +void RenderableModelEntityItem::locationChanged() { + EntityItem::locationChanged(); + if (_model && _model->isActive()) { + _model->setRotation(getRotation()); + _model->setTranslation(getPosition()); + } +} diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 0aaa7a0977..c53f8e04ea 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -73,6 +73,7 @@ public: virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; virtual void loader() override; + virtual void locationChanged() override; private: void remapTextures(); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 5090ebb7e0..ff7b9169ab 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -749,6 +749,14 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList= 0) { + QUuid value = properties.getParentID(); + changedProperties[index] = QString("parentID:") + value.toString(); + } + } } int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index e7c4442755..0d875ae789 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -95,6 +95,9 @@ const float METERS_PER_MILLIMETER = 0.01f; void Model::setScaleInternal(const glm::vec3& scale) { if (glm::distance(_scale, scale) > METERS_PER_MILLIMETER) { _scale = scale; + if (_scale.x == 0.0f || _scale.y == 0.0f || _scale.z == 0.0f) { + assert(false); + } initJointTransforms(); } } @@ -1210,7 +1213,7 @@ bool Model::initWhenReady(render::ScenePointer scene) { auto renderPayload = std::make_shared(renderItem); _renderItems.insert(item, renderPayload); pendingChanges.resetItem(item, renderPayload); - pendingChanges.updateItem(item, [&](MeshPartPayload& data) { + pendingChanges.updateItem(item, [=](MeshPartPayload& data) { data.updateTransform(transform, offset); data.notifyLocationChanged(); }); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 98d127cc1e..6bd3e0d9fd 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -99,6 +99,11 @@ void SpatiallyNestable::setParentID(const QUuid& parentID) { parentChanged(); } +void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) { + _parentJointIndex = parentJointIndex; +} + + glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex) { QSharedPointer parentFinder = DependencyManager::get(); Transform parentTransform; diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 7a43e2a563..4a1808c6e0 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -38,11 +38,11 @@ public: virtual const QUuid& getID() const { return _id; } virtual void setID(const QUuid& id) { _id = id; } - virtual const QUuid getParentID() const { return _parentID; } + virtual QUuid getParentID() const { return _parentID; } virtual void setParentID(const QUuid& parentID); virtual quint16 getParentJointIndex() const { return _parentJointIndex; } - virtual void setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; } + virtual void setParentJointIndex(quint16 parentJointIndex); static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex); static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex); From 24fb43e8cde597dc77d694b964fc5955f96acf1b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Dec 2015 12:33:14 -0800 Subject: [PATCH 02/54] 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. From 7f11d2a4fef193c600569b1a66610cdea7997531 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Dec 2015 14:45:02 -0800 Subject: [PATCH 03/54] whitespace --- libraries/entities/src/EntityTree.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 70d0860dd3..36f23edee2 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -18,7 +18,6 @@ #include "VariantMapToScriptValue.h" #include "AddEntityOperator.h" -// #include "MovingEntitiesOperator.h" #include "UpdateEntityOperator.h" #include "QVariantGLM.h" #include "EntitiesLogging.h" @@ -144,7 +143,6 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, entity->getQueryAACube()); recurseTreeWithOperator(&theOperator); - entity->setProperties(tempProperties); _isDirty = true; } From da7aed8666735f15db37dea8f6ca86dba83ac4a9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Dec 2015 14:48:07 -0800 Subject: [PATCH 04/54] use parenting for near-grabbing --- examples/controllers/handControllerGrab.js | 80 ++++++++-------------- 1 file changed, 28 insertions(+), 52 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 07894b46d1..92db768e55 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -90,6 +90,7 @@ var ZERO_VEC = { }; var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; +var NULL_PARENT_ID = "{00000000-0000-0000-000000000000}"; var MSEC_PER_SEC = 1000.0; // these control how long an abandoned pointer line or action will hang around @@ -261,9 +262,9 @@ function MyController(hand) { this.triggerValue = 0; // rolling average of trigger value this.rawTriggerValue = 0; this.rawBumperValue = 0; - + this.overlayLine = null; - + this.ignoreIK = false; this.offsetPosition = Vec3.ZERO; this.offsetRotation = Quat.IDENTITY; @@ -672,7 +673,9 @@ function MyController(hand) { } //this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - this.overlayLineOn(distantPickRay.origin, Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH)), NO_INTERSECT_COLOR); + this.overlayLineOn(distantPickRay.origin, + Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH)), + NO_INTERSECT_COLOR); }; this.distanceHolding = function() { @@ -696,7 +699,6 @@ function MyController(hand) { this.radiusScalar = 1.0; } - this.actionID = NULL_ACTION_ID; this.actionID = Entities.addAction("spring", this.grabbedEntity, { targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, @@ -879,41 +881,26 @@ function MyController(hand) { } this.actionID = NULL_ACTION_ID; - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: this.offsetPosition, - relativeRotation: this.offsetRotation, - ttl: ACTION_TTL, - kinematic: NEAR_GRABBING_KINEMATIC, - kinematicSetVelocity: true, - ignoreIK: this.ignoreIK + Entities.editEntity(this.grabbedEntity, { + parentID: MyAvatar.sessionUUID, + parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand") }); - if (this.actionID === NULL_ACTION_ID) { - this.actionID = null; + + if (this.state == STATE_NEAR_GRABBING) { + this.setState(STATE_CONTINUE_NEAR_GRABBING); } else { - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); - if (this.state == STATE_NEAR_GRABBING) { - this.setState(STATE_CONTINUE_NEAR_GRABBING); - } else { - // equipping - Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); - this.startHandGrasp(); - - this.setState(STATE_CONTINUE_EQUIP_BD); - } - - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - - Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); - - Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); - + // equipping + Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); + this.startHandGrasp(); + this.setState(STATE_CONTINUE_EQUIP_BD); } + if (this.hand === RIGHT_HAND) { + Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); + } else { + Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); + } + Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); + Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); this.currentHandControllerTipPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition; @@ -961,21 +948,6 @@ function MyController(hand) { if (this.state === STATE_CONTINUE_EQUIP_BD) { Entities.callEntityMethod(this.grabbedEntity, "continueEquip"); } - - if (this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) { - // if less than a 5 seconds left, refresh the actions ttl - Entities.updateAction(this.grabbedEntity, this.actionID, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: this.offsetPosition, - relativeRotation: this.offsetRotation, - ttl: ACTION_TTL, - kinematic: NEAR_GRABBING_KINEMATIC, - kinematicSetVelocity: true, - ignoreIK: this.ignoreIK - }); - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); - } }; this.waitingForBumperRelease = function() { @@ -1187,6 +1159,11 @@ function MyController(hand) { if (this.actionID !== null) { Entities.deleteAction(this.grabbedEntity, this.actionID); } + + Entities.editEntity(this.grabbedEntity, { + parentID: NULL_PARENT_ID, + parentJointIndex: 0 + }); } this.deactivateEntity(this.grabbedEntity); @@ -1315,7 +1292,6 @@ function update() { Messages.subscribe('Hifi-Hand-Disabler'); handleHandDisablerMessages = function(channel, message, sender) { - if (sender === MyAvatar.sessionUUID) { if (message === 'left') { handToDisable = LEFT_HAND; From 076e2b73a1ff9ce81474a90065eeb0c5fde99286 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Dec 2015 06:44:06 -0800 Subject: [PATCH 05/54] make AABox encoder and decode safer --- libraries/octree/src/OctreePacketData.cpp | 26 ++++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 1f7c73bb1c..a66ae840c0 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -23,6 +23,11 @@ AtomicUIntStat OctreePacketData::_totalBytesOfValues { 0 }; AtomicUIntStat OctreePacketData::_totalBytesOfPositions { 0 }; AtomicUIntStat OctreePacketData::_totalBytesOfRawData { 0 }; +struct aaCubeData { + glm::vec3 corner; + float scale; +}; + OctreePacketData::OctreePacketData(bool enableCompression, int targetSize) { changeSettings(enableCompression, targetSize); // does reset... } @@ -462,8 +467,15 @@ bool OctreePacketData::appendValue(const QByteArray& bytes) { } bool OctreePacketData::appendValue(const AACube& aaCube) { - bool success = appendValue(aaCube.getCorner()); - return success & appendValue(aaCube.getScale()); + aaCubeData cube { aaCube.getCorner(), aaCube.getScale() }; + const unsigned char* data = (const unsigned char*)&cube; + int length = sizeof(aaCubeData); + bool success = append(data, length); + if (success) { + _bytesOfValues += length; + _totalBytesOfValues += length; + } + return success; } bool OctreePacketData::appendPosition(const glm::vec3& value) { @@ -644,10 +656,8 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteA } 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; + aaCubeData cube; + memcpy(&cube, dataBytes, sizeof(aaCubeData)); + result = AACube(cube.corner, cube.scale); + return sizeof(aaCubeData); } From f3acec5177500730543a372025bfb25e0b3dcfa2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Dec 2015 06:44:15 -0800 Subject: [PATCH 06/54] whitespace --- libraries/shared/src/GLMHelpers.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 221e613b8b..101412bbf7 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -135,8 +135,6 @@ 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) From 270d5fc8e1facaa92bdab6b36ed4d3dfa8141640 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Dec 2015 06:44:34 -0800 Subject: [PATCH 07/54] remove commented-out code --- libraries/entities/src/UpdateEntityOperator.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/entities/src/UpdateEntityOperator.h b/libraries/entities/src/UpdateEntityOperator.h index 12d90118e5..5124075a6d 100644 --- a/libraries/entities/src/UpdateEntityOperator.h +++ b/libraries/entities/src/UpdateEntityOperator.h @@ -34,7 +34,6 @@ private: EntityItemPointer _existingEntity; EntityTreeElementPointer _containingElement; AACube _containingElementCube; // we temporarily store our cube here in case we need to delete the containing element - // BoundingBoxRelatedProperties _newProperties; EntityItemID _entityItemID; bool _foundOld; bool _foundNew; From c74f8bca491ba7432318cee58394053b175b40f0 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 14 Dec 2015 09:13:36 -0800 Subject: [PATCH 08/54] location getters also return a success boolean so that callers can know if the value they are receiving is bad due to lack of information about an object's parent --- .../src/entities/AssignmentParentFinder.cpp | 7 +- .../src/entities/AssignmentParentFinder.h | 2 +- interface/src/InterfaceParentFinder.h | 2 +- interface/src/avatar/Avatar.h | 2 + libraries/avatars/src/AvatarData.cpp | 17 +- libraries/avatars/src/AvatarData.h | 2 + .../src/EntityTreeRenderer.cpp | 7 +- .../src/RenderableBoxEntityItem.cpp | 10 +- .../src/RenderableEntityItem.cpp | 7 +- .../src/RenderableModelEntityItem.cpp | 16 +- .../RenderableParticleEffectEntityItem.cpp | 13 +- .../src/RenderablePolyVoxEntityItem.cpp | 13 +- .../src/RenderableSphereEntityItem.cpp | 6 +- .../src/RenderableTextEntityItem.cpp | 8 +- .../src/RenderableWebEntityItem.cpp | 6 +- .../src/RenderableZoneEntityItem.cpp | 13 +- libraries/entities/src/AddEntityOperator.cpp | 9 +- libraries/entities/src/EntityItem.cpp | 100 +++--- libraries/entities/src/EntityItem.h | 18 +- .../entities/src/EntityScriptingInterface.cpp | 14 +- libraries/entities/src/EntitySimulation.cpp | 10 +- libraries/entities/src/EntityTree.cpp | 19 +- libraries/entities/src/EntityTreeElement.cpp | 63 ++-- libraries/entities/src/SphereEntityItem.cpp | 6 +- libraries/shared/src/SpatialParentFinder.h | 2 +- libraries/shared/src/SpatiallyNestable.cpp | 304 +++++++++++++----- libraries/shared/src/SpatiallyNestable.h | 32 +- 27 files changed, 506 insertions(+), 202 deletions(-) diff --git a/assignment-client/src/entities/AssignmentParentFinder.cpp b/assignment-client/src/entities/AssignmentParentFinder.cpp index 5fe4742b90..fbcaba84ae 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.cpp +++ b/assignment-client/src/entities/AssignmentParentFinder.cpp @@ -11,9 +11,14 @@ #include "AssignmentParentFinder.h" -SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID) const { +SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID, bool& success) const { SpatiallyNestableWeakPointer parent; // search entities parent = _tree->findEntityByEntityItemID(parentID); + if (parent.lock()) { + success = true; + } else { + success = false; + } return parent; } diff --git a/assignment-client/src/entities/AssignmentParentFinder.h b/assignment-client/src/entities/AssignmentParentFinder.h index 99fa58ffed..9a776bc7dd 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.h +++ b/assignment-client/src/entities/AssignmentParentFinder.h @@ -25,7 +25,7 @@ class AssignmentParentFinder : public SpatialParentFinder { public: AssignmentParentFinder(EntityTreePointer tree) : _tree(tree) { } virtual ~AssignmentParentFinder() { } - virtual SpatiallyNestableWeakPointer find(QUuid parentID) const; + virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const; protected: EntityTreePointer _tree; diff --git a/interface/src/InterfaceParentFinder.h b/interface/src/InterfaceParentFinder.h index c8e8d4ed9f..db579c2144 100644 --- a/interface/src/InterfaceParentFinder.h +++ b/interface/src/InterfaceParentFinder.h @@ -21,7 +21,7 @@ class InterfaceParentFinder : public SpatialParentFinder { public: InterfaceParentFinder() { } virtual ~InterfaceParentFinder() { } - virtual SpatiallyNestableWeakPointer find(QUuid parentID) const; + virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const; }; #endif // hifi_InterfaceParentFinder_h diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 09685c318e..6c5338414f 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -158,7 +158,9 @@ public: void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; } AvatarMotionState* getMotionState() { return _motionState; } + using SpatiallyNestable::setPosition; virtual void setPosition(const glm::vec3& position) override; + using SpatiallyNestable::setOrientation; virtual void setOrientation(const glm::quat& orientation) override; public slots: diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index d241df7e0e..76130f7136 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -93,7 +93,11 @@ void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { Transform trans; trans.setTranslation(position); trans.setRotation(orientation); - SpatiallyNestable::setTransform(trans); + bool success; + SpatiallyNestable::setTransform(trans, success); + if (!success) { + qDebug() << "Warning -- AvatarData::nextAttitude failed"; + } avatarLock.unlock(); updateAttitude(); } @@ -211,8 +215,9 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { setAtBit(bitItems, IS_EYE_TRACKER_CONNECTED); } // referential state - SpatiallyNestablePointer parent = getParentPointer(); - if (parent) { + bool success; + SpatiallyNestablePointer parent = getParentPointer(success); + if (parent && success) { setAtBit(bitItems, HAS_REFERENTIAL); } *destinationBuffer++ = bitItems; @@ -1443,7 +1448,11 @@ QJsonObject AvatarData::toJson() const { } auto recordingBasis = getRecordingBasis(); - Transform avatarTransform = getTransform(); + bool success; + Transform avatarTransform = getTransform(success); + if (!success) { + qDebug() << "Warning -- AvatarData::toJson couldn't get avatar transform"; + } avatarTransform.setScale(getTargetScale()); if (recordingBasis) { root[JSON_AVATAR_BASIS] = Transform::toJson(*recordingBasis); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 1fa33ff606..c9a2286cb2 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -201,7 +201,9 @@ public: float getBodyRoll() const; void setBodyRoll(float bodyRoll); + using SpatiallyNestable::setPosition; virtual void setPosition(const glm::vec3& position) override; + using SpatiallyNestable::setOrientation; virtual void setOrientation(const glm::quat& orientation) override; void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index e3618d0e2a..3dc702f5dd 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -761,7 +761,12 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT // Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2) const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f; - const float stretchFactor = log(1.0f + (entity->getMinimumAACube().getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2); + bool success; + auto minAACube = entity->getMinimumAACube(success); + if (!success) { + return; + } + const float stretchFactor = log(1.0f + (minAACube.getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2); AudioInjector::playSound(collisionSoundURL, volume, stretchFactor, position); } diff --git a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp index 54fe491c46..7318177deb 100644 --- a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp @@ -56,14 +56,20 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { gpu::Batch& batch = *args->_batch; glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha()); + bool success; + auto transToCenter = getTransformToCenter(success); + if (!success) { + return; + } + if (_procedural->ready()) { - batch.setModelTransform(getTransformToCenter()); // we want to include the scale as well + batch.setModelTransform(transToCenter); // we want to include the scale as well _procedural->prepare(batch, getPosition(), getDimensions()); auto color = _procedural->getColor(cubeColor); batch._glColor4f(color.r, color.g, color.b, color.a); DependencyManager::get()->renderCube(batch); } else { - DependencyManager::get()->renderSolidCubeInstance(batch, getTransformToCenter(), cubeColor); + DependencyManager::get()->renderSolidCubeInstance(batch, transToCenter, cubeColor); } static const auto triCount = DependencyManager::get()->getCubeTriangleCount(); args->_details._trianglesRendered += triCount; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 5504268dce..25f4052c75 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -28,7 +28,12 @@ namespace render { template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload) { if (payload && payload->entity) { - return payload->entity->getAABox(); + bool success; + auto result = payload->entity->getAABox(success); + if (!success) { + return render::Item::Bound(); + } + return result; } return render::Item::Bound(); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 14e89b59fd..fc39297914 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -196,7 +196,12 @@ namespace render { template <> const Item::Bound payloadGetBound(const RenderableModelEntityItemMeta::Pointer& payload) { if (payload && payload->entity) { - return payload->entity->getAABox(); + bool success; + auto result = payload->entity->getAABox(success); + if (!success) { + return render::Item::Bound(); + } + return result; } return render::Item::Bound(); } @@ -338,9 +343,12 @@ void RenderableModelEntityItem::render(RenderArgs* args) { } else { static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f); gpu::Batch& batch = *args->_batch; - auto shapeTransform = getTransformToCenter(); - batch.setModelTransform(Transform()); // we want to include the scale as well - DependencyManager::get()->renderWireCubeInstance(batch, shapeTransform, greenColor); + bool success; + auto shapeTransform = getTransformToCenter(success); + if (success) { + batch.setModelTransform(Transform()); // we want to include the scale as well + DependencyManager::get()->renderWireCubeInstance(batch, shapeTransform, greenColor); + } } } diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 520069abdf..6b128d0810 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -235,10 +235,15 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { for (auto& particle : _particles) { particlePrimitives->emplace_back(particle.position, glm::vec2(particle.lifetime, particle.seed)); } - - auto bounds = getAABox(); - auto position = getPosition(); - auto rotation = getRotation(); + + bool successb, successp, successr; + auto bounds = getAABox(successb); + auto position = getPosition(successp); + auto rotation = getOrientation(successr); + bool success = successb && successp && successr; + if (!success) { + return; + } Transform transform; transform.setTranslation(position); transform.setRotation(rotation); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 10593a9e04..d798508ff6 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -135,9 +135,11 @@ glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const { glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const { glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units - glm::vec3 center = getCenterPosition(); - glm::vec3 position = getPosition(); + bool success; // XXX Does this actually have to happen in world space? + glm::vec3 center = getCenterPosition(success); + glm::vec3 position = getPosition(success); glm::vec3 positionToCenter = center - position; + positionToCenter -= getDimensions() * Vectors::HALF - getSurfacePositionAdjustment(); glm::mat4 centerToCorner = glm::translate(glm::mat4(), positionToCenter); glm::mat4 scaled = glm::scale(centerToCorner, scale); @@ -574,7 +576,12 @@ namespace render { template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload) { if (payload && payload->_owner) { auto polyVoxEntity = std::dynamic_pointer_cast(payload->_owner); - return polyVoxEntity->getAABox(); + bool success; + auto result = polyVoxEntity->getAABox(success); + if (!success) { + return render::Item::Bound(); + } + return result; } return render::Item::Bound(); } diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp index 8768e41a07..81a24c07a7 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp @@ -59,7 +59,11 @@ void RenderableSphereEntityItem::render(RenderArgs* args) { gpu::Batch& batch = *args->_batch; glm::vec4 sphereColor(toGlm(getXColor()), getLocalRenderAlpha()); - Transform modelTransform = getTransformToCenter(); + bool success; + Transform modelTransform = getTransformToCenter(success); + if (!success) { + return; + } modelTransform.postScale(SPHERE_ENTITY_SCALE); if (_procedural->ready()) { batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index bdf3b5b97c..d88b4d5f0a 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -44,8 +44,12 @@ void RenderableTextEntityItem::render(RenderArgs* args) { // Batch render calls Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - - Transform transformToTopLeft = getTransformToCenter(); + + bool success; + Transform transformToTopLeft = getTransformToCenter(success); + if (!success) { + return; + } if (getFaceCamera()) { //rotate about vertical to face the camera glm::vec3 dPosition = args->_viewFrustum->getPosition() - getPosition(); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 44a0740a4d..8aae853f5e 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -185,7 +185,11 @@ void RenderableWebEntityItem::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - batch.setModelTransform(getTransformToCenter()); + bool success; + batch.setModelTransform(getTransformToCenter(success)); + if (!success) { + return; + } bool textured = false, culled = false, emissive = false; if (_texture) { batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture); diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index ca16b3aca1..eb01bd551e 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -135,7 +135,11 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { gpu::Batch& batch = *args->_batch; batch.setModelTransform(Transform()); - auto shapeTransform = getTransformToCenter(); + bool success; + auto shapeTransform = getTransformToCenter(success); + if (!success) { + break; + } auto deferredLightingEffect = DependencyManager::get(); if (getShapeType() == SHAPE_TYPE_SPHERE) { shapeTransform.postScale(SPHERE_ENTITY_SCALE); @@ -190,7 +194,12 @@ namespace render { template <> const Item::Bound payloadGetBound(const RenderableZoneEntityItemMeta::Pointer& payload) { if (payload && payload->entity) { - return payload->entity->getAABox(); + bool success; + auto result = payload->entity->getAABox(success); + if (!success) { + return render::Item::Bound(); + } + return result; } return render::Item::Bound(); } diff --git a/libraries/entities/src/AddEntityOperator.cpp b/libraries/entities/src/AddEntityOperator.cpp index 9fd1de74fe..b11cec8e81 100644 --- a/libraries/entities/src/AddEntityOperator.cpp +++ b/libraries/entities/src/AddEntityOperator.cpp @@ -25,7 +25,14 @@ AddEntityOperator::AddEntityOperator(EntityTreePointer tree, EntityItemPointer n // caller must have verified existence of newEntity assert(_newEntity); - _newEntityBox = _newEntity->getQueryAACube().clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE); + bool success; + auto queryCube = _newEntity->getQueryAACube(success); + if (!success) { + // XXX put on a list for reprocessing? + qDebug() << "Warning -- AddEntityOperator failed to get queryAACube:" << _newEntity->getID(); + } + + _newEntityBox = queryCube.clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE); } bool AddEntityOperator::preRecursion(OctreeElementPointer element) { diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 70cecbc357..519ae5895f 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1156,8 +1156,8 @@ void EntityItem::recordCreationTime() { _lastSimulated = now; } -const Transform EntityItem::getTransformToCenter() const { - Transform result = getTransform(); +const Transform EntityItem::getTransformToCenter(bool& success) const { + Transform result = getTransform(success); if (getRegistrationPoint() != ENTITY_ITEM_HALF_VEC3) { // If it is not already centered, translate to center result.postTranslate(ENTITY_ITEM_HALF_VEC3 - getRegistrationPoint()); // Position to center } @@ -1175,28 +1175,29 @@ void EntityItem::setDimensions(const glm::vec3& value) { /// The maximum bounding cube for the entity, independent of it's rotation. /// This accounts for the registration point (upon which rotation occurs around). /// -const AACube& EntityItem::getMaximumAACube() const { +const AACube& EntityItem::getMaximumAACube(bool& success) const { if (_recalcMaxAACube) { // * we know that the position is the center of rotation - glm::vec3 centerOfRotation = getPosition(); // also where _registration point is + glm::vec3 centerOfRotation = getPosition(success); // also where _registration point is + if (success) { + // * 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 = (getDimensions() * getRegistrationPoint()); + glm::vec3 registrationRemainder = (getDimensions() * (glm::vec3(1.0f, 1.0f, 1.0f) - getRegistrationPoint())); + glm::vec3 furthestExtentFromRegistration = glm::max(registrationPoint, registrationRemainder); - // * 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 = (getDimensions() * getRegistrationPoint()); - glm::vec3 registrationRemainder = (getDimensions() * (glm::vec3(1.0f, 1.0f, 1.0f) - getRegistrationPoint())); - 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 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); - // * 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); - - _maxAACube = AACube(minimumCorner, radius * 2.0f); - _recalcMaxAACube = false; + _maxAACube = AACube(minimumCorner, radius * 2.0f); + _recalcMaxAACube = false; + } } return _maxAACube; } @@ -1204,7 +1205,7 @@ const AACube& EntityItem::getMaximumAACube() const { /// The minimum bounding cube for the entity accounting for it's rotation. /// This accounts for the registration point (upon which rotation occurs around). /// -const AACube& EntityItem::getMinimumAACube() const { +const AACube& EntityItem::getMinimumAACube(bool& success) const { if (_recalcMinAACube) { // _position represents the position of the registration point. glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; @@ -1212,25 +1213,28 @@ const AACube& EntityItem::getMinimumAACube() const { glm::vec3 unrotatedMinRelativeToEntity = - (getDimensions() * getRegistrationPoint()); glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder; Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; - Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); + Extents rotatedExtentsRelativeToRegistrationPoint = + unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); // shift the extents to be relative to the position/registration point - rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition()); + rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition(success)); - // the cube that best encompasses extents is... - AABox box(rotatedExtentsRelativeToRegistrationPoint); - glm::vec3 centerOfBox = box.calcCenter(); - float longestSide = box.getLargestDimension(); - float halfLongestSide = longestSide / 2.0f; - glm::vec3 cornerOfCube = centerOfBox - glm::vec3(halfLongestSide, halfLongestSide, halfLongestSide); + if (success) { + // the cube that best encompasses extents is... + AABox box(rotatedExtentsRelativeToRegistrationPoint); + glm::vec3 centerOfBox = box.calcCenter(); + float longestSide = box.getLargestDimension(); + float halfLongestSide = longestSide / 2.0f; + glm::vec3 cornerOfCube = centerOfBox - glm::vec3(halfLongestSide, halfLongestSide, halfLongestSide); - _minAACube = AACube(cornerOfCube, longestSide); - _recalcMinAACube = false; + _minAACube = AACube(cornerOfCube, longestSide); + _recalcMinAACube = false; + } } return _minAACube; } -const AABox& EntityItem::getAABox() const { +const AABox& EntityItem::getAABox(bool& success) const { if (_recalcAABox) { // _position represents the position of the registration point. glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; @@ -1238,24 +1242,26 @@ const AABox& EntityItem::getAABox() const { glm::vec3 unrotatedMinRelativeToEntity = - (getDimensions() * _registrationPoint); glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder; Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; - Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); + Extents rotatedExtentsRelativeToRegistrationPoint = + unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); // shift the extents to be relative to the position/registration point - rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition()); + rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition(success)); - _cachedAABox = AABox(rotatedExtentsRelativeToRegistrationPoint); - _recalcAABox = false; + if (success) { + _cachedAABox = AABox(rotatedExtentsRelativeToRegistrationPoint); + _recalcAABox = false; + } } return _cachedAABox; } -AACube EntityItem::getQueryAACube() const { - // XXX - if (!_queryAACubeSet) { - _queryAACube = getMaximumAACube(); - _queryAACubeSet = true; +AACube EntityItem::getQueryAACube(bool& success) const { + AACube result = getMaximumAACube(success); + if (success) { + return result; } - return SpatiallyNestable::getQueryAACube(); + return SpatiallyNestable::getQueryAACube(success); } @@ -1288,7 +1294,9 @@ float EntityItem::getRadius() const { bool EntityItem::contains(const glm::vec3& point) const { if (getShapeType() == SHAPE_TYPE_COMPOUND) { - return getAABox().contains(point); + bool success; + bool result = getAABox(success).contains(point); + return result & success; } else { ShapeInfo info; info.setParams(getShapeType(), glm::vec3(0.5f)); @@ -1831,6 +1839,14 @@ QList EntityItem::getActionsOfType(EntityActionType typeToG return result; } +glm::quat EntityItem::getAbsoluteJointRotationInObjectFrame(int index) const { + return glm::quat(); +} + +glm::vec3 EntityItem::getAbsoluteJointTranslationInObjectFrame(int index) const { + return glm::vec3(0.0f); +} + void EntityItem::locationChanged() { requiresRecalcBoxes(); SpatiallyNestable::locationChanged(); // tell all the children, also diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 1b4d86850b..1aebcba705 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -161,11 +161,10 @@ public: // attributes applicable to all entity types EntityTypes::EntityType getType() const { return _type; } - inline glm::vec3 getCenterPosition() const { return getTransformToCenter().getTranslation(); } + inline glm::vec3 getCenterPosition(bool& success) const { return getTransformToCenter(success).getTranslation(); } void setCenterPosition(const glm::vec3& position); - const Transform getTransformToCenter() const; - void setTranformToCenter(const Transform& transform); + const Transform getTransformToCenter(bool& success) const; inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; } @@ -232,11 +231,12 @@ public: quint64 getExpiry() const; // position, size, and bounds related helpers - const AACube& getMaximumAACube() const; - const AACube& getMinimumAACube() const; - const AABox& getAABox() const; /// axis aligned bounding box in world-frame (meters) + const AACube& getMaximumAACube(bool& success) const; + const AACube& getMinimumAACube(bool& success) const; + const AABox& getAABox(bool& success) const; /// axis aligned bounding box in world-frame (meters) - virtual AACube getQueryAACube() const; + using SpatiallyNestable::getQueryAACube; + virtual AACube getQueryAACube(bool& success) const override; const QString& getScript() const { return _script; } void setScript(const QString& value) { _script = value; } @@ -381,8 +381,8 @@ public: QList getActionsOfType(EntityActionType typeToGet); // these are in the frame of this object - virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override { return glm::quat(); } - virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override { return glm::vec3(0.0f); } + virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; + virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; virtual void loader() {} // called indirectly when urls for geometry are updated diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index a0a6719521..fbbf6dbef3 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -72,12 +72,15 @@ EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties scriptSideProperties.setLocalPosition(entitySideProperties.getPosition()); scriptSideProperties.setLocalRotation(entitySideProperties.getRotation()); + bool success; glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(), entitySideProperties.getParentID(), - entitySideProperties.getParentJointIndex()); + entitySideProperties.getParentJointIndex(), + success); glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(), entitySideProperties.getParentID(), - entitySideProperties.getParentJointIndex()); + entitySideProperties.getParentJointIndex(), + success); scriptSideProperties.setPosition(worldPosition); scriptSideProperties.setRotation(worldRotation); @@ -89,13 +92,15 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti // convert position and rotation properties from world-space to local, unless localPosition and localRotation // are set. If they are set, they overwrite position and rotation. EntityItemProperties entitySideProperties = scriptSideProperties; + bool success; if (scriptSideProperties.localPositionChanged()) { entitySideProperties.setPosition(scriptSideProperties.getLocalPosition()); } else if (scriptSideProperties.positionChanged()) { glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(), entitySideProperties.getParentID(), - entitySideProperties.getParentJointIndex()); + entitySideProperties.getParentJointIndex(), + success); entitySideProperties.setPosition(localPosition); } @@ -104,7 +109,8 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti } else if (scriptSideProperties.rotationChanged()) { glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(), entitySideProperties.getParentID(), - entitySideProperties.getParentJointIndex()); + entitySideProperties.getParentJointIndex(), + success); entitySideProperties.setRotation(localRotation); } diff --git a/libraries/entities/src/EntitySimulation.cpp b/libraries/entities/src/EntitySimulation.cpp index 86536315b8..ad354465d0 100644 --- a/libraries/entities/src/EntitySimulation.cpp +++ b/libraries/entities/src/EntitySimulation.cpp @@ -119,8 +119,9 @@ 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->getQueryAACube(); - if (!domainBounds.touches(newCube)) { + bool success; + AACube newCube = entity->getQueryAACube(success); + if (success && !domainBounds.touches(newCube)) { qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds."; _entitiesToDelete.insert(entity); _mortalEntities.remove(entity); @@ -200,8 +201,9 @@ 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->getQueryAACube(); - if (!domainBounds.touches(newCube)) { + bool success; + AACube newCube = entity->getQueryAACube(success); + if (success && !domainBounds.touches(newCube)) { qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds."; _entitiesToDelete.insert(entity); _mortalEntities.remove(entity); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 36f23edee2..6c2682c554 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -141,7 +141,12 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI EntityItemProperties tempProperties; tempProperties.setLocked(wantsLocked); - UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, entity->getQueryAACube()); + bool success; + AACube queryCube = entity->getQueryAACube(success); + if (!success) { + qCDebug(entities) << "Warning -- failed to get query-cube for" << entity->getID(); + } + UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, queryCube); recurseTreeWithOperator(&theOperator); entity->setProperties(tempProperties); _isDirty = true; @@ -230,9 +235,15 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI if (!containingElement) { continue; } - UpdateEntityOperator theChildOperator(getThisPointer(), - containingElement, - childEntity, childEntity->getQueryAACube()); + + bool success; + AACube queryCube = childEntity->getQueryAACube(success); + if (!success) { + qCDebug(entities) << "Can't update child -- failed to get query-cube for" << childEntity->getID(); + // XXX put on a list for later checking? + } + + UpdateEntityOperator theChildOperator(getThisPointer(), containingElement, childEntity, queryCube); 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 7154e6fce0..77e2318bc8 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -302,8 +302,9 @@ 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->getQueryAACube(); - if (params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) { + bool success; + AACube entityCube = entity->getQueryAACube(success); + if (!success || params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) { includeThisEntity = false; // out of view, don't include it } } @@ -413,11 +414,21 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData } bool EntityTreeElement::containsEntityBounds(EntityItemPointer entity) const { - return containsBounds(entity->getQueryAACube()); + bool success; + auto queryCube = entity->getQueryAACube(success); + if (!success) { + return false; + } + return containsBounds(queryCube); } bool EntityTreeElement::bestFitEntityBounds(EntityItemPointer entity) const { - return bestFitBounds(entity->getQueryAACube()); + bool success; + auto queryCube = entity->getQueryAACube(success); + if (!success) { + return false; + } + return bestFitBounds(queryCube); } bool EntityTreeElement::containsBounds(const EntityItemProperties& properties) const { @@ -516,7 +527,8 @@ bool EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm:: bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, - const QVector& entityIdsToInclude, void** intersectedObject, bool precisionPicking, float distanceToElementCube) { + const QVector& entityIdsToInclude, void** intersectedObject, + bool precisionPicking, float distanceToElementCube) { // only called if we do intersect our bounding cube, but find if we actually intersect with entities... int entityNumber = 0; @@ -526,7 +538,12 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con return; } - AABox entityBox = entity->getAABox(); + bool success; + AABox entityBox = entity->getAABox(success); + if (!success) { + return; + } + float localDistance; BoxFace localFace; glm::vec3 localSurfaceNormal; @@ -631,11 +648,12 @@ EntityItemPointer EntityTreeElement::getClosestEntity(glm::vec3 position) const void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searchRadius, QVector& foundEntities) const { forEachEntity([&](EntityItemPointer entity) { - AABox entityBox = entity->getAABox(); + bool success; + AABox entityBox = entity->getAABox(success); // if the sphere doesn't intersect with our world frame AABox, we don't need to consider the more complex case glm::vec3 penetration; - if (entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) { + if (success && entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) { glm::vec3 dimensions = entity->getDimensions(); @@ -651,9 +669,12 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc // maximum bounding sphere, which is actually larger than our actual radius float entityTrueRadius = dimensions.x / 2.0f; - if (findSphereSpherePenetration(searchPosition, searchRadius, - entity->getCenterPosition(), entityTrueRadius, penetration)) { - foundEntities.push_back(entity); + bool success; + if (findSphereSpherePenetration(searchPosition, searchRadius, + entity->getCenterPosition(success), entityTrueRadius, penetration)) { + if (success) { + foundEntities.push_back(entity); + } } } else { // determine the worldToEntityMatrix that doesn't include scale because @@ -679,7 +700,8 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc void EntityTreeElement::getEntities(const AACube& cube, QVector& foundEntities) { forEachEntity([&](EntityItemPointer entity) { - AABox entityBox = entity->getAABox(); + bool success; + AABox entityBox = entity->getAABox(success); // FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better // FIXME - consider allowing the entity to determine penetration so that // entities could presumably dull actuall hull testing if they wanted to @@ -693,10 +715,10 @@ void EntityTreeElement::getEntities(const AACube& cube, QVector& foundEntities) { forEachEntity([&](EntityItemPointer entity) { - AABox entityBox = entity->getAABox(); + bool success; + AABox entityBox = entity->getAABox(success); // FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better // FIXME - consider allowing the entity to determine penetration so that // entities could presumably dull actuall hull testing if they wanted to @@ -718,10 +741,10 @@ void EntityTreeElement::getEntities(const AABox& box, QVector // test the triangles of the face against the box? // if translated search face triangle intersect target box // add to result - // + // // If the entities AABox touches the search cube then consider it to be found - if (entityBox.touches(box)) { + if (success && entityBox.touches(box)) { foundEntities.push_back(entity); } }); @@ -940,7 +963,11 @@ bool EntityTreeElement::pruneChildren() { void EntityTreeElement::expandExtentsToContents(Extents& extents) { withReadLock([&] { foreach(EntityItemPointer entity, _entityItems) { - extents.add(entity->getAABox()); + bool success; + AABox aaBox = entity->getAABox(success); + if (success) { + extents.add(aaBox); + } } }); } diff --git a/libraries/entities/src/SphereEntityItem.cpp b/libraries/entities/src/SphereEntityItem.cpp index 841b70aa56..7ad7b39f20 100644 --- a/libraries/entities/src/SphereEntityItem.cpp +++ b/libraries/entities/src/SphereEntityItem.cpp @@ -110,7 +110,11 @@ bool SphereEntityItem::findDetailedRayIntersection(const glm::vec3& origin, cons // then translate back to work coordinates glm::vec3 hitAt = glm::vec3(entityToWorldMatrix * glm::vec4(entityFrameHitAt, 1.0f)); distance = glm::distance(origin, hitAt); - surfaceNormal = glm::normalize(hitAt - getCenterPosition()); + bool success; + surfaceNormal = glm::normalize(hitAt - getCenterPosition(success)); + if (!success) { + return false; + } return true; } return false; diff --git a/libraries/shared/src/SpatialParentFinder.h b/libraries/shared/src/SpatialParentFinder.h index 936d497eae..9b49490fa5 100644 --- a/libraries/shared/src/SpatialParentFinder.h +++ b/libraries/shared/src/SpatialParentFinder.h @@ -31,7 +31,7 @@ public: SpatialParentFinder() { } virtual ~SpatialParentFinder() { } - virtual SpatiallyNestableWeakPointer find(QUuid parentID) const = 0; + virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const = 0; }; #endif // hifi_SpatialParentFinder_h diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 42b4c9ead3..7c25fc0ec8 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -24,21 +24,25 @@ SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) : _transform.setRotation(glm::quat()); } -Transform SpatiallyNestable::getParentTransform() const { +Transform SpatiallyNestable::getParentTransform(bool& success) const { Transform result; - SpatiallyNestablePointer parent = getParentPointer(); + SpatiallyNestablePointer parent = getParentPointer(success); + if (!success) { + return result; + } if (parent) { - Transform parentTransform = parent->getTransform(_parentJointIndex); - result = parentTransform.setScale(1.0f); + Transform parentTransform = parent->getTransform(_parentJointIndex, success); + result = parentTransform.setScale(1.0f); // TODO: scaling } return result; } -SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { +SpatiallyNestablePointer SpatiallyNestable::getParentPointer(bool& success) const { SpatiallyNestablePointer parent = _parent.lock(); if (!parent && _parentID.isNull()) { // no parent + success = true; return nullptr; } @@ -48,6 +52,7 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { parent->beParentOfChild(getThisPointer()); _parentKnowsMe = true; } + success = true; return parent; } @@ -63,9 +68,14 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { // we have a _parentID but no parent pointer, or our parent pointer was to the wrong thing QSharedPointer parentFinder = DependencyManager::get(); if (!parentFinder) { + success = false; return nullptr; } - _parent = parentFinder->find(_parentID); + _parent = parentFinder->find(_parentID, success); + if (!success) { + return nullptr; + } + parent = _parent.lock(); if (parent) { parent->beParentOfChild(thisPointer); @@ -73,7 +83,9 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { } if (parent || _parentID.isNull()) { - thisPointer->parentChanged(); + success = true; + } else { + success = false; } return parent; @@ -96,136 +108,245 @@ void SpatiallyNestable::setParentID(const QUuid& parentID) { _parentID = parentID; _parentKnowsMe = false; } - parentChanged(); } void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; } - -glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex) { +glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, + const QUuid& parentID, int parentJointIndex, + bool& success) { + Transform result; QSharedPointer parentFinder = DependencyManager::get(); - Transform parentTransform; - if (parentFinder) { - auto parentWP = parentFinder->find(parentID); - auto parent = parentWP.lock(); - if (parent) { - parentTransform = parent->getTransform(parentJointIndex); - parentTransform.setScale(1.0f); - } + if (!parentFinder) { + success = false; + return glm::vec3(0.0f); } + Transform parentTransform; + auto parentWP = parentFinder->find(parentID, success); + if (!success) { + return glm::vec3(0.0f); + } + + auto parent = parentWP.lock(); + if (!parentID.isNull() && !parent) { + success = false; + return glm::vec3(0.0f); + } + + if (parent) { + parentTransform = parent->getTransform(parentJointIndex, success); + if (!success) { + return glm::vec3(0.0f); + } + parentTransform.setScale(1.0f); // TODO: scale + } + success = true; + Transform positionTransform; positionTransform.setTranslation(position); Transform myWorldTransform; Transform::mult(myWorldTransform, parentTransform, positionTransform); - myWorldTransform.setTranslation(position); - Transform result; Transform::inverseMult(result, parentTransform, myWorldTransform); return result.getTranslation(); } -glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex) { +glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, + const QUuid& parentID, int parentJointIndex, + bool& success) { + Transform result; QSharedPointer parentFinder = DependencyManager::get(); - Transform parentTransform; - if (parentFinder) { - auto parentWP = parentFinder->find(parentID); - auto parent = parentWP.lock(); - if (parent) { - parentTransform = parent->getTransform(parentJointIndex); - parentTransform.setScale(1.0f); - } + if (!parentFinder) { + success = false; + return glm::quat(); } + Transform parentTransform; + auto parentWP = parentFinder->find(parentID, success); + if (!success) { + return glm::quat(); + } + + auto parent = parentWP.lock(); + if (!parentID.isNull() && !parent) { + success = false; + return glm::quat(); + } + + if (parent) { + parentTransform = parent->getTransform(parentJointIndex, success); + if (!success) { + return glm::quat(); + } + parentTransform.setScale(1.0f); // TODO: scale + } + success = true; + Transform orientationTransform; orientationTransform.setRotation(orientation); Transform myWorldTransform; Transform::mult(myWorldTransform, parentTransform, orientationTransform); myWorldTransform.setRotation(orientation); - Transform result; Transform::inverseMult(result, parentTransform, myWorldTransform); return result.getRotation(); } -glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex) { +glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, + const QUuid& parentID, int parentJointIndex, + bool& success) { + Transform result; QSharedPointer parentFinder = DependencyManager::get(); - Transform parentTransform; - if (parentFinder) { - auto parentWP = parentFinder->find(parentID); - auto parent = parentWP.lock(); - if (parent) { - parentTransform = parent->getTransform(parentJointIndex); - parentTransform.setScale(1.0f); - } + if (!parentFinder) { + success = false; + return glm::vec3(0.0f); } + + Transform parentTransform; + auto parentWP = parentFinder->find(parentID, success); + if (!success) { + return glm::vec3(0.0f); + } + + auto parent = parentWP.lock(); + if (!parentID.isNull() && !parent) { + success = false; + return glm::vec3(0.0f); + } + + if (parent) { + parentTransform = parent->getTransform(parentJointIndex, success); + if (!success) { + return glm::vec3(0.0f); + } + parentTransform.setScale(1.0f); // TODO: scale + } + success = true; + Transform positionTransform; positionTransform.setTranslation(position); - Transform result; Transform::mult(result, parentTransform, positionTransform); return result.getTranslation(); } -glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex) { +glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, + const QUuid& parentID, int parentJointIndex, + bool& success) { + Transform result; QSharedPointer parentFinder = DependencyManager::get(); - Transform parentTransform; - if (parentFinder) { - auto parentWP = parentFinder->find(parentID); - auto parent = parentWP.lock(); - if (parent) { - parentTransform = parent->getTransform(parentJointIndex); - parentTransform.setScale(1.0f); - } + if (!parentFinder) { + success = false; + return glm::quat(); } + + Transform parentTransform; + auto parentWP = parentFinder->find(parentID, success); + if (!success) { + return glm::quat(); + } + + auto parent = parentWP.lock(); + if (!parentID.isNull() && !parent) { + success = false; + return glm::quat(); + } + + if (parent) { + parentTransform = parent->getTransform(parentJointIndex, success); + if (!success) { + return glm::quat(); + } + parentTransform.setScale(1.0f); + } + success = true; + Transform orientationTransform; orientationTransform.setRotation(orientation); - Transform result; Transform::mult(result, parentTransform, orientationTransform); return result.getRotation(); } +glm::vec3 SpatiallyNestable::getPosition(bool& success) const { + return getTransform(success).getTranslation(); +} + glm::vec3 SpatiallyNestable::getPosition() const { - return getTransform().getTranslation(); + bool success; + auto result = getPosition(success); + if (!success) { + qDebug() << "Warning -- getPosition failed"; + } + return result; } -glm::vec3 SpatiallyNestable::getPosition(int jointIndex) const { - return getTransform(jointIndex).getTranslation(); +glm::vec3 SpatiallyNestable::getPosition(int jointIndex, bool& success) const { + return getTransform(jointIndex, success).getTranslation(); } -void SpatiallyNestable::setPosition(const glm::vec3& position) { - Transform parentTransform = getParentTransform(); +void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success) { + Transform parentTransform = getParentTransform(success); Transform myWorldTransform; _transformLock.withWriteLock([&] { Transform::mult(myWorldTransform, parentTransform, _transform); myWorldTransform.setTranslation(position); Transform::inverseMult(_transform, parentTransform, myWorldTransform); }); - locationChanged(); + if (success) { + locationChanged(); + } +} + +void SpatiallyNestable::setPosition(const glm::vec3& position) { + bool success; + setPosition(position, success); + if (!success) { + qDebug() << "Warning -- setPosition failed"; + } +} + +glm::quat SpatiallyNestable::getOrientation(bool& success) const { + return getTransform(success).getRotation(); } glm::quat SpatiallyNestable::getOrientation() const { - return getTransform().getRotation(); + bool success; + auto result = getOrientation(success); + if (!success) { + qDebug() << "Warning -- getOrientation failed"; + } + return result; } -glm::quat SpatiallyNestable::getOrientation(int jointIndex) const { - return getTransform(jointIndex).getRotation(); +glm::quat SpatiallyNestable::getOrientation(int jointIndex, bool& success) const { + return getTransform(jointIndex, success).getRotation(); } -void SpatiallyNestable::setOrientation(const glm::quat& orientation) { - Transform parentTransform = getParentTransform(); +void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& success) { + Transform parentTransform = getParentTransform(success); Transform myWorldTransform; _transformLock.withWriteLock([&] { Transform::mult(myWorldTransform, parentTransform, _transform); myWorldTransform.setRotation(orientation); Transform::inverseMult(_transform, parentTransform, myWorldTransform); }); - locationChanged(); + if (success) { + locationChanged(); + } } -const Transform SpatiallyNestable::getTransform() const { +void SpatiallyNestable::setOrientation(const glm::quat& orientation) { + bool success; + setOrientation(orientation, success); + if (!success) { + qDebug() << "Wanring -- setOrientation failed"; + } +} + +const Transform SpatiallyNestable::getTransform(bool& success) const { // return a world-space transform for this object's location - Transform parentTransform = getParentTransform(); + Transform parentTransform = getParentTransform(success); Transform result; _transformLock.withReadLock([&] { Transform::mult(result, parentTransform, _transform); @@ -233,25 +354,34 @@ const Transform SpatiallyNestable::getTransform() const { return result; } -const Transform SpatiallyNestable::getTransform(int jointIndex) const { +const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success) const { // this returns the world-space transform for this object. It finds its parent's transform (which may // cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it. - Transform worldTransform = getTransform(); - Transform jointInObjectFrame = getAbsoluteJointTransformInObjectFrame(jointIndex); Transform jointInWorldFrame; + + Transform worldTransform = getTransform(success); + if (!success) { + return jointInWorldFrame; + } + + Transform jointInObjectFrame = getAbsoluteJointTransformInObjectFrame(jointIndex); Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame); + success = true; return jointInWorldFrame; } -void SpatiallyNestable::setTransform(const Transform& transform) { - Transform parentTransform = getParentTransform(); +void SpatiallyNestable::setTransform(const Transform& transform, bool& success) { + Transform parentTransform = getParentTransform(success); _transformLock.withWriteLock([&] { Transform::inverseMult(_transform, parentTransform, transform); }); - locationChanged(); + if (success) { + locationChanged(); + } } glm::vec3 SpatiallyNestable::getScale() const { + // TODO: scale glm::vec3 result; _transformLock.withReadLock([&] { result = _transform.getScale(); @@ -260,11 +390,12 @@ glm::vec3 SpatiallyNestable::getScale() const { } glm::vec3 SpatiallyNestable::getScale(int jointIndex) const { - // XXX ... something with joints + // TODO: scale return getScale(); } void SpatiallyNestable::setScale(const glm::vec3& scale) { + // TODO: scale _transformLock.withWriteLock([&] { _transform.setScale(scale); }); @@ -317,6 +448,7 @@ void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) { } glm::vec3 SpatiallyNestable::getLocalScale() const { + // TODO: scale glm::vec3 result; _transformLock.withReadLock([&] { result = _transform.getScale(); @@ -325,6 +457,7 @@ glm::vec3 SpatiallyNestable::getLocalScale() const { } void SpatiallyNestable::setLocalScale(const glm::vec3& scale) { + // TODO: scale _transformLock.withWriteLock([&] { _transform.setScale(scale); }); @@ -353,6 +486,16 @@ const Transform SpatiallyNestable::getAbsoluteJointTransformInObjectFrame(int jo return jointTransformInObjectFrame; } +glm::quat SpatiallyNestable::getAbsoluteJointRotationInObjectFrame(int index) const { + assert(false); + return glm::quat(); +} + +glm::vec3 SpatiallyNestable::getAbsoluteJointTranslationInObjectFrame(int index) const { + assert(false); + return glm::vec3(); +} + SpatiallyNestablePointer SpatiallyNestable::getThisPointer() const { SpatiallyNestableConstPointer constThisPointer = shared_from_this(); SpatiallyNestablePointer thisPointer = std::const_pointer_cast(constThisPointer); // ermahgerd !!! @@ -391,10 +534,19 @@ void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { _queryAACubeSet = true; } -AACube SpatiallyNestable::getQueryAACube() const { - if (!_queryAACubeSet) { - _queryAACube = AACube(getPosition() - glm::vec3(0.5f), 1.0f); // XXX - _queryAACubeSet = true; +AACube SpatiallyNestable::getQueryAACube(bool& success) const { + if (_queryAACubeSet) { + success = true; + return _queryAACube; } - return _queryAACube; + return AACube(getPosition(success) - glm::vec3(0.5f), 1.0f); // XXX +} + +AACube SpatiallyNestable::getQueryAACube() const { + bool success; + auto result = getQueryAACube(success); + if (!success) { + qDebug() << "getQueryAACube failed:" << getID(); + } + return result; } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 8aa97ac77f..f61ac487fd 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -45,34 +45,39 @@ public: virtual quint16 getParentJointIndex() const { return _parentJointIndex; } virtual void setParentJointIndex(quint16 parentJointIndex); - static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex); - static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex); + static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success); + static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success); - static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex); - static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex); + static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success); + static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success); // world frame - virtual const Transform getTransform() const; - virtual void setTransform(const Transform& transform); + virtual const Transform getTransform(bool& success) const; + virtual void setTransform(const Transform& transform, bool& success); - virtual Transform getParentTransform() const; + virtual Transform getParentTransform(bool& success) const; + virtual glm::vec3 getPosition(bool& success) const; virtual glm::vec3 getPosition() const; + virtual void setPosition(const glm::vec3& position, bool& success); virtual void setPosition(const glm::vec3& position); + virtual glm::quat getOrientation(bool& success) const; virtual glm::quat getOrientation() const; - virtual glm::quat getOrientation(int jointIndex) const; + virtual glm::quat getOrientation(int jointIndex, bool& success) const; + virtual void setOrientation(const glm::quat& orientation, bool& success); virtual void setOrientation(const glm::quat& orientation); virtual void setQueryAACube(const AACube& queryAACube); + virtual AACube getQueryAACube(bool& success) const; virtual AACube getQueryAACube() const; virtual glm::vec3 getScale() const; virtual void setScale(const glm::vec3& scale); // get world-frame values for a specific joint - virtual const Transform getTransform(int jointIndex) const; - virtual glm::vec3 getPosition(int jointIndex) const; + virtual const Transform getTransform(int jointIndex, bool& success) const; + virtual glm::vec3 getPosition(int jointIndex, bool& success) const; virtual glm::vec3 getScale(int jointIndex) const; // object's parent's frame @@ -93,8 +98,8 @@ public: // this object's frame 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(); } + virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const; + virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const; SpatiallyNestablePointer getThisPointer() const; @@ -103,7 +108,7 @@ protected: QUuid _id; QUuid _parentID; // what is this thing's transform relative to? quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to? - SpatiallyNestablePointer getParentPointer() const; + SpatiallyNestablePointer getParentPointer(bool& success) const; mutable SpatiallyNestableWeakPointer _parent; virtual void beParentOfChild(SpatiallyNestablePointer newChild) const; @@ -112,7 +117,6 @@ protected: mutable ReadWriteLockable _childrenLock; mutable QHash _children; - virtual void parentChanged() {} // called when parent pointer is updated virtual void locationChanged(); // called when a this object's location has changed virtual void dimensionsChanged() {} // called when a this object's dimensions have changed From 165c41d8435bdf0ba0266dcf9c42e31bcb3af5b0 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 14 Dec 2015 14:19:19 -0800 Subject: [PATCH 09/54] add a way to remember which entities couldn't be properly placed in octree due to missing parents --- interface/src/InterfaceParentFinder.cpp | 17 +++++++--- libraries/entities/src/AddEntityOperator.cpp | 3 +- libraries/entities/src/EntityTree.cpp | 34 ++++++++++++++++++++ libraries/entities/src/EntityTree.h | 3 ++ libraries/shared/src/SpatiallyNestable.h | 5 +++ 5 files changed, 56 insertions(+), 6 deletions(-) diff --git a/interface/src/InterfaceParentFinder.cpp b/interface/src/InterfaceParentFinder.cpp index 112bae5bb8..de4b0ce38c 100644 --- a/interface/src/InterfaceParentFinder.cpp +++ b/interface/src/InterfaceParentFinder.cpp @@ -16,22 +16,31 @@ #include "InterfaceParentFinder.h" -SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID) const { +SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID, bool& success) const { SpatiallyNestableWeakPointer parent; if (parentID.isNull()) { + success = true; return parent; } // search entities EntityTreeRenderer* treeRenderer = qApp->getEntities(); - EntityTreePointer tree = treeRenderer->getTree(); - parent = tree->findEntityByEntityItemID(parentID); + EntityTreePointer tree = treeRenderer ? treeRenderer->getTree() : nullptr; + parent = tree ? tree->findEntityByEntityItemID(parentID) : nullptr; if (!parent.expired()) { + success = true; return parent; } // search avatars QSharedPointer avatarManager = DependencyManager::get(); - return avatarManager->getAvatarBySessionID(parentID); + parent = avatarManager->getAvatarBySessionID(parentID); + if (!parent.expired()) { + success = true; + return parent; + } + + success = false; + return parent; } diff --git a/libraries/entities/src/AddEntityOperator.cpp b/libraries/entities/src/AddEntityOperator.cpp index b11cec8e81..1c39b40495 100644 --- a/libraries/entities/src/AddEntityOperator.cpp +++ b/libraries/entities/src/AddEntityOperator.cpp @@ -28,8 +28,7 @@ AddEntityOperator::AddEntityOperator(EntityTreePointer tree, EntityItemPointer n bool success; auto queryCube = _newEntity->getQueryAACube(success); if (!success) { - // XXX put on a list for reprocessing? - qDebug() << "Warning -- AddEntityOperator failed to get queryAACube:" << _newEntity->getID(); + _newEntity->markAncestorMissing(true); } _newEntityBox = queryCube.clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 6876efb1f5..5ae578750c 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -18,6 +18,7 @@ #include "VariantMapToScriptValue.h" #include "AddEntityOperator.h" +#include "MovingEntitiesOperator.h" #include "UpdateEntityOperator.h" #include "QVariantGLM.h" #include "EntitiesLogging.h" @@ -323,6 +324,11 @@ EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const Enti // Recurse the tree and store the entity in the correct tree element AddEntityOperator theOperator(getThisPointer(), result); recurseTreeWithOperator(&theOperator); + if (result->getAncestorMissing()) { + // we added the entity, but didn't know about all its ancestors, so it went into the wrong place. + // add it to a list of entities needing to be fixed once their parents are known. + _missingParent.append(result); + } postAddEntity(result); } @@ -932,7 +938,35 @@ void EntityTree::entityChanged(EntityItemPointer entity) { } } +void EntityTree::fixupMissingParents() { + MovingEntitiesOperator moveOperator(getThisPointer()); + + QMutableVectorIterator iter(_missingParent); + while (iter.hasNext()) { + EntityItemWeakPointer entityWP = iter.next(); + EntityItemPointer entity = entityWP.lock(); + if (entity) { + bool success; + AACube newCube = entity->getQueryAACube(success); + if (success) { + // this entity's parent (or ancestry) was previously not fully known, and now is. Update its + // location in the EntityTree. + moveOperator.addEntityToMoveList(entity, newCube); + iter.remove(); + entity->markAncestorMissing(false); + } + } + } + + if (moveOperator.hasMovingEntities()) { + PerformanceTimer perfTimer("recurseTreeWithOperator"); + recurseTreeWithOperator(&moveOperator); + } + +} + void EntityTree::update() { + fixupMissingParents(); if (_simulation) { withWriteLock([&] { _simulation->updateEntities(); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 5e54e562a0..d54ab4f06f 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -306,6 +306,9 @@ protected: quint64 _totalEditDeltas = 0; quint64 _maxEditDelta = 0; quint64 _treeResetTime = 0; + + void fixupMissingParents(); + QVector _missingParent; }; #endif // hifi_EntityTree_h diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index f61ac487fd..63b2dc194f 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -103,6 +103,9 @@ public: SpatiallyNestablePointer getThisPointer() const; + void markAncestorMissing(bool value) { _missingAncestor = value; } + bool getAncestorMissing() { return _missingAncestor; } + protected: const NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; @@ -127,6 +130,8 @@ protected: mutable AACube _queryAACube; mutable bool _queryAACubeSet { false }; + bool _missingAncestor { false }; + private: mutable ReadWriteLockable _transformLock; Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform. From 0013d58365c1bd9e3c9e353383ab35b68aecec96 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 15 Dec 2015 14:25:02 -0800 Subject: [PATCH 10/54] include queryAACube when scripts make changes --- libraries/entities/src/EntityScriptingInterface.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index fbbf6dbef3..9b6238a923 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -134,6 +134,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); propertiesWithSimID.setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); + propertiesWithSimID.setQueryAACube(entity->getQueryAACube()); // and make note of it now, so we can act on it right away. entity->setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); @@ -199,11 +200,11 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) { EntityItemProperties properties = scriptSideProperties; EntityItemID entityID(id); - // If we have a local entity tree set, then also update it. if (!_entityTree) { queueEntityMessage(PacketType::EntityEdit, entityID, properties); return id; } + // If we have a local entity tree set, then also update it. bool updatedEntity = false; _entityTree->withWriteLock([&] { @@ -271,6 +272,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& entity->flagForOwnership(); } } + properties.setQueryAACube(entity->getQueryAACube()); entity->setLastBroadcast(usecTimestampNow()); } }); From b9f0a87a25cc3743b1578e6febcfe6551076c7ad Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 15 Dec 2015 14:43:14 -0800 Subject: [PATCH 11/54] if a server can't get the queryAACube but received one from an interface, use the received one --- libraries/shared/src/SpatiallyNestable.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 7c25fc0ec8..911ce813d5 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -546,7 +546,11 @@ AACube SpatiallyNestable::getQueryAACube() const { bool success; auto result = getQueryAACube(success); if (!success) { - qDebug() << "getQueryAACube failed:" << getID(); + if (_queryAACubeSet) { + result = _queryAACube; + } else { + qDebug() << "getQueryAACube failed:" << getID(); + } } return result; } From 2b800d711ffd98adaefa5c57f61ebbbd24f1037f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 15 Dec 2015 15:18:43 -0800 Subject: [PATCH 12/54] queryAACube to and from scriptvalues --- libraries/entities/src/EntityItem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index e684bdc203..d626349296 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1051,6 +1051,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper COPY_ENTITY_PROPERTY_TO_PROPERTIES(actionData, getActionData); COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentID, getParentID); COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentJointIndex, getParentJointIndex); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(queryAACube, getQueryAACube); properties._defaultSettings = false; @@ -1115,6 +1116,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(actionData, setActionData); SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentID, setParentID); SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentJointIndex, setParentJointIndex); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(queryAACube, setQueryAACube); if (somethingChanged) { uint64_t now = usecTimestampNow(); From 0ac06bad5cd0bf844562e04c01ffb1857f259eb6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 15 Dec 2015 15:31:02 -0800 Subject: [PATCH 13/54] more AACube plumbing --- libraries/entities/src/EntityItemProperties.cpp | 7 +++++++ libraries/entities/src/EntityItemPropertiesMacros.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index ef0a80c93c..39e6d5b856 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -474,6 +474,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_ID, parentID); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_JOINT_INDEX, parentJointIndex); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_QUERY_AA_CUBE, queryAACube); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation); @@ -604,6 +605,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(parentID, QUuid, setParentID); COPY_PROPERTY_FROM_QSCRIPTVALUE(parentJointIndex, quint16, setParentJointIndex); + COPY_PROPERTY_FROM_QSCRIPTVALUE(queryAACube, AACube, setQueryAACube); COPY_PROPERTY_FROM_QSCRIPTVALUE(localPosition, glmVec3, setLocalPosition); COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation); @@ -1465,6 +1467,8 @@ void EntityItemProperties::markAllChanged() { _parentIDChanged = true; _parentJointIndexChanged = true; + + _queryAACubeChanged = true; } // The minimum bounding box for the entity. @@ -1764,6 +1768,9 @@ QList EntityItemProperties::listChangedProperties() { if (parentJointIndexChanged()) { out += "parentJointIndex"; } + if (queryAACubeChanged()) { + out += "queryAACube"; + } getAnimation().listChangedProperties(out); getKeyLight().listChangedProperties(out); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 2236245d26..01d043d070 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -228,6 +228,13 @@ inline glmVec3 glmVec3_convertFromScriptValue(const QScriptValue& v, bool& isVal return glm::vec3(0); } +inline AACube AACube_convertFromScriptValue(const QScriptValue& v, bool& isValid) { + isValid = true; + AACube result; + aaCubeFromScriptValue(v, result); + return result; +} + inline qVectorFloat qVectorFloat_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return qVectorFloatFromScriptValue(v); From 951db42146074d6c8a991a4c322b92254767a91e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 15 Dec 2015 16:17:49 -0800 Subject: [PATCH 14/54] only send queryAABox if something about the location changed --- libraries/entities/src/EntityItemProperties.cpp | 4 ++++ libraries/entities/src/EntityItemProperties.h | 1 + libraries/entities/src/EntityScriptingInterface.cpp | 9 +++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 39e6d5b856..45e0520065 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1784,3 +1784,7 @@ QList EntityItemProperties::listChangedProperties() { bool EntityItemProperties::parentDependentPropertyChanged() const { return localPositionChanged() || positionChanged() || localRotationChanged() || rotationChanged(); } + +bool EntityItemProperties::parentRelatedPropertyChanged() const { + return parentDependentPropertyChanged() || parentIDChanged() || parentJointIndexChanged(); +} diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 500f0d45db..900f5b65ac 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -84,6 +84,7 @@ 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 AABox getAABox() const; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 9b6238a923..896d05b5ff 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -134,7 +134,10 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); propertiesWithSimID.setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); - propertiesWithSimID.setQueryAACube(entity->getQueryAACube()); + if (propertiesWithSimID.parentRelatedPropertyChanged()) { + // due to parenting, the server may not know where something is in world-space, so include the bounding cube. + propertiesWithSimID.setQueryAACube(entity->getQueryAACube()); + } // and make note of it now, so we can act on it right away. entity->setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); @@ -272,7 +275,9 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& entity->flagForOwnership(); } } - properties.setQueryAACube(entity->getQueryAACube()); + if (properties.parentRelatedPropertyChanged()) { + properties.setQueryAACube(entity->getQueryAACube()); + } entity->setLastBroadcast(usecTimestampNow()); } }); From 1c0231c416c65f5acb70d7457b4149878016ab64 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 15 Dec 2015 16:46:16 -0800 Subject: [PATCH 15/54] quiet some debugging prints --- libraries/shared/src/SpatiallyNestable.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 911ce813d5..47d48d1e93 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -14,7 +14,6 @@ #include "DependencyManager.h" #include "SpatiallyNestable.h" - SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) : _nestableType(nestableType), _id(id), @@ -275,9 +274,11 @@ glm::vec3 SpatiallyNestable::getPosition(bool& success) const { glm::vec3 SpatiallyNestable::getPosition() const { bool success; auto result = getPosition(success); + #ifdef WANT_DEBUG if (!success) { - qDebug() << "Warning -- getPosition failed"; + qDebug() << "Warning -- getPosition failed" << getID(); } + #endif return result; } @@ -301,9 +302,11 @@ void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success) { void SpatiallyNestable::setPosition(const glm::vec3& position) { bool success; setPosition(position, success); + #ifdef WANT_DEBUG if (!success) { - qDebug() << "Warning -- setPosition failed"; + qDebug() << "Warning -- setPosition failed" << getID(); } + #endif } glm::quat SpatiallyNestable::getOrientation(bool& success) const { @@ -313,9 +316,11 @@ glm::quat SpatiallyNestable::getOrientation(bool& success) const { glm::quat SpatiallyNestable::getOrientation() const { bool success; auto result = getOrientation(success); + #ifdef WANT_DEBUG if (!success) { - qDebug() << "Warning -- getOrientation failed"; + qDebug() << "Warning -- getOrientation failed" << getID(); } + #endif return result; } @@ -339,9 +344,11 @@ void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& succe void SpatiallyNestable::setOrientation(const glm::quat& orientation) { bool success; setOrientation(orientation, success); + #ifdef WANT_DEBUG if (!success) { - qDebug() << "Wanring -- setOrientation failed"; + qDebug() << "Warning -- setOrientation failed" << getID(); } + #endif } const Transform SpatiallyNestable::getTransform(bool& success) const { From 630b53d950f96b2c37c166dda1a1a6039f55886b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 15 Dec 2015 17:42:34 -0800 Subject: [PATCH 16/54] revert grab script changes --- examples/controllers/handControllerGrab.js | 80 ++++++++++++++-------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 92db768e55..07894b46d1 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -90,7 +90,6 @@ var ZERO_VEC = { }; var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; -var NULL_PARENT_ID = "{00000000-0000-0000-000000000000}"; var MSEC_PER_SEC = 1000.0; // these control how long an abandoned pointer line or action will hang around @@ -262,9 +261,9 @@ function MyController(hand) { this.triggerValue = 0; // rolling average of trigger value this.rawTriggerValue = 0; this.rawBumperValue = 0; - + this.overlayLine = null; - + this.ignoreIK = false; this.offsetPosition = Vec3.ZERO; this.offsetRotation = Quat.IDENTITY; @@ -673,9 +672,7 @@ function MyController(hand) { } //this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - this.overlayLineOn(distantPickRay.origin, - Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH)), - NO_INTERSECT_COLOR); + this.overlayLineOn(distantPickRay.origin, Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH)), NO_INTERSECT_COLOR); }; this.distanceHolding = function() { @@ -699,6 +696,7 @@ function MyController(hand) { this.radiusScalar = 1.0; } + this.actionID = NULL_ACTION_ID; this.actionID = Entities.addAction("spring", this.grabbedEntity, { targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, @@ -881,26 +879,41 @@ function MyController(hand) { } this.actionID = NULL_ACTION_ID; - Entities.editEntity(this.grabbedEntity, { - parentID: MyAvatar.sessionUUID, - parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand") + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: this.offsetPosition, + relativeRotation: this.offsetRotation, + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC, + kinematicSetVelocity: true, + ignoreIK: this.ignoreIK }); + if (this.actionID === NULL_ACTION_ID) { + this.actionID = null; + } else { + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + if (this.state == STATE_NEAR_GRABBING) { + this.setState(STATE_CONTINUE_NEAR_GRABBING); + } else { + // equipping + Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); + this.startHandGrasp(); + + this.setState(STATE_CONTINUE_EQUIP_BD); + } + + if (this.hand === RIGHT_HAND) { + Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); + } else { + Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); + } + + Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); + + Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); - if (this.state == STATE_NEAR_GRABBING) { - this.setState(STATE_CONTINUE_NEAR_GRABBING); - } else { - // equipping - Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); - this.startHandGrasp(); - this.setState(STATE_CONTINUE_EQUIP_BD); } - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); - Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); this.currentHandControllerTipPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition; @@ -948,6 +961,21 @@ function MyController(hand) { if (this.state === STATE_CONTINUE_EQUIP_BD) { Entities.callEntityMethod(this.grabbedEntity, "continueEquip"); } + + if (this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) { + // if less than a 5 seconds left, refresh the actions ttl + Entities.updateAction(this.grabbedEntity, this.actionID, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: this.offsetPosition, + relativeRotation: this.offsetRotation, + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC, + kinematicSetVelocity: true, + ignoreIK: this.ignoreIK + }); + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + } }; this.waitingForBumperRelease = function() { @@ -1159,11 +1187,6 @@ function MyController(hand) { if (this.actionID !== null) { Entities.deleteAction(this.grabbedEntity, this.actionID); } - - Entities.editEntity(this.grabbedEntity, { - parentID: NULL_PARENT_ID, - parentJointIndex: 0 - }); } this.deactivateEntity(this.grabbedEntity); @@ -1292,6 +1315,7 @@ function update() { Messages.subscribe('Hifi-Hand-Disabler'); handleHandDisablerMessages = function(channel, message, sender) { + if (sender === MyAvatar.sessionUUID) { if (message === 'left') { handToDisable = LEFT_HAND; From 45d19167c946219f6eb830e3c73f62f3bf3ceff9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 16 Dec 2015 10:09:46 -0800 Subject: [PATCH 17/54] fix a couple of missing-parent bugs --- assignment-client/src/entities/AssignmentParentFinder.cpp | 5 ++--- libraries/entities/src/EntityItem.cpp | 2 ++ libraries/entities/src/EntityTree.cpp | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/entities/AssignmentParentFinder.cpp b/assignment-client/src/entities/AssignmentParentFinder.cpp index fbcaba84ae..d8bc51a0f0 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.cpp +++ b/assignment-client/src/entities/AssignmentParentFinder.cpp @@ -15,10 +15,9 @@ SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID, bool& SpatiallyNestableWeakPointer parent; // search entities parent = _tree->findEntityByEntityItemID(parentID); - if (parent.lock()) { - success = true; - } else { + if (parent.expired()) { success = false; } + success = true; return parent; } diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index d626349296..bc91b46f5b 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1254,6 +1254,8 @@ const AABox& EntityItem::getAABox(bool& success) const { _cachedAABox = AABox(rotatedExtentsRelativeToRegistrationPoint); _recalcAABox = false; } + } else { + success = true; } return _cachedAABox; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 5ae578750c..cb787607a8 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -240,8 +240,8 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI bool success; AACube queryCube = childEntity->getQueryAACube(success); if (!success) { - qCDebug(entities) << "Can't update child -- failed to get query-cube for" << childEntity->getID(); - // XXX put on a list for later checking? + _missingParent.append(childEntity); + continue; } UpdateEntityOperator theChildOperator(getThisPointer(), containingElement, childEntity, queryCube); From 10b82945a6fdbad870c25edbe3eb377c480c8223 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 16 Dec 2015 10:16:01 -0800 Subject: [PATCH 18/54] formatting --- libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp | 2 +- libraries/entities/src/UpdateEntityOperator.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 57c985c992..1048f594f4 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -142,7 +142,7 @@ glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const { glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const { glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units - bool success; // XXX Does this actually have to happen in world space? + bool success; // TODO -- Does this actually have to happen in world space? glm::vec3 center = getCenterPosition(success); glm::vec3 position = getPosition(success); glm::vec3 positionToCenter = center - position; diff --git a/libraries/entities/src/UpdateEntityOperator.h b/libraries/entities/src/UpdateEntityOperator.h index 5124075a6d..ea6faabe3e 100644 --- a/libraries/entities/src/UpdateEntityOperator.h +++ b/libraries/entities/src/UpdateEntityOperator.h @@ -12,7 +12,6 @@ #ifndef hifi_UpdateEntityOperator_h #define hifi_UpdateEntityOperator_h -// #include "BoundingBoxRelatedProperties.h" #include "EntitiesLogging.h" #include "EntityItem.h" #include "EntityItemProperties.h" From 0500c21e0067f9ff5f68e49d34621d7cdf1296da Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 16 Dec 2015 16:09:52 -0800 Subject: [PATCH 19/54] unmangle merge --- libraries/avatars/src/AvatarData.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 3301b97942..ecf9947979 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -90,10 +90,13 @@ const QUrl& AvatarData::defaultFullAvatarModelUrl() { // There are a number of possible strategies for this set of tools through endRender, below. void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { avatarLock.lock(); - Transform trans = getTransform(); + bool success; + Transform trans = getTransform(success); + if (!success) { + return; + } trans.setTranslation(position); trans.setRotation(orientation); - bool success; SpatiallyNestable::setTransform(trans, success); if (!success) { qDebug() << "Warning -- AvatarData::nextAttitude failed"; From b83579e6e5426924c946abeaa7e204d1de6b9402 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 16 Dec 2015 17:25:49 -0800 Subject: [PATCH 20/54] include queryAABox in physics-induced sends --- libraries/avatars/src/AvatarData.cpp | 1 + libraries/entities/src/EntityScriptingInterface.cpp | 3 +-- libraries/physics/src/EntityMotionState.cpp | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ecf9947979..8942699070 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -93,6 +93,7 @@ void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { bool success; Transform trans = getTransform(success); if (!success) { + qDebug() << "Warning -- AvatarData::nextAttitude failed"; return; } trans.setTranslation(position); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 896d05b5ff..05fd481761 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -211,8 +211,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& bool updatedEntity = false; _entityTree->withWriteLock([&] { - if (scriptSideProperties.parentDependentPropertyChanged() || - scriptSideProperties.parentIDChanged() || scriptSideProperties.parentJointIndexChanged()) { + if (scriptSideProperties.parentRelatedPropertyChanged()) { // All of parentID, parentJointIndex, position, rotation are needed to make sense of any of them. // If any of these changed, pull any missing properties from the entity. EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index f86369a514..2e23c4ebd8 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -466,6 +466,11 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q properties.setActionData(_serverActionData); } + if (properties.parentRelatedPropertyChanged()) { + // 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 quint64 now = usecTimestampNow(); properties.setLastEdited(now); From 7693058e39a48b5e725557c6020a3f71d141337e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 17 Dec 2015 10:49:24 -0800 Subject: [PATCH 21/54] clear _queryAACubeSet flag in locationChanged --- libraries/shared/src/SpatiallyNestable.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 47d48d1e93..c056173464 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -531,6 +531,17 @@ void SpatiallyNestable::forEachDescendant(std::functionlocationChanged(); }); From 473212e5b72d577871889bb4b2f394195833fbd1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 17 Dec 2015 14:29:41 -0800 Subject: [PATCH 22/54] try to be more coherent about queryAABox meaning --- libraries/entities/src/EntityItem.cpp | 16 +++++++---- libraries/entities/src/EntityItem.h | 6 ++-- .../entities/src/EntityScriptingInterface.cpp | 11 ++++++++ libraries/entities/src/EntityTree.cpp | 3 ++ libraries/physics/src/EntityMotionState.cpp | 11 ++++++++ libraries/shared/src/SpatiallyNestable.cpp | 28 +++++++++++++++---- libraries/shared/src/SpatiallyNestable.h | 9 ++++-- 7 files changed, 68 insertions(+), 16 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index bc91b46f5b..89c5d28f99 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1177,7 +1177,7 @@ void EntityItem::setDimensions(const glm::vec3& value) { /// The maximum bounding cube for the entity, independent of it's rotation. /// This accounts for the registration point (upon which rotation occurs around). /// -const AACube& EntityItem::getMaximumAACube(bool& success) const { +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 @@ -1207,7 +1207,7 @@ const AACube& EntityItem::getMaximumAACube(bool& success) const { /// The minimum bounding cube for the entity accounting for it's rotation. /// This accounts for the registration point (upon which rotation occurs around). /// -const AACube& EntityItem::getMinimumAACube(bool& success) const { +AACube EntityItem::getMinimumAACube(bool& success) const { if (_recalcMinAACube) { // _position represents the position of the registration point. glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; @@ -1236,7 +1236,7 @@ const AACube& EntityItem::getMinimumAACube(bool& success) const { return _minAACube; } -const AABox& EntityItem::getAABox(bool& success) const { +AABox EntityItem::getAABox(bool& success) const { if (_recalcAABox) { // _position represents the position of the registration point. glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; @@ -1261,11 +1261,17 @@ const AABox& EntityItem::getAABox(bool& success) const { } AACube EntityItem::getQueryAACube(bool& success) const { - AACube result = getMaximumAACube(success); + AACube result = SpatiallyNestable::getQueryAACube(success); if (success) { return result; } - return SpatiallyNestable::getQueryAACube(success); + // this is for when we've loaded an older json file that didn't have queryAACube properties. + result = getMaximumAACube(success); + if (success) { + _queryAACube = result; + _queryAACubeSet = true; + } + return result; } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 5877b9acbd..06434a3ea4 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -231,9 +231,9 @@ public: quint64 getExpiry() const; // position, size, and bounds related helpers - const AACube& getMaximumAACube(bool& success) const; - const AACube& getMinimumAACube(bool& success) const; - const AABox& getAABox(bool& success) const; /// axis aligned bounding box in world-frame (meters) + virtual AACube getMaximumAACube(bool& success) const override; + AACube getMinimumAACube(bool& success) const; + AABox getAABox(bool& success) const; /// axis aligned bounding box in world-frame (meters) using SpatiallyNestable::getQueryAACube; virtual AACube getQueryAACube(bool& success) const override; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 05fd481761..9d5600e615 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -279,6 +279,17 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& } entity->setLastBroadcast(usecTimestampNow()); } + + // if we've moved an entity with children, check/update the queryAACube of all descendents and tell the server + // if they've changed. + // TODO -- ancestors of this entity may also need to expand their queryAACubes. + entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { + if (descendant->setPuffedQueryAACube()) { + EntityItemProperties newQueryCubeProperties; + newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); + queueEntityMessage(PacketType::EntityEdit, descendant->getID(), newQueryCubeProperties); + } + }); }); queueEntityMessage(PacketType::EntityEdit, entityID, properties); return id; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index cb787607a8..b0a2f73b6c 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -89,6 +89,9 @@ void EntityTree::postAddEntity(EntityItemPointer entity) { _isDirty = true; maybeNotifyNewCollisionSoundURL("", entity->getCollisionSoundURL()); emit addingEntity(entity->getEntityItemID()); + + // find and hook up any entities with this entity as a (previously) missing parent + fixupMissingParents(); } bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) { diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 2e23c4ebd8..0e80a28b0a 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -507,6 +507,17 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q entityPacketSender->queueEditEntityMessage(PacketType::EntityEdit, id, properties); _entity->setLastBroadcast(usecTimestampNow()); + // if we've moved an entity with children, check/update the queryAACube of all descendents and tell the server + // if they've changed. + // TODO -- ancestors of this entity may also need to expand their queryAACubes. + _entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { + if (descendant->setPuffedQueryAACube()) { + EntityItemProperties newQueryCubeProperties; + newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); + entityPacketSender->queueEditEntityMessage(PacketType::EntityEdit, descendant->getID(), newQueryCubeProperties); + } + }); + _lastStep = step; } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index c056173464..43632825be 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -552,11 +552,33 @@ void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { _queryAACubeSet = true; } +AACube SpatiallyNestable::getMaximumAACube(bool& success) const { + return AACube(getPosition(success) - glm::vec3(0.5f), 1.0f); // XXX +} + +bool SpatiallyNestable::setPuffedQueryAACube() { + bool success; + AACube currentAACube = getMaximumAACube(success); + if (!success) { + qDebug() << "can't getMaximumAACube for" << getID(); + return false; + } + if (_queryAACubeSet && _queryAACube.contains(currentAACube)) { + return false; + } + + // make an AACube with edges twice as long and centered on the object + _queryAACube = AACube(currentAACube.getCorner() - glm::vec3(currentAACube.getScale()), currentAACube.getScale() * 2.0f); + _queryAACubeSet = true; + return true; +} + AACube SpatiallyNestable::getQueryAACube(bool& success) const { if (_queryAACubeSet) { success = true; return _queryAACube; } + success = false; return AACube(getPosition(success) - glm::vec3(0.5f), 1.0f); // XXX } @@ -564,11 +586,7 @@ AACube SpatiallyNestable::getQueryAACube() const { bool success; auto result = getQueryAACube(success); if (!success) { - if (_queryAACubeSet) { - result = _queryAACube; - } else { - qDebug() << "getQueryAACube failed:" << getID(); - } + qDebug() << "getQueryAACube failed for" << getID(); } return result; } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 63b2dc194f..e5540eb79c 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -68,6 +68,9 @@ public: virtual void setOrientation(const glm::quat& orientation, bool& success); virtual void setOrientation(const glm::quat& orientation); + virtual AACube getMaximumAACube(bool& success) const; + virtual bool setPuffedQueryAACube(); + virtual void setQueryAACube(const AACube& queryAACube); virtual AACube getQueryAACube(bool& success) const; virtual AACube getQueryAACube() const; @@ -106,6 +109,9 @@ public: void markAncestorMissing(bool value) { _missingAncestor = value; } bool getAncestorMissing() { return _missingAncestor; } + void forEachChild(std::function actor); + void forEachDescendant(std::function actor); + protected: const NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; @@ -123,9 +129,6 @@ protected: virtual void locationChanged(); // called when a this object's location has changed virtual void dimensionsChanged() {} // called when a this object's dimensions have changed - 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 }; From 2dd2a49141402ded56df07f956adb37a872b3c2d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 17 Dec 2015 15:02:07 -0800 Subject: [PATCH 23/54] a non-set queryAACube is one with no volume --- libraries/shared/src/SpatiallyNestable.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 43632825be..45cd7fec02 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -531,17 +531,6 @@ void SpatiallyNestable::forEachDescendant(std::functionlocationChanged(); }); @@ -549,7 +538,9 @@ void SpatiallyNestable::locationChanged() { void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { _queryAACube = queryAACube; - _queryAACubeSet = true; + if (queryAACube.getScale() > 0.0f) { + _queryAACubeSet = true; + } } AACube SpatiallyNestable::getMaximumAACube(bool& success) const { From 688448fe4155a11c2dae4f02c35c43f84ce2809d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 17 Dec 2015 16:18:41 -0800 Subject: [PATCH 24/54] more queryAABox experimenting --- .../entities/src/EntityScriptingInterface.cpp | 2 +- libraries/physics/src/EntityMotionState.cpp | 6 +++++- libraries/shared/src/SpatiallyNestable.cpp | 19 ++++++++++++++----- libraries/shared/src/SpatiallyNestable.h | 1 + 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 9d5600e615..57201174f5 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -274,7 +274,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& entity->flagForOwnership(); } } - if (properties.parentRelatedPropertyChanged()) { + if (properties.parentRelatedPropertyChanged() && entity->setPuffedQueryAACube()) { properties.setQueryAACube(entity->getQueryAACube()); } entity->setLastBroadcast(usecTimestampNow()); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 0e80a28b0a..ac0e25a233 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -374,6 +374,10 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep, const QUuid& s return true; } + if (_entity->queryAABoxNeedsUpdate()) { + return true; + } + if (_entity->getSimulatorID() != sessionID) { // we don't own the simulation, but maybe we should... if (_outgoingPriority != NO_PRORITY) { @@ -466,7 +470,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q properties.setActionData(_serverActionData); } - if (properties.parentRelatedPropertyChanged()) { + if (properties.parentRelatedPropertyChanged() && _entity->setPuffedQueryAACube()) { // due to parenting, the server may not know where something is in world-space, so include the bounding cube. properties.setQueryAACube(_entity->getQueryAACube()); } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 45cd7fec02..eb8af2101e 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -536,6 +536,10 @@ void SpatiallyNestable::locationChanged() { }); } +AACube SpatiallyNestable::getMaximumAACube(bool& success) const { + return AACube(getPosition(success) - glm::vec3(0.5f), 1.0f); // XXX +} + void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { _queryAACube = queryAACube; if (queryAACube.getScale() > 0.0f) { @@ -543,11 +547,7 @@ void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { } } -AACube SpatiallyNestable::getMaximumAACube(bool& success) const { - return AACube(getPosition(success) - glm::vec3(0.5f), 1.0f); // XXX -} - -bool SpatiallyNestable::setPuffedQueryAACube() { +bool SpatiallyNestable::queryAABoxNeedsUpdate() const { bool success; AACube currentAACube = getMaximumAACube(success); if (!success) { @@ -558,6 +558,15 @@ bool SpatiallyNestable::setPuffedQueryAACube() { return false; } + return true; +} + +bool SpatiallyNestable::setPuffedQueryAACube() { + if (!queryAABoxNeedsUpdate()) { + return false; + } + bool success; + AACube currentAACube = getMaximumAACube(success); // make an AACube with edges twice as long and centered on the object _queryAACube = AACube(currentAACube.getCorner() - glm::vec3(currentAACube.getScale()), currentAACube.getScale() * 2.0f); _queryAACubeSet = true; diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index e5540eb79c..91fdd84be0 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -72,6 +72,7 @@ public: virtual bool setPuffedQueryAACube(); virtual void setQueryAACube(const AACube& queryAACube); + virtual bool queryAABoxNeedsUpdate() const; virtual AACube getQueryAACube(bool& success) const; virtual AACube getQueryAACube() const; From 81d3571171495566816d3627ccabb11b0ff8630c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 18 Dec 2015 12:04:47 -0800 Subject: [PATCH 25/54] fix getMaximumAACube and getMinimumAACube success return values --- libraries/entities/src/EntityItem.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 89c5d28f99..7a2d01053c 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1200,6 +1200,8 @@ AACube EntityItem::getMaximumAACube(bool& success) const { _maxAACube = AACube(minimumCorner, radius * 2.0f); _recalcMaxAACube = false; } + } else { + success = true; } return _maxAACube; } @@ -1232,6 +1234,8 @@ AACube EntityItem::getMinimumAACube(bool& success) const { _minAACube = AACube(cornerOfCube, longestSide); _recalcMinAACube = false; } + } else { + success = true; } return _minAACube; } From 69bba4a18272b0c6c05ebe166f92a55c79da4d99 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 18 Dec 2015 14:46:24 -0800 Subject: [PATCH 26/54] queryAABox wasn't centered on object --- libraries/shared/src/SpatiallyNestable.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index eb8af2101e..af889b8245 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -567,8 +567,9 @@ bool SpatiallyNestable::setPuffedQueryAACube() { } bool success; AACube currentAACube = getMaximumAACube(success); - // make an AACube with edges twice as long and centered on the object - _queryAACube = AACube(currentAACube.getCorner() - glm::vec3(currentAACube.getScale()), currentAACube.getScale() * 2.0f); + // 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); + // _queryAACube = AACube(currentAACube.getCorner(), currentAACube.getScale()); _queryAACubeSet = true; return true; } From 5bede8123d12929d5dc4f78dbf933ef2f3894620 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 18 Dec 2015 14:47:05 -0800 Subject: [PATCH 27/54] script for debugging queryAACube --- examples/show-query-box.js | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 examples/show-query-box.js diff --git a/examples/show-query-box.js b/examples/show-query-box.js new file mode 100644 index 0000000000..e01dea669a --- /dev/null +++ b/examples/show-query-box.js @@ -0,0 +1,45 @@ +Script.include("libraries/utils.js"); + +var INSPECT_RADIUS = 10; +var overlays = {}; + +function updateOverlay(entityID, queryAACube) { + var cubeCenter = {x: queryAACube.x + queryAACube.scale / 2.0, + y: queryAACube.y + queryAACube.scale / 2.0, + z: queryAACube.z + queryAACube.scale / 2.0}; + + if (entityID in overlays) { + var overlay = overlays[entityID]; + Overlays.editOverlay(overlay, { + position: cubeCenter, + size: queryAACube.scale + }); + } else { + overlays[entityID] = Overlays.addOverlay("cube", { + position: cubeCenter, + size: queryAACube.scale, + color: { red: 0, green: 0, blue: 255}, + alpha: 1, + // borderSize: ..., + solid: false + }); + } +} + +Script.setInterval(function() { + // {f4b3936e-c452-4b31-ab40-dd9a550cb756} + var nearbyEntities = Entities.findEntities(MyAvatar.position, INSPECT_RADIUS); + for (var entityIndex = 0; entityIndex < nearbyEntities.length; entityIndex++) { + var entityID = nearbyEntities[entityIndex]; + var queryAACube = Entities.getEntityProperties(entityID, ["queryAACube"]).queryAACube; + updateOverlay(entityID, queryAACube); + } +}, 100); + +function cleanup() { + for (var entityID in overlays) { + Overlays.deleteOverlay(overlays[entityID]); + } +} + +Script.scriptEnding.connect(cleanup); From 9b49d9d66b6a97e4ed468e8bca8f55f48e403353 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 18 Dec 2015 15:10:51 -0800 Subject: [PATCH 28/54] default parentJointIndex to -1 --- libraries/entities/src/EntityItemProperties.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 900f5b65ac..6553f231d0 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -192,7 +192,7 @@ public: DEFINE_PROPERTY_REF(PROP_Y_P_NEIGHBOR_ID, YPNeighborID, yPNeighborID, EntityItemID, UNKNOWN_ENTITY_ID); 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_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, -1); DEFINE_PROPERTY_REF(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube, AACube()); // these are used when bouncing location data into and out of scripts From 7689453ba2306716d9b1747ff219425917ff44e8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 18 Dec 2015 15:11:28 -0800 Subject: [PATCH 29/54] don't reset action refresh counter untill the updateAction succeeded --- examples/controllers/handControllerGrab.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 07894b46d1..09d2130c18 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -826,14 +826,16 @@ function MyController(hand) { this.currentObjectPosition = Vec3.sum(this.currentObjectPosition, change); } - Entities.updateAction(this.grabbedEntity, this.actionID, { + var success = Entities.updateAction(this.grabbedEntity, this.actionID, { targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, ttl: ACTION_TTL }); - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + if (success) { + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + } }; this.nearGrabbing = function() { From 3782c21b4552cd7ac9c59d83b6adf559962cc637 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 18 Dec 2015 16:06:51 -0800 Subject: [PATCH 30/54] when a parent moves, check children vs their queryAACubes --- libraries/shared/src/SpatiallyNestable.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index af889b8245..48e9b14271 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -296,6 +296,8 @@ void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success) { }); if (success) { locationChanged(); + } else { + qDebug() << "setPosition failed for" << getID(); } } @@ -554,6 +556,18 @@ bool SpatiallyNestable::queryAABoxNeedsUpdate() const { qDebug() << "can't getMaximumAACube for" << getID(); return false; } + + // make sure children are still in their boxes, also. + bool childNeedsUpdate = false; + getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) { + if (descendant->queryAABoxNeedsUpdate()) { + childNeedsUpdate = true; + } + }); + if (childNeedsUpdate) { + return true; + } + if (_queryAACubeSet && _queryAACube.contains(currentAACube)) { return false; } From 701f99d28ead6b5a908456610e6e9296fd1695a7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 18 Dec 2015 16:28:11 -0800 Subject: [PATCH 31/54] only send a queryAACube for entities to entity-server --- .../entities/src/EntityScriptingInterface.cpp | 26 +++++++++++-------- libraries/physics/src/EntityMotionState.cpp | 12 ++++++--- libraries/shared/src/SpatiallyNestable.cpp | 2 ++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 57201174f5..56dc13a126 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -278,18 +278,22 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& properties.setQueryAACube(entity->getQueryAACube()); } entity->setLastBroadcast(usecTimestampNow()); - } - // if we've moved an entity with children, check/update the queryAACube of all descendents and tell the server - // if they've changed. - // TODO -- ancestors of this entity may also need to expand their queryAACubes. - entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { - if (descendant->setPuffedQueryAACube()) { - EntityItemProperties newQueryCubeProperties; - newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); - queueEntityMessage(PacketType::EntityEdit, descendant->getID(), newQueryCubeProperties); - } - }); + // if we've moved an entity with children, check/update the queryAACube of all descendents and tell the server + // if they've changed. + // TODO -- ancestors of this entity may also need to expand their queryAACubes. + entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { + if (descendant->getNestableType() == NestableType::Entity) { + EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); + if (descendant->setPuffedQueryAACube()) { + EntityItemProperties newQueryCubeProperties; + newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); + queueEntityMessage(PacketType::EntityEdit, descendant->getID(), newQueryCubeProperties); + entityDescendant->setLastBroadcast(usecTimestampNow()); + } + } + }); + } }); queueEntityMessage(PacketType::EntityEdit, entityID, properties); return id; diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index ac0e25a233..4dd61608cc 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -515,10 +515,14 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q // if they've changed. // TODO -- ancestors of this entity may also need to expand their queryAACubes. _entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { - if (descendant->setPuffedQueryAACube()) { - EntityItemProperties newQueryCubeProperties; - newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); - entityPacketSender->queueEditEntityMessage(PacketType::EntityEdit, descendant->getID(), newQueryCubeProperties); + if (descendant->getNestableType() == NestableType::Entity) { + EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); + if (descendant->setPuffedQueryAACube()) { + EntityItemProperties newQueryCubeProperties; + newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); + entityPacketSender->queueEditEntityMessage(PacketType::EntityEdit, descendant->getID(), newQueryCubeProperties); + entityDescendant->setLastBroadcast(usecTimestampNow()); + } } }); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index af889b8245..ef8c39292b 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -296,6 +296,8 @@ void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success) { }); if (success) { locationChanged(); + } else { + qDebug() << "setPosition failed for" << getID(); } } From cdefa7ec32e95b663a70a9b2c63204a7a2a15010 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 19 Dec 2015 08:09:39 -0800 Subject: [PATCH 32/54] move some debugging scripts into their own directory --- examples/{ => debugging}/actionInspector.js | 4 ++-- examples/{ => debugging}/grabInspector.js | 4 ++-- .../queryAACubeInspector.js} | 15 +++++++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) rename examples/{ => debugging}/actionInspector.js (98%) rename examples/{ => debugging}/grabInspector.js (98%) rename examples/{show-query-box.js => debugging/queryAACubeInspector.js} (80%) diff --git a/examples/actionInspector.js b/examples/debugging/actionInspector.js similarity index 98% rename from examples/actionInspector.js rename to examples/debugging/actionInspector.js index 934120ddf6..303dcbebbd 100644 --- a/examples/actionInspector.js +++ b/examples/debugging/actionInspector.js @@ -1,6 +1,6 @@ // // actionInspector.js -// examples +// examples/debugging/ // // Created by Seth Alves on 2015-9-30. // Copyright 2015 High Fidelity, Inc. @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/utils.js"); +Script.include("../libraries/utils.js"); var INSPECT_RADIUS = 10; diff --git a/examples/grabInspector.js b/examples/debugging/grabInspector.js similarity index 98% rename from examples/grabInspector.js rename to examples/debugging/grabInspector.js index 8a027f819a..aeea2c20b4 100644 --- a/examples/grabInspector.js +++ b/examples/debugging/grabInspector.js @@ -1,6 +1,6 @@ // // grabInspector.js -// examples +// examples/debugging/ // // Created by Seth Alves on 2015-9-30. // Copyright 2015 High Fidelity, Inc. @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/utils.js"); +Script.include("../libraries/utils.js"); var INSPECT_RADIUS = 10; var overlays = {}; diff --git a/examples/show-query-box.js b/examples/debugging/queryAACubeInspector.js similarity index 80% rename from examples/show-query-box.js rename to examples/debugging/queryAACubeInspector.js index e01dea669a..96296a7576 100644 --- a/examples/show-query-box.js +++ b/examples/debugging/queryAACubeInspector.js @@ -1,4 +1,16 @@ -Script.include("libraries/utils.js"); +// +// grabInspector.js +// examples/debugging/ +// +// Created by Seth Alves on 2015-12-19. +// Copyright 2015 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 +// + + +Script.include("../libraries/utils.js"); var INSPECT_RADIUS = 10; var overlays = {}; @@ -27,7 +39,6 @@ function updateOverlay(entityID, queryAACube) { } Script.setInterval(function() { - // {f4b3936e-c452-4b31-ab40-dd9a550cb756} var nearbyEntities = Entities.findEntities(MyAvatar.position, INSPECT_RADIUS); for (var entityIndex = 0; entityIndex < nearbyEntities.length; entityIndex++) { var entityID = nearbyEntities[entityIndex]; From abaa3299842c6f07dc88ab27048c10565b94d1d5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 21 Dec 2015 10:55:07 -0800 Subject: [PATCH 33/54] parents AACube should encompass all children's --- libraries/shared/src/AACube.cpp | 7 +++++++ libraries/shared/src/AACube.h | 2 ++ libraries/shared/src/SpatiallyNestable.cpp | 13 +++++++++++++ 3 files changed, 22 insertions(+) diff --git a/libraries/shared/src/AACube.cpp b/libraries/shared/src/AACube.cpp index 32a304872c..4378dbb89b 100644 --- a/libraries/shared/src/AACube.cpp +++ b/libraries/shared/src/AACube.cpp @@ -465,3 +465,10 @@ AABox AACube::clamp(float min, float max) const { return temp.clamp(min, max); } +AACube& AACube::operator += (const glm::vec3& point) { + _corner = glm::min(_corner, point); + glm::vec3 scale = point - _corner; + _scale = glm::max(_scale, scale.x, scale.y, scale.z); + + return (*this); +} diff --git a/libraries/shared/src/AACube.h b/libraries/shared/src/AACube.h index d301207429..fbbbe9992a 100644 --- a/libraries/shared/src/AACube.h +++ b/libraries/shared/src/AACube.h @@ -64,6 +64,8 @@ public: AABox clamp(const glm::vec3& min, const glm::vec3& max) const; AABox clamp(float min, float max) const; + AACube& operator += (const glm::vec3& point); + private: glm::vec3 getClosestPointOnFace(const glm::vec3& point, BoxFace face) const; glm::vec3 getClosestPointOnFace(const glm::vec4& origin, const glm::vec4& direction, BoxFace face) const; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 48e9b14271..0880d39356 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -585,6 +585,19 @@ bool SpatiallyNestable::setPuffedQueryAACube() { _queryAACube = AACube(currentAACube.getCorner() - glm::vec3(currentAACube.getScale()), currentAACube.getScale() * 3.0f); // _queryAACube = AACube(currentAACube.getCorner(), currentAACube.getScale()); _queryAACubeSet = true; + + getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) { + bool success; + AACube descendantAACube = descendant->getMaximumAACube(success); + if (success) { + if (_queryAACube.contains(currentAACube)) { + return; + } + _queryAACube += descendantAACube.getMinimumPoint(); + _queryAACube += descendantAACube.getMaximumPoint(); + } + }); + return true; } From 3c2dac5cf8226e9627f4ff97c3230911f2e3e1fd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 21 Dec 2015 11:05:07 -0800 Subject: [PATCH 34/54] parent query-cube should encompass child query-cube not child max-aa-cube --- libraries/shared/src/SpatiallyNestable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 0880d39356..f273aaadda 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -588,7 +588,7 @@ bool SpatiallyNestable::setPuffedQueryAACube() { getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) { bool success; - AACube descendantAACube = descendant->getMaximumAACube(success); + AACube descendantAACube = descendant->getQueryAACube(success); if (success) { if (_queryAACube.contains(currentAACube)) { return; From 00e0b26f05c21a62fc949300c4880344891081fe Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 21 Dec 2015 11:15:54 -0800 Subject: [PATCH 35/54] fix thinko and whitespace --- libraries/shared/src/SpatiallyNestable.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index f273aaadda..416b6646c2 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -587,16 +587,16 @@ bool SpatiallyNestable::setPuffedQueryAACube() { _queryAACubeSet = true; getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) { - bool success; - AACube descendantAACube = descendant->getQueryAACube(success); - if (success) { - if (_queryAACube.contains(currentAACube)) { - return; - } - _queryAACube += descendantAACube.getMinimumPoint(); - _queryAACube += descendantAACube.getMaximumPoint(); + bool success; + AACube descendantAACube = descendant->getQueryAACube(success); + if (success) { + if (_queryAACube.contains(descendantAACube)) { + return; } - }); + _queryAACube += descendantAACube.getMinimumPoint(); + _queryAACube += descendantAACube.getMaximumPoint(); + } + }); return true; } From 68cfda1af9e264e04027da98530fb10b47df1a6e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 21 Dec 2015 11:34:53 -0800 Subject: [PATCH 36/54] try again on AACube::operator += --- libraries/shared/src/AACube.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/AACube.cpp b/libraries/shared/src/AACube.cpp index 4378dbb89b..4218826141 100644 --- a/libraries/shared/src/AACube.cpp +++ b/libraries/shared/src/AACube.cpp @@ -466,9 +466,15 @@ AABox AACube::clamp(float min, float max) const { } AACube& AACube::operator += (const glm::vec3& point) { - _corner = glm::min(_corner, point); - glm::vec3 scale = point - _corner; - _scale = glm::max(_scale, scale.x, scale.y, scale.z); + glm::vec3 oldMaximumPoint = getMaximumPoint(); + _corner = glm::vec3(glm::min(_corner.x, point.x), + glm::min(_corner.y, point.y), + glm::min(_corner.z, point.z)); + + glm::vec3 scaleOld = oldMaximumPoint - _corner; + glm::vec3 scalePoint = point - _corner; + _scale = glm::max(_scale, scalePoint.x, scalePoint.y, scalePoint.z); + _scale = glm::max(_scale, scaleOld.x, scaleOld.y, scaleOld.z); return (*this); } From f0bffe7a24f28025e7f76c3b07890a658016215c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 21 Dec 2015 14:29:07 -0800 Subject: [PATCH 37/54] fix success return value --- assignment-client/src/entities/AssignmentParentFinder.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/entities/AssignmentParentFinder.cpp b/assignment-client/src/entities/AssignmentParentFinder.cpp index d8bc51a0f0..cc5c7557dc 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.cpp +++ b/assignment-client/src/entities/AssignmentParentFinder.cpp @@ -17,7 +17,8 @@ SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID, bool& parent = _tree->findEntityByEntityItemID(parentID); if (parent.expired()) { success = false; + } else { + success = true; } - success = true; return parent; } From c84fa5f82133b28b849c238eb8d95f9813711ffd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 21 Dec 2015 14:45:18 -0800 Subject: [PATCH 38/54] cleanups --- libraries/entities/src/EntityScriptingInterface.cpp | 1 - libraries/physics/src/EntityMotionState.cpp | 1 - libraries/shared/src/SpatiallyNestable.cpp | 6 ++++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 56dc13a126..0581f380aa 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -281,7 +281,6 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& // if we've moved an entity with children, check/update the queryAACube of all descendents and tell the server // if they've changed. - // TODO -- ancestors of this entity may also need to expand their queryAACubes. entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { if (descendant->getNestableType() == NestableType::Entity) { EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 4dd61608cc..430db2b2aa 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -513,7 +513,6 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q // if we've moved an entity with children, check/update the queryAACube of all descendents and tell the server // if they've changed. - // TODO -- ancestors of this entity may also need to expand their queryAACubes. _entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { if (descendant->getNestableType() == NestableType::Entity) { EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 416b6646c2..288bda5dfa 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -14,6 +14,8 @@ #include "DependencyManager.h" #include "SpatiallyNestable.h" +const float defaultAACubeSize = 1.0f; + SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) : _nestableType(nestableType), _id(id), @@ -539,7 +541,7 @@ void SpatiallyNestable::locationChanged() { } AACube SpatiallyNestable::getMaximumAACube(bool& success) const { - return AACube(getPosition(success) - glm::vec3(0.5f), 1.0f); // XXX + return AACube(getPosition(success) - glm::vec3(defaultAACubeSize / 2.0f), defaultAACubeSize); } void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { @@ -607,7 +609,7 @@ AACube SpatiallyNestable::getQueryAACube(bool& success) const { return _queryAACube; } success = false; - return AACube(getPosition(success) - glm::vec3(0.5f), 1.0f); // XXX + return AACube(getPosition(success) - glm::vec3(defaultAACubeSize / 2.0f), defaultAACubeSize); } AACube SpatiallyNestable::getQueryAACube() const { From 1d9f3097da5c0506083c6278137f1611c851baf8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 21 Dec 2015 15:16:55 -0800 Subject: [PATCH 39/54] trying to track down why equips fail after a few minutes --- libraries/physics/src/ObjectAction.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 17b565ba21..e8e1188dc9 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -23,15 +23,15 @@ ObjectAction::~ObjectAction() { } void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) { - bool ownerEntityExpired = false; quint64 expiresWhen = 0; + EntityItemPointer ownerEntity = nullptr; withReadLock([&]{ - ownerEntityExpired = _ownerEntity.expired(); + ownerEntity = _ownerEntity.lock(); expiresWhen = _expires; }); - if (ownerEntityExpired) { + if (!ownerEntity) { qDebug() << "warning -- action with no entity removing self from btCollisionWorld."; btDynamicsWorld* dynamicsWorld = static_cast(collisionWorld); if (dynamicsWorld) { @@ -43,10 +43,8 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta if (expiresWhen > 0) { quint64 now = usecTimestampNow(); if (now > expiresWhen) { - EntityItemPointer ownerEntity = nullptr; QUuid myID; withWriteLock([&]{ - ownerEntity = _ownerEntity.lock(); _active = false; myID = getID(); }); From 6e1217d3763435787ad2a3313fc3fa306b8adf20 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 22 Dec 2015 11:22:35 -0800 Subject: [PATCH 40/54] if an action fails (probably due to time skew bug), recreate it --- examples/controllers/handControllerGrab.js | 93 +++++++++++++--------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 09d2130c18..c7dcda21f3 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -835,9 +835,32 @@ function MyController(hand) { }); if (success) { this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + } else { + print("continueDistanceHolding -- updateAction failed"); } }; + + this.setupHoldAction = function() { + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: this.offsetPosition, + relativeRotation: this.offsetRotation, + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC, + kinematicSetVelocity: true, + ignoreIK: this.ignoreIK + }); + if (this.actionID === NULL_ACTION_ID) { + this.actionID = null; + return false; + } + var now = Date.now(); + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + return true; + }; + this.nearGrabbing = function() { var now = Date.now(); var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); @@ -880,42 +903,27 @@ function MyController(hand) { this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); } - this.actionID = NULL_ACTION_ID; - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: this.offsetPosition, - relativeRotation: this.offsetRotation, - ttl: ACTION_TTL, - kinematic: NEAR_GRABBING_KINEMATIC, - kinematicSetVelocity: true, - ignoreIK: this.ignoreIK - }); - if (this.actionID === NULL_ACTION_ID) { - this.actionID = null; - } else { - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); - if (this.state == STATE_NEAR_GRABBING) { - this.setState(STATE_CONTINUE_NEAR_GRABBING); - } else { - // equipping - Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); - this.startHandGrasp(); - - this.setState(STATE_CONTINUE_EQUIP_BD); - } - - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - - Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); - - Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); - + if (!this.setupHoldAction()) { + return; } + if (this.state == STATE_NEAR_GRABBING) { + this.setState(STATE_CONTINUE_NEAR_GRABBING); + } else { + // equipping + Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); + this.startHandGrasp(); + + this.setState(STATE_CONTINUE_EQUIP_BD); + } + + if (this.hand === RIGHT_HAND) { + Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); + } else { + Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); + } + + Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); + Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); this.currentHandControllerTipPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition; @@ -966,7 +974,7 @@ function MyController(hand) { if (this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) { // if less than a 5 seconds left, refresh the actions ttl - Entities.updateAction(this.grabbedEntity, this.actionID, { + var success = Entities.updateAction(this.grabbedEntity, this.actionID, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, @@ -976,7 +984,13 @@ function MyController(hand) { kinematicSetVelocity: true, ignoreIK: this.ignoreIK }); - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + if (success) { + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + } else { + print("continueNearGrabbing -- updateAction failed"); + Entities.deleteAction(this.grabbedEntity, this.actionID); + this.setupHoldAction(); + } } }; @@ -1024,7 +1038,7 @@ function MyController(hand) { return; } } else { - Entities.updateAction(this.grabbedEntity, this.equipSpringID, { + var success = Entities.updateAction(this.grabbedEntity, this.equipSpringID, { targetPosition: targetPosition, linearTimeScale: EQUIP_SPRING_TIMEFRAME, targetRotation: targetRotation, @@ -1032,6 +1046,9 @@ function MyController(hand) { ttl: ACTION_TTL, ignoreIK: ignoreIK }); + if (!success) { + print("pullTowardEquipPosition -- updateActionfailed"); + } } if (Vec3.distance(grabbedProperties.position, targetPosition) < EQUIP_SPRING_SHUTOFF_DISTANCE) { From 036002151d7810c76e386e89262b1b5c9fe35d0e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 22 Dec 2015 12:40:38 -0800 Subject: [PATCH 41/54] call activateBody in prepareForPhysicsSimulation rather than various other places --- interface/src/avatar/AvatarActionHold.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 689d557c48..4dda14e194 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -89,6 +89,8 @@ void AvatarActionHold::prepareForPhysicsSimulation() { // code here for future reference. // _palmRotationFromRigidBody = avatarRotationInverse * palmRotation; }); + + activateBody(); } std::shared_ptr AvatarActionHold::getTarget(glm::quat& rotation, glm::vec3& position) { @@ -197,7 +199,6 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { if (_kinematic) { doKinematicUpdate(deltaTimeStep); } else { - activateBody(); forceBodyNonStatic(); ObjectActionSpring::updateActionWorker(deltaTimeStep); } @@ -247,7 +248,6 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { _previousSet = true; }); - activateBody(); forceBodyNonStatic(); } @@ -344,7 +344,6 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { ownerEntity->setActionDataNeedsTransmit(true); } }); - activateBody(); } return true; @@ -431,6 +430,5 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) { _active = true; }); - activateBody(); forceBodyNonStatic(); } From 9f828448a01dc116d6f132ce19cdfd0c5d64a002 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 07:29:14 -0800 Subject: [PATCH 42/54] add comment --- examples/debugging/queryAACubeInspector.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/debugging/queryAACubeInspector.js b/examples/debugging/queryAACubeInspector.js index 96296a7576..2735617bc1 100644 --- a/examples/debugging/queryAACubeInspector.js +++ b/examples/debugging/queryAACubeInspector.js @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// This script draws an overlay cube around nearby entities to show their queryAABoxes. + Script.include("../libraries/utils.js"); From 9145a8a753953094c32288d12a30d121512233cb Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 07:29:24 -0800 Subject: [PATCH 43/54] back out off-brand change --- examples/controllers/handControllerGrab.js | 98 +++++++++------------- 1 file changed, 40 insertions(+), 58 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index cf9b245993..ed02bd3709 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -1234,39 +1234,16 @@ function MyController(hand) { this.handleSpotlight(this.grabbedEntity); } - var success = Entities.updateAction(this.grabbedEntity, this.actionID, { + Entities.updateAction(this.grabbedEntity, this.actionID, { targetPosition: targetPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, ttl: ACTION_TTL }); - if (success) { - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); - } else { - print("continueDistanceHolding -- updateAction failed"); - } - }; - - this.setupHoldAction = function() { - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: this.offsetPosition, - relativeRotation: this.offsetRotation, - ttl: ACTION_TTL, - kinematic: NEAR_GRABBING_KINEMATIC, - kinematicSetVelocity: true, - ignoreIK: this.ignoreIK - }); - if (this.actionID === NULL_ACTION_ID) { - this.actionID = null; - return false; - } - var now = Date.now(); this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); - return true; + }; this.projectVectorAlongAxis = function(position, axisStart, axisEnd) { @@ -1296,7 +1273,7 @@ function MyController(hand) { return projection - }; + }, this.nearGrabbing = function() { var now = Date.now(); @@ -1340,29 +1317,43 @@ function MyController(hand) { this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); } - if (!this.setupHoldAction()) { - return; - } - - if (this.state == STATE_NEAR_GRABBING) { - this.setState(STATE_CONTINUE_NEAR_GRABBING); + this.actionID = NULL_ACTION_ID; + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: this.offsetPosition, + relativeRotation: this.offsetRotation, + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC, + kinematicSetVelocity: true, + ignoreIK: this.ignoreIK + }); + if (this.actionID === NULL_ACTION_ID) { + this.actionID = null; } else { - // equipping - Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); - this.startHandGrasp(); + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + if (this.state == STATE_NEAR_GRABBING) { + this.setState(STATE_CONTINUE_NEAR_GRABBING); + } else { + // equipping + Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); + this.startHandGrasp(); + + this.setState(STATE_CONTINUE_EQUIP_BD); + } + + if (this.hand === RIGHT_HAND) { + Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); + } else { + Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); + } + + Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); + + Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); - this.setState(STATE_CONTINUE_EQUIP_BD); } - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - - Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); - Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); - this.currentHandControllerTipPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition; @@ -1412,7 +1403,7 @@ function MyController(hand) { if (this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) { // if less than a 5 seconds left, refresh the actions ttl - var success = Entities.updateAction(this.grabbedEntity, this.actionID, { + Entities.updateAction(this.grabbedEntity, this.actionID, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, @@ -1422,13 +1413,7 @@ function MyController(hand) { kinematicSetVelocity: true, ignoreIK: this.ignoreIK }); - if (success) { - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); - } else { - print("continueNearGrabbing -- updateAction failed"); - Entities.deleteAction(this.grabbedEntity, this.actionID); - this.setupHoldAction(); - } + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); } }; @@ -1475,7 +1460,7 @@ function MyController(hand) { return; } } else { - var success = Entities.updateAction(this.grabbedEntity, this.equipSpringID, { + Entities.updateAction(this.grabbedEntity, this.equipSpringID, { targetPosition: targetPosition, linearTimeScale: EQUIP_SPRING_TIMEFRAME, targetRotation: targetRotation, @@ -1483,9 +1468,6 @@ function MyController(hand) { ttl: ACTION_TTL, ignoreIK: ignoreIK }); - if (!success) { - print("pullTowardEquipPosition -- updateActionfailed"); - } } if (Vec3.distance(grabbedProperties.position, targetPosition) < EQUIP_SPRING_SHUTOFF_DISTANCE) { @@ -1867,4 +1849,4 @@ function cleanup() { } Script.scriptEnding.connect(cleanup); -Script.update.connect(update); +Script.update.connect(update); \ No newline at end of file From 86b551c177e05f49b08dab988e89327588678863 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 07:33:50 -0800 Subject: [PATCH 44/54] back out off-brand change --- interface/src/avatar/AvatarActionHold.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 4dda14e194..689d557c48 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -89,8 +89,6 @@ void AvatarActionHold::prepareForPhysicsSimulation() { // code here for future reference. // _palmRotationFromRigidBody = avatarRotationInverse * palmRotation; }); - - activateBody(); } std::shared_ptr AvatarActionHold::getTarget(glm::quat& rotation, glm::vec3& position) { @@ -199,6 +197,7 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { if (_kinematic) { doKinematicUpdate(deltaTimeStep); } else { + activateBody(); forceBodyNonStatic(); ObjectActionSpring::updateActionWorker(deltaTimeStep); } @@ -248,6 +247,7 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { _previousSet = true; }); + activateBody(); forceBodyNonStatic(); } @@ -344,6 +344,7 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { ownerEntity->setActionDataNeedsTransmit(true); } }); + activateBody(); } return true; @@ -430,5 +431,6 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) { _active = true; }); + activateBody(); forceBodyNonStatic(); } From 40a25f859aaf13800f2b28026b21b1225002c129 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 08:00:23 -0800 Subject: [PATCH 45/54] cleanups --- libraries/entities/src/EntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 7a2d01053c..2f15fa7293 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1310,7 +1310,7 @@ bool EntityItem::contains(const glm::vec3& point) const { if (getShapeType() == SHAPE_TYPE_COMPOUND) { bool success; bool result = getAABox(success).contains(point); - return result & success; + return result && success; } else { ShapeInfo info; info.setParams(getShapeType(), glm::vec3(0.5f)); From f5bc58f6061f5df4575a23ae2ddb878a050cac3b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 08:00:31 -0800 Subject: [PATCH 46/54] back out off-brand change --- libraries/entities/src/EntityTree.cpp | 3 +++ libraries/physics/src/ObjectAction.cpp | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 4e8be972ea..fa9b6032b2 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -959,6 +959,9 @@ void EntityTree::fixupMissingParents() { iter.remove(); entity->markAncestorMissing(false); } + } else { + // entity was deleted before we found its parent. + iter.remove(); } } diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index e8e1188dc9..17b565ba21 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -23,15 +23,15 @@ ObjectAction::~ObjectAction() { } void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) { + bool ownerEntityExpired = false; quint64 expiresWhen = 0; - EntityItemPointer ownerEntity = nullptr; withReadLock([&]{ - ownerEntity = _ownerEntity.lock(); + ownerEntityExpired = _ownerEntity.expired(); expiresWhen = _expires; }); - if (!ownerEntity) { + if (ownerEntityExpired) { qDebug() << "warning -- action with no entity removing self from btCollisionWorld."; btDynamicsWorld* dynamicsWorld = static_cast(collisionWorld); if (dynamicsWorld) { @@ -43,8 +43,10 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta if (expiresWhen > 0) { quint64 now = usecTimestampNow(); if (now > expiresWhen) { + EntityItemPointer ownerEntity = nullptr; QUuid myID; withWriteLock([&]{ + ownerEntity = _ownerEntity.lock(); _active = false; myID = getID(); }); From 63293d5838caabc827df3b22a4d8af13c895f15e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 08:07:31 -0800 Subject: [PATCH 47/54] remove commented code --- libraries/shared/src/SpatiallyNestable.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 288bda5dfa..841d8c3d44 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -585,7 +585,6 @@ bool SpatiallyNestable::setPuffedQueryAACube() { 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); - // _queryAACube = AACube(currentAACube.getCorner(), currentAACube.getScale()); _queryAACubeSet = true; getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) { From 41dcc3d52b63db942853f52f9241ea744815b0ad Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 4 Jan 2016 17:24:39 -0800 Subject: [PATCH 48/54] QML dialogs should not consume key events when disabled --- interface/resources/qml/AddressBarDialog.qml | 6 ++++-- interface/resources/qml/ErrorDialog.qml | 3 +++ interface/resources/qml/LoginDialog.qml | 6 ++++-- interface/resources/qml/MessageDialog.qml | 4 ++++ interface/resources/qml/RootMenu.qml | 9 --------- 5 files changed, 15 insertions(+), 13 deletions(-) delete mode 100644 interface/resources/qml/RootMenu.qml diff --git a/interface/resources/qml/AddressBarDialog.qml b/interface/resources/qml/AddressBarDialog.qml index 3852ea3819..d84ea306b8 100644 --- a/interface/resources/qml/AddressBarDialog.qml +++ b/interface/resources/qml/AddressBarDialog.qml @@ -169,8 +169,10 @@ DialogContainer { switch (event.key) { case Qt.Key_Escape: case Qt.Key_Back: - enabled = false - event.accepted = true + if (enabled) { + enabled = false + event.accepted = true + } break case Qt.Key_Enter: case Qt.Key_Return: diff --git a/interface/resources/qml/ErrorDialog.qml b/interface/resources/qml/ErrorDialog.qml index 76d9111d97..4ace671c52 100644 --- a/interface/resources/qml/ErrorDialog.qml +++ b/interface/resources/qml/ErrorDialog.qml @@ -96,6 +96,9 @@ DialogContainer { } Keys.onPressed: { + if (!enabled) { + return + } switch (event.key) { case Qt.Key_Escape: case Qt.Key_Back: diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index 29264fa608..3ce5251771 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -343,8 +343,10 @@ DialogContainer { switch (event.key) { case Qt.Key_Escape: case Qt.Key_Back: - enabled = false - event.accepted = true + if (enabled) { + enabled = false + event.accepted = true + } break case Qt.Key_Enter: case Qt.Key_Return: diff --git a/interface/resources/qml/MessageDialog.qml b/interface/resources/qml/MessageDialog.qml index e8b01df9d0..73fb135ac4 100644 --- a/interface/resources/qml/MessageDialog.qml +++ b/interface/resources/qml/MessageDialog.qml @@ -300,6 +300,10 @@ VrDialog { Keys.onPressed: { + if (!enabled) { + return + } + if (event.modifiers === Qt.ControlModifier) switch (event.key) { case Qt.Key_A: diff --git a/interface/resources/qml/RootMenu.qml b/interface/resources/qml/RootMenu.qml deleted file mode 100644 index b8c81a6589..0000000000 --- a/interface/resources/qml/RootMenu.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Controls 1.3 - -Item { - Menu { - id: root - objectName: "rootMenu" - } -} From e6b59cb0a14eef004df3ef7b0dfbe1cfe85680b9 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 4 Jan 2016 17:26:46 -0800 Subject: [PATCH 49/54] Make it easier for QML dialogs to access the global menu, manipulate the overlay desktop --- interface/resources/qml/Root.qml | 7 ++++++- interface/src/Application.cpp | 21 ++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/Root.qml b/interface/resources/qml/Root.qml index 1b0f09558f..14799f78c0 100644 --- a/interface/resources/qml/Root.qml +++ b/interface/resources/qml/Root.qml @@ -1,11 +1,16 @@ import Hifi 1.0 -import QtQuick 2.3 +import QtQuick 2.5 +import QtQuick.Controls 1.4 // This is our primary 'window' object to which all dialogs and controls will // be childed. Root { id: root + objectName: "desktopRoot" anchors.fill: parent + property var rootMenu: Menu { + objectName: "rootMenu" + } onParentChanged: { forceActiveFocus(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f6350cb8d5..0fbb0523ef 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1173,7 +1173,6 @@ void Application::initializeUi() { offscreenUi->setProxyWindow(_window->windowHandle()); offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); offscreenUi->load("Root.qml"); - offscreenUi->load("RootMenu.qml"); // FIXME either expose so that dialogs can set this themselves or // do better detection in the offscreen UI of what has focus offscreenUi->setNavigationFocused(false); @@ -2033,16 +2032,16 @@ void Application::keyPressEvent(QKeyEvent* event) { break; } - case Qt::Key_Escape: { - getActiveDisplayPlugin()->abandonCalibration(); - if (!event->isAutoRepeat()) { - // this starts the HFCancelEvent - HFBackEvent startBackEvent(HFBackEvent::startType()); - sendEvent(this, &startBackEvent); - } - - break; - } +// case Qt::Key_Escape: { +// getActiveDisplayPlugin()->abandonCalibration(); +// if (!event->isAutoRepeat()) { +// // this starts the HFCancelEvent +// HFBackEvent startBackEvent(HFBackEvent::startType()); +// sendEvent(this, &startBackEvent); +// } +// +// break; +// } default: event->ignore(); From 56ee48a084a102a9970ea562995a31d31dc4da45 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 4 Jan 2016 17:27:07 -0800 Subject: [PATCH 50/54] Working on focus problems --- interface/resources/qml/QmlWindow.qml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interface/resources/qml/QmlWindow.qml b/interface/resources/qml/QmlWindow.qml index 951aa24471..afe165daf4 100644 --- a/interface/resources/qml/QmlWindow.qml +++ b/interface/resources/qml/QmlWindow.qml @@ -43,10 +43,6 @@ VrDialog { focus: true property var dialog: root - onLoaded: { - forceActiveFocus() - } - Keys.onPressed: { console.log("QmlWindow pageLoader keypress") } From 8485c89a0e261919a98f53b4db84e8395cd48606 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 4 Jan 2016 17:41:03 -0800 Subject: [PATCH 51/54] More work on exposing tools to QML overlay windows --- interface/resources/qml/QmlWindow.qml | 1 - interface/resources/qml/controls/DialogBase.qml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/QmlWindow.qml b/interface/resources/qml/QmlWindow.qml index afe165daf4..2d8bf08dc5 100644 --- a/interface/resources/qml/QmlWindow.qml +++ b/interface/resources/qml/QmlWindow.qml @@ -10,7 +10,6 @@ import "styles" VrDialog { id: root - objectName: "topLevelWindow" HifiConstants { id: hifi } title: "QmlWindow" resizable: true diff --git a/interface/resources/qml/controls/DialogBase.qml b/interface/resources/qml/controls/DialogBase.qml index a6616fc731..9fb2a47907 100644 --- a/interface/resources/qml/controls/DialogBase.qml +++ b/interface/resources/qml/controls/DialogBase.qml @@ -5,6 +5,7 @@ import "../styles" Item { id: root + objectName: "topLevelWindow" HifiConstants { id: hifi } implicitHeight: contentImplicitHeight + titleBorder.height + hifi.styles.borderWidth implicitWidth: contentImplicitWidth + hifi.styles.borderWidth * 2 From 4b6f58dcab3242d2b178b10e86106ce9371c77a5 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 4 Jan 2016 17:58:10 -0800 Subject: [PATCH 52/54] Restoring code commented out for debugging --- interface/src/Application.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0fbb0523ef..b323862139 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2032,16 +2032,16 @@ void Application::keyPressEvent(QKeyEvent* event) { break; } -// case Qt::Key_Escape: { -// getActiveDisplayPlugin()->abandonCalibration(); -// if (!event->isAutoRepeat()) { -// // this starts the HFCancelEvent -// HFBackEvent startBackEvent(HFBackEvent::startType()); -// sendEvent(this, &startBackEvent); -// } -// -// break; -// } + case Qt::Key_Escape: { + getActiveDisplayPlugin()->abandonCalibration(); + if (!event->isAutoRepeat()) { + // this starts the HFCancelEvent + HFBackEvent startBackEvent(HFBackEvent::startType()); + sendEvent(this, &startBackEvent); + } + + break; + } default: event->ignore(); From 96f506a98db225816da67dabfc97952d1768b90a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 5 Jan 2016 07:27:27 -0800 Subject: [PATCH 53/54] code review --- libraries/avatars/src/AvatarData.cpp | 10 ++++++++++ libraries/avatars/src/AvatarData.h | 3 +++ .../entities/src/EntityScriptingInterface.cpp | 6 +++--- libraries/physics/src/EntityMotionState.cpp | 4 ++-- libraries/shared/src/SpatiallyNestable.cpp | 14 ++------------ libraries/shared/src/SpatiallyNestable.h | 6 +++--- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index d955808e34..1848845a07 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1648,3 +1648,13 @@ void AvatarData::setPosition(const glm::vec3& position) { void AvatarData::setOrientation(const glm::quat& orientation) { SpatiallyNestable::setOrientation(orientation); } + +glm::quat AvatarData::getAbsoluteJointRotationInObjectFrame(int index) const { + assert(false); + return glm::quat(); +} + +glm::vec3 AvatarData::getAbsoluteJointTranslationInObjectFrame(int index) const { + assert(false); + return glm::vec3(); +} diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 42ecf098b3..c0fe62c7c4 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -356,6 +356,9 @@ public slots: void setJointMappingsFromNetworkReply(); void setSessionUUID(const QUuid& sessionUUID) { setID(sessionUUID); } + virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; + virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; + protected: glm::vec3 _handPosition; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 59aa4dac85..cfb8e0b5a9 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -274,7 +274,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& entity->flagForOwnership(); } } - if (properties.parentRelatedPropertyChanged() && entity->setPuffedQueryAACube()) { + if (properties.parentRelatedPropertyChanged() && entity->computePuffedQueryAACube()) { properties.setQueryAACube(entity->getQueryAACube()); } entity->setLastBroadcast(usecTimestampNow()); @@ -283,8 +283,8 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& // if they've changed. entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { if (descendant->getNestableType() == NestableType::Entity) { - EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); - if (descendant->setPuffedQueryAACube()) { + if (descendant->computePuffedQueryAACube()) { + EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); EntityItemProperties newQueryCubeProperties; newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); queueEntityMessage(PacketType::EntityEdit, descendant->getID(), newQueryCubeProperties); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 430db2b2aa..cd07b4112f 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -470,7 +470,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q properties.setActionData(_serverActionData); } - if (properties.parentRelatedPropertyChanged() && _entity->setPuffedQueryAACube()) { + 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()); } @@ -516,7 +516,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q _entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { if (descendant->getNestableType() == NestableType::Entity) { EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); - if (descendant->setPuffedQueryAACube()) { + if (descendant->computePuffedQueryAACube()) { EntityItemProperties newQueryCubeProperties; newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); entityPacketSender->queueEditEntityMessage(PacketType::EntityEdit, descendant->getID(), newQueryCubeProperties); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 841d8c3d44..07d5ddeeb0 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -497,16 +497,6 @@ const Transform SpatiallyNestable::getAbsoluteJointTransformInObjectFrame(int jo return jointTransformInObjectFrame; } -glm::quat SpatiallyNestable::getAbsoluteJointRotationInObjectFrame(int index) const { - assert(false); - return glm::quat(); -} - -glm::vec3 SpatiallyNestable::getAbsoluteJointTranslationInObjectFrame(int index) const { - assert(false); - return glm::vec3(); -} - SpatiallyNestablePointer SpatiallyNestable::getThisPointer() const { SpatiallyNestableConstPointer constThisPointer = shared_from_this(); SpatiallyNestablePointer thisPointer = std::const_pointer_cast(constThisPointer); // ermahgerd !!! @@ -562,7 +552,7 @@ bool SpatiallyNestable::queryAABoxNeedsUpdate() const { // make sure children are still in their boxes, also. bool childNeedsUpdate = false; getThisPointer()->forEachDescendant([&](SpatiallyNestablePointer descendant) { - if (descendant->queryAABoxNeedsUpdate()) { + if (!childNeedsUpdate && descendant->queryAABoxNeedsUpdate()) { childNeedsUpdate = true; } }); @@ -577,7 +567,7 @@ bool SpatiallyNestable::queryAABoxNeedsUpdate() const { return true; } -bool SpatiallyNestable::setPuffedQueryAACube() { +bool SpatiallyNestable::computePuffedQueryAACube() { if (!queryAABoxNeedsUpdate()) { return false; } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 91fdd84be0..6573c0c2ce 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -69,7 +69,7 @@ public: virtual void setOrientation(const glm::quat& orientation); virtual AACube getMaximumAACube(bool& success) const; - virtual bool setPuffedQueryAACube(); + virtual bool computePuffedQueryAACube(); virtual void setQueryAACube(const AACube& queryAACube); virtual bool queryAABoxNeedsUpdate() const; @@ -102,8 +102,8 @@ public: // this object's frame virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const; - virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const; - virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const; + virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const = 0; + virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const = 0; SpatiallyNestablePointer getThisPointer() const; From 900a0f7f086bea0b4d6f0e8be8759ce5bb08fdf6 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 5 Jan 2016 09:16:44 -0800 Subject: [PATCH 54/54] Trigger selection is too twitchy --- interface/resources/controllers/standard_navigation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/controllers/standard_navigation.json b/interface/resources/controllers/standard_navigation.json index c3b30e8607..208970f030 100644 --- a/interface/resources/controllers/standard_navigation.json +++ b/interface/resources/controllers/standard_navigation.json @@ -11,7 +11,7 @@ { "from": "Standard.DR", "to": "Actions.UiNavLateral" }, { "from": "Standard.LB", "to": "Actions.UiNavGroup","filters": "invert" }, { "from": "Standard.RB", "to": "Actions.UiNavGroup" }, - { "from": [ "Standard.A", "Standard.X", "Standard.RT", "Standard.LT" ], "to": "Actions.UiNavSelect" }, + { "from": [ "Standard.A", "Standard.X" ], "to": "Actions.UiNavSelect" }, { "from": [ "Standard.B", "Standard.Y", "Standard.RightPrimaryThumb", "Standard.LeftPrimaryThumb" ], "to": "Actions.UiNavBack" }, { "from": [ "Standard.RT", "Standard.LT" ],