From e4e86c245e8291640d6261e3df821478f19d375c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 31 Jul 2016 14:11:56 -0700 Subject: [PATCH 01/13] 3d overlays can be children of entities or avatars --- interface/src/ui/overlays/Base3DOverlay.cpp | 117 ++++++++++++++---- interface/src/ui/overlays/Base3DOverlay.h | 16 +-- interface/src/ui/overlays/Circle3DOverlay.cpp | 6 +- interface/src/ui/overlays/Image3DOverlay.cpp | 15 ++- interface/src/ui/overlays/Line3DOverlay.cpp | 6 +- interface/src/ui/overlays/Overlay.cpp | 4 +- interface/src/ui/overlays/Planar3DOverlay.cpp | 6 +- interface/src/ui/overlays/Sphere3DOverlay.cpp | 2 +- interface/src/ui/overlays/Text3DOverlay.cpp | 31 +++-- interface/src/ui/overlays/Volume3DOverlay.cpp | 2 +- interface/src/ui/overlays/Web3DOverlay.cpp | 16 ++- libraries/entities/src/EntityItem.h | 4 - libraries/shared/src/SpatiallyNestable.cpp | 30 ++++- libraries/shared/src/SpatiallyNestable.h | 18 ++- 14 files changed, 193 insertions(+), 80 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 94533137ad..dc97af5300 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -21,6 +21,7 @@ const bool DEFAULT_IS_SOLID = false; const bool DEFAULT_IS_DASHED_LINE = false; Base3DOverlay::Base3DOverlay() : + SpatiallyNestable(NestableType::Overlay, QUuid::createUuid()), _lineWidth(DEFAULT_LINE_WIDTH), _isSolid(DEFAULT_IS_SOLID), _isDashedLine(DEFAULT_IS_DASHED_LINE), @@ -31,15 +32,68 @@ Base3DOverlay::Base3DOverlay() : Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : Overlay(base3DOverlay), - _transform(base3DOverlay->_transform), + SpatiallyNestable(NestableType::Overlay, QUuid::createUuid()), _lineWidth(base3DOverlay->_lineWidth), _isSolid(base3DOverlay->_isSolid), _isDashedLine(base3DOverlay->_isDashedLine), _ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection), _drawInFront(base3DOverlay->_drawInFront) { + setTransform(base3DOverlay->getTransform()); } -void Base3DOverlay::setProperties(const QVariantMap& properties) { + +QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties, + const QUuid& currentParentID, + int currentParentJointIndex) { + // the position and rotation in _transform are relative to the parent (aka local). The versions coming from + // scripts are in world-frame, unless localPosition or localRotation are used. Patch up the properties + // so that "position" and "rotation" are relative-to-parent values. + QVariantMap result = properties; + QUuid parentID = result["parentID"].isValid() ? QUuid(result["parentID"].toString()) : currentParentID; + int parentJointIndex = + result["parentJointIndex"].isValid() ? result["parentJointIndex"].toInt() : currentParentJointIndex; + bool success; + + // carry over some legacy keys + if (!result["position"].isValid() && !result["localPosition"].isValid()) { + if (result["p1"].isValid()) { + result["position"] = result["p1"]; + } else if (result["point"].isValid()) { + result["position"] = result["point"]; + } else if (result["start"].isValid()) { + result["position"] = result["start"]; + } + } + if (!result["orientation"].isValid() && result["rotation"].isValid()) { + result["orientation"] = result["rotation"]; + } + if (!result["localOrientation"].isValid() && result["localRotation"].isValid()) { + result["localOrientation"] = result["localRotation"]; + } + + // make "position" and "orientation" be relative-to-parent + if (result["localPosition"].isValid()) { + result["position"] = result["localPosition"]; + } else if (result["position"].isValid()) { + glm::vec3 localPosition = SpatiallyNestable::worldToLocal(vec3FromVariant(result["position"]), + parentID, parentJointIndex, success); + result["position"] = vec3toVariant(localPosition); + } + + if (result["localOrientation"].isValid()) { + result["orientation"] = result["localOrientation"]; + } else if (result["orientation"].isValid()) { + glm::quat localOrientation = SpatiallyNestable::worldToLocal(quatFromVariant(result["orientation"]), + parentID, parentJointIndex, success); + result["orientation"] = quatToVariant(localOrientation); + } + + return result; +} + +void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { + QVariantMap properties = + convertOverlayLocationFromScriptSemantics(originalProperties, getParentID(), getParentJointIndex()); Overlay::setProperties(properties); bool needRenderItemUpdate = false; @@ -52,17 +106,12 @@ void Base3DOverlay::setProperties(const QVariantMap& properties) { needRenderItemUpdate = true; } - auto position = properties["position"]; - - // if "position" property was not there, check to see if they included aliases: point, p1 - if (!position.isValid()) { - position = properties["p1"]; - if (!position.isValid()) { - position = properties["point"]; - } + if (properties["position"].isValid()) { + setPosition(vec3FromVariant(properties["position"])); + needRenderItemUpdate = true; } - if (position.isValid()) { - setPosition(vec3FromVariant(position)); + if (properties["orientation"].isValid()) { + setOrientation(quatFromVariant(properties["orientation"])); needRenderItemUpdate = true; } @@ -71,13 +120,6 @@ void Base3DOverlay::setProperties(const QVariantMap& properties) { needRenderItemUpdate = true; } - auto rotation = properties["rotation"]; - - if (rotation.isValid()) { - setRotation(quatFromVariant(rotation)); - needRenderItemUpdate = true; - } - if (properties["isSolid"].isValid()) { setIsSolid(properties["isSolid"].toBool()); } @@ -107,6 +149,13 @@ void Base3DOverlay::setProperties(const QVariantMap& properties) { setIgnoreRayIntersection(properties["ignoreRayIntersection"].toBool()); } + if (properties["parentID"].isValid()) { + setParentID(QUuid(properties["parentID"].toString())); + } + if (properties["parentJointIndex"].isValid()) { + setParentJointIndex(properties["parentJointIndex"].toInt()); + } + // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { auto itemID = getRenderItemID(); @@ -123,12 +172,18 @@ QVariant Base3DOverlay::getProperty(const QString& property) { if (property == "position" || property == "start" || property == "p1" || property == "point") { return vec3toVariant(getPosition()); } + if (property == "localPosition") { + return vec3toVariant(getLocalPosition()); + } + if (property == "rotation" || property == "orientation") { + return quatToVariant(getOrientation()); + } + if (property == "localRotation" || property == "localOrientation") { + return quatToVariant(getLocalOrientation()); + } if (property == "lineWidth") { return _lineWidth; } - if (property == "rotation") { - return quatToVariant(getRotation()); - } if (property == "isSolid" || property == "isFilled" || property == "solid" || property == "filed") { return _isSolid; } @@ -144,6 +199,12 @@ QVariant Base3DOverlay::getProperty(const QString& property) { if (property == "drawInFront") { return _drawInFront; } + if (property == "parentID") { + return getParentID(); + } + if (property == "parentJointIndex") { + return getParentJointIndex(); + } return Overlay::getProperty(property); } @@ -152,3 +213,15 @@ bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3 float& distance, BoxFace& face, glm::vec3& surfaceNormal) { return false; } + +void Base3DOverlay::locationChanged(bool tellPhysics) { + auto itemID = getRenderItemID(); + if (render::Item::isValidID(itemID)) { + render::ScenePointer scene = qApp->getMain3DScene(); + render::PendingChanges pendingChanges; + pendingChanges.updateItem(itemID); + scene->enqueuePendingChanges(pendingChanges); + } + // Overlays can't currently have children. + // SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also +} diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index e602dec48c..551c1c3384 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -12,10 +12,11 @@ #define hifi_Base3DOverlay_h #include +#include #include "Overlay.h" -class Base3DOverlay : public Overlay { +class Base3DOverlay : public Overlay, public SpatiallyNestable { Q_OBJECT public: @@ -24,12 +25,9 @@ public: // getters virtual bool is3D() const override { return true; } - const glm::vec3& getPosition() const { return _transform.getTranslation(); } - const glm::quat& getRotation() const { return _transform.getRotation(); } - const glm::vec3& getScale() const { return _transform.getScale(); } // TODO: consider implementing registration points in this class - const glm::vec3& getCenter() const { return getPosition(); } + glm::vec3 getCenter() const { return getPosition(); } float getLineWidth() const { return _lineWidth; } bool getIsSolid() const { return _isSolid; } @@ -38,12 +36,6 @@ public: bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; } bool getDrawInFront() const { return _drawInFront; } - // setters - void setPosition(const glm::vec3& value) { _transform.setTranslation(value); } - void setRotation(const glm::quat& value) { _transform.setRotation(value); } - void setScale(float value) { _transform.setScale(value); } - void setScale(const glm::vec3& value) { _transform.setScale(value); } - void setLineWidth(float lineWidth) { _lineWidth = lineWidth; } void setIsSolid(bool isSolid) { _isSolid = isSolid; } void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; } @@ -64,7 +56,7 @@ public: } protected: - Transform _transform; + virtual void locationChanged(bool tellPhysics = true) override; float _lineWidth; bool _isSolid; diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 6ebfd5c71c..e9ee997aac 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -69,17 +69,17 @@ void Circle3DOverlay::render(RenderArgs* args) { // FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround - auto transform = _transform; + auto transform = getTransform(); transform.postScale(glm::vec3(getDimensions(), 1.0f)); batch.setModelTransform(transform); - + // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise // we just draw a line... if (getIsSolid()) { if (!_quadVerticesID) { _quadVerticesID = geometryCache->allocateID(); } - + if (geometryChanged) { QVector points; QVector colors; diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index d59e552779..d05eaac07c 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -37,7 +37,9 @@ Image3DOverlay::Image3DOverlay(const Image3DOverlay* image3DOverlay) : } void Image3DOverlay::update(float deltatime) { - applyTransformTo(_transform); + Transform transform = getTransform(); + applyTransformTo(transform); + setTransform(transform); } void Image3DOverlay::render(RenderArgs* args) { @@ -86,13 +88,14 @@ void Image3DOverlay::render(RenderArgs* args) { xColor color = getColor(); float alpha = getAlpha(); - applyTransformTo(_transform, true); - Transform transform = _transform; + Transform transform = getTransform(); + applyTransformTo(transform, true); + setTransform(transform); transform.postScale(glm::vec3(getDimensions(), 1.0f)); batch->setModelTransform(transform); batch->setResourceTexture(0, _texture->getGPUTexture()); - + DependencyManager::get()->renderQuad( *batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha) @@ -187,7 +190,9 @@ bool Image3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec float& distance, BoxFace& face, glm::vec3& surfaceNormal) { if (_texture && _texture->isLoaded()) { // Make sure position and rotation is updated. - applyTransformTo(_transform, true); + Transform transform; + applyTransformTo(transform, true); + setTransform(transform); // Produce the dimensions of the overlay based on the image's aspect ratio and the overlay's scale. bool isNull = _fromImage.isNull(); diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index c9a8b19f6a..85962d38b1 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -35,8 +35,8 @@ AABox Line3DOverlay::getBounds() const { auto extents = Extents{}; extents.addPoint(_start); extents.addPoint(_end); - extents.transform(_transform); - + extents.transform(getTransform()); + return AABox(extents); } @@ -52,7 +52,7 @@ void Line3DOverlay::render(RenderArgs* args) { auto batch = args->_batch; if (batch) { - batch->setModelTransform(_transform); + batch->setModelTransform(getTransform()); auto geometryCache = DependencyManager::get(); if (getIsDashedLine()) { diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 5d2c315a92..82b90d228c 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -77,7 +77,7 @@ void Overlay::setProperties(const QVariantMap& properties) { if (properties["pulsePeriod"].isValid()) { setPulsePeriod(properties["pulsePeriod"].toFloat()); } - + if (properties["alphaPulse"].isValid()) { setAlphaPulse(properties["alphaPulse"].toFloat()); } @@ -90,7 +90,7 @@ void Overlay::setProperties(const QVariantMap& properties) { bool visible = properties["visible"].toBool(); setVisible(visible); } - + if (properties["anchor"].isValid()) { QString property = properties["anchor"].toString(); if (property == "MyAvatar") { diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index c580464e16..58d72b100b 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -28,10 +28,10 @@ Planar3DOverlay::Planar3DOverlay(const Planar3DOverlay* planar3DOverlay) : AABox Planar3DOverlay::getBounds() const { auto halfDimensions = glm::vec3{_dimensions / 2.0f, 0.01f}; - + auto extents = Extents{-halfDimensions, halfDimensions}; - extents.transform(_transform); - + extents.transform(getTransform()); + return AABox(extents); } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index bbdd886d11..b925265cde 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -39,7 +39,7 @@ void Sphere3DOverlay::render(RenderArgs* args) { auto batch = args->_batch; if (batch) { - Transform transform = _transform; + Transform transform = getTransform(); transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE); batch->setModelTransform(transform); diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 0ae1c306ba..1fbf6a9bbd 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -65,44 +65,47 @@ xColor Text3DOverlay::getBackgroundColor() { } void Text3DOverlay::update(float deltatime) { - applyTransformTo(_transform); + Transform transform = getTransform(); + applyTransformTo(transform); + setTransform(transform); } void Text3DOverlay::render(RenderArgs* args) { if (!_visible || !getParentVisible()) { return; // do nothing if we're not visible } - + Q_ASSERT(args->_batch); auto& batch = *args->_batch; - - applyTransformTo(_transform, true); - batch.setModelTransform(_transform); + + Transform transform = getTransform(); + applyTransformTo(transform, true); + setTransform(transform); + batch.setModelTransform(transform); const float MAX_COLOR = 255.0f; xColor backgroundColor = getBackgroundColor(); glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR, getBackgroundAlpha()); - + glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; - + const float SLIGHTLY_BEHIND = -0.001f; - + glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, quadColor); - + // Same font properties as textSize() float maxHeight = (float)_textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO; - + float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight; - + glm::vec2 clipMinimum(0.0f, 0.0f); glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor, (dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor); - Transform transform = _transform; transform.postTranslate(glm::vec3(-(halfDimensions.x - _leftMargin), halfDimensions.y - _topMargin, 0.001f)); transform.setScale(scaleFactor); @@ -222,6 +225,8 @@ QSizeF Text3DOverlay::textSize(const QString& text) const { bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3 &direction, float &distance, BoxFace &face, glm::vec3& surfaceNormal) { - applyTransformTo(_transform, true); + Transform transform = getTransform(); + applyTransformTo(transform, true); + setTransform(transform); return Billboard3DOverlay::findRayIntersection(origin, direction, distance, face, surfaceNormal); } diff --git a/interface/src/ui/overlays/Volume3DOverlay.cpp b/interface/src/ui/overlays/Volume3DOverlay.cpp index 563198c976..ad61e28bc7 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.cpp +++ b/interface/src/ui/overlays/Volume3DOverlay.cpp @@ -56,7 +56,7 @@ bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve float& distance, BoxFace& face, glm::vec3& surfaceNormal) { // extents is the entity relative, scaled, centered extents of the entity glm::mat4 worldToEntityMatrix; - _transform.getInverseMatrix(worldToEntityMatrix); + getTransform().getInverseMatrix(worldToEntityMatrix); glm::vec3 overlayFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f)); glm::vec3 overlayFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f)); diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 1c84e71fa7..1b9adbfa95 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -47,7 +47,7 @@ Web3DOverlay::~Web3DOverlay() { _webSurface->disconnect(_connection); // The lifetime of the QML surface MUST be managed by the main thread // Additionally, we MUST use local variables copied by value, rather than - // member variables, since they would implicitly refer to a this that + // member variables, since they would implicitly refer to a this that // is no longer valid auto webSurface = _webSurface; AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] { @@ -57,7 +57,9 @@ Web3DOverlay::~Web3DOverlay() { } void Web3DOverlay::update(float deltatime) { - applyTransformTo(_transform); + Transform transform = getTransform(); + applyTransformTo(transform); + setTransform(transform); } void Web3DOverlay::render(RenderArgs* args) { @@ -85,8 +87,9 @@ void Web3DOverlay::render(RenderArgs* args) { vec2 halfSize = size / 2.0f; vec4 color(toGlm(getColor()), getAlpha()); - applyTransformTo(_transform, true); - Transform transform = _transform; + Transform transform = getTransform(); + applyTransformTo(transform, true); + setTransform(transform); if (glm::length2(getDimensions()) != 1.0f) { transform.postScale(vec3(getDimensions(), 1.0f)); } @@ -165,7 +168,10 @@ bool Web3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& // FIXME - face and surfaceNormal not being returned // Make sure position and rotation is updated. - applyTransformTo(_transform, true); + Transform transform; + applyTransformTo(transform, true); + setTransform(transform); + vec2 size = _resolution / _dpi * INCHES_TO_METERS * vec2(getDimensions()); // Produce the dimensions of the overlay based on the image's aspect ratio and the overlay's scale. return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), size, distance); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 9fa13690f1..7ee80e73af 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -321,10 +321,6 @@ public: /// return preferred shape type (actual physical shape may differ) virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; } - // these are only needed because the names don't match - virtual const glm::quat getRotation() const { return getOrientation(); } - virtual void setRotation(glm::quat orientation) { setOrientation(orientation); } - // updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags virtual void updateRegistrationPoint(const glm::vec3& value); void updatePosition(const glm::vec3& value); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 2a3cb4af47..41b1460619 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -513,6 +513,15 @@ const Transform SpatiallyNestable::getTransform(bool& success, int depth) const return result; } +const Transform SpatiallyNestable::getTransform() const { + bool success; + Transform result = getTransform(success); + if (!success) { + qDebug() << "getTransform failed for" << getID(); + } + return result; +} + const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, int depth) 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. @@ -558,6 +567,12 @@ void SpatiallyNestable::setTransform(const Transform& transform, bool& success) } } +bool SpatiallyNestable::setTransform(const Transform& transform) { + bool success; + setTransform(transform, success); + return success; +} + glm::vec3 SpatiallyNestable::getScale() const { // TODO: scale glm::vec3 result; @@ -575,7 +590,7 @@ glm::vec3 SpatiallyNestable::getScale(int jointIndex) const { void SpatiallyNestable::setScale(const glm::vec3& scale) { // guard against introducing NaN into the transform if (isNaN(scale)) { - qDebug() << "SpatiallyNestable::setLocalScale -- scale contains NaN"; + qDebug() << "SpatiallyNestable::setScale -- scale contains NaN"; return; } // TODO: scale @@ -585,6 +600,19 @@ void SpatiallyNestable::setScale(const glm::vec3& scale) { dimensionsChanged(); } +void SpatiallyNestable::setScale(float value) { + // guard against introducing NaN into the transform + if (value <= 0.0f) { + qDebug() << "SpatiallyNestable::setScale -- scale is zero or negative value"; + return; + } + // TODO: scale + _transformLock.withWriteLock([&] { + _transform.setScale(value); + }); + dimensionsChanged(); +} + const Transform SpatiallyNestable::getLocalTransform() const { Transform result; _transformLock.withReadLock([&] { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index c2563a1188..a579c0dfe4 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -28,7 +28,8 @@ using SpatiallyNestableConstPointer = std::shared_ptr; enum class NestableType { Entity, - Avatar + Avatar, + Overlay }; class SpatiallyNestable : public std::enable_shared_from_this { @@ -53,7 +54,9 @@ public: // world frame virtual const Transform getTransform(bool& success, int depth = 0) const; + virtual const Transform getTransform() const; virtual void setTransform(const Transform& transform, bool& success); + virtual bool setTransform(const Transform& transform); virtual Transform getParentTransform(bool& success, int depth = 0) const; @@ -68,6 +71,10 @@ public: virtual void setOrientation(const glm::quat& orientation, bool& success, bool tellPhysics = true); virtual void setOrientation(const glm::quat& orientation); + // these are here because some older code uses rotation rather than orientation + virtual const glm::quat getRotation() const { return getOrientation(); } + virtual void setRotation(glm::quat orientation) { setOrientation(orientation); } + virtual glm::vec3 getVelocity(bool& success) const; virtual glm::vec3 getVelocity() const; virtual void setVelocity(const glm::vec3& velocity, bool& success); @@ -91,6 +98,7 @@ public: virtual glm::vec3 getScale() const; virtual void setScale(const glm::vec3& scale); + virtual void setScale(float value); // get world-frame values for a specific joint virtual const Transform getTransform(int jointIndex, bool& success, int depth = 0) const; @@ -123,10 +131,10 @@ public: // this object's frame virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const; - virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const = 0; - virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const = 0; - virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) = 0; - virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) = 0; + virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { return glm::quat(); } + virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { return glm::vec3(); } + virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { return false; } + virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) {return false; } SpatiallyNestablePointer getThisPointer() const; From 627048db845f7b957e1ff18df73f4b535f37cb67 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 31 Jul 2016 16:36:14 -0700 Subject: [PATCH 02/13] pull missing location properties from overlay --- interface/src/ui/overlays/Base3DOverlay.cpp | 67 +++++++++++++-------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index dc97af5300..b6f1c1eadc 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -42,35 +42,15 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : setTransform(base3DOverlay->getTransform()); } -QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties, - const QUuid& currentParentID, - int currentParentJointIndex) { +QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties) { // the position and rotation in _transform are relative to the parent (aka local). The versions coming from // scripts are in world-frame, unless localPosition or localRotation are used. Patch up the properties // so that "position" and "rotation" are relative-to-parent values. QVariantMap result = properties; - QUuid parentID = result["parentID"].isValid() ? QUuid(result["parentID"].toString()) : currentParentID; - int parentJointIndex = - result["parentJointIndex"].isValid() ? result["parentJointIndex"].toInt() : currentParentJointIndex; + QUuid parentID = result["parentID"].isValid() ? QUuid(result["parentID"].toString()) : QUuid(); + int parentJointIndex = result["parentJointIndex"].isValid() ? result["parentJointIndex"].toInt() : -1; bool success; - // carry over some legacy keys - if (!result["position"].isValid() && !result["localPosition"].isValid()) { - if (result["p1"].isValid()) { - result["position"] = result["p1"]; - } else if (result["point"].isValid()) { - result["position"] = result["point"]; - } else if (result["start"].isValid()) { - result["position"] = result["start"]; - } - } - if (!result["orientation"].isValid() && result["rotation"].isValid()) { - result["orientation"] = result["rotation"]; - } - if (!result["localOrientation"].isValid() && result["localRotation"].isValid()) { - result["localOrientation"] = result["localRotation"]; - } - // make "position" and "orientation" be relative-to-parent if (result["localPosition"].isValid()) { result["position"] = result["localPosition"]; @@ -92,8 +72,45 @@ QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& propert } void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { - QVariantMap properties = - convertOverlayLocationFromScriptSemantics(originalProperties, getParentID(), getParentJointIndex()); + QVariantMap properties = originalProperties; + + // carry over some legacy keys + if (!properties["position"].isValid() && !properties["localPosition"].isValid()) { + if (properties["p1"].isValid()) { + properties["position"] = properties["p1"]; + } else if (properties["point"].isValid()) { + properties["position"] = properties["point"]; + } else if (properties["start"].isValid()) { + properties["position"] = properties["start"]; + } + } + if (!properties["orientation"].isValid() && properties["rotation"].isValid()) { + properties["orientation"] = properties["rotation"]; + } + if (!properties["localOrientation"].isValid() && properties["localRotation"].isValid()) { + properties["localOrientation"] = properties["localRotation"]; + } + + // All of parentID, parentJointIndex, position, orientation are needed to make sense of any of them. + // If any of these changed, pull any missing properties from the overlay. + if (properties["parentID"].isValid() || properties["parentJointIndex"].isValid() || + properties["position"].isValid() || properties["localPosition"].isValid() || + properties["orientation"].isValid() || properties["localOrientation"].isValid()) { + if (!properties["parentID"].isValid()) { + properties["parentID"] = getParentID(); + } + if (!properties["parentJointIndex"].isValid()) { + properties["parentJointIndex"] = getParentJointIndex(); + } + if (!properties["position"].isValid() && !properties["localPosition"].isValid()) { + properties["position"] = vec3toVariant(getPosition()); + } + if (!properties["orientation"].isValid() || !properties["localOrientation"].isValid()) { + properties["orientation"] = quatToVariant(getOrientation()); + } + } + + properties = convertOverlayLocationFromScriptSemantics(properties); Overlay::setProperties(properties); bool needRenderItemUpdate = false; From 8102ea4b8ee3f2eddbd21bb889c277fb1db9a62f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Aug 2016 07:48:44 -0700 Subject: [PATCH 03/13] don't call locationChanged or dimensionsChanged when they didn't --- libraries/shared/src/SpatiallyNestable.cpp | 111 ++++++++++++++++----- 1 file changed, 87 insertions(+), 24 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 41b1460619..6a9cdd0935 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -313,17 +313,20 @@ void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success, bo success = false; return; } + + bool changed = false; Transform parentTransform = getParentTransform(success); Transform myWorldTransform; _transformLock.withWriteLock([&] { Transform::mult(myWorldTransform, parentTransform, _transform); - myWorldTransform.setTranslation(position); - Transform::inverseMult(_transform, parentTransform, myWorldTransform); + if (myWorldTransform.getTranslation() != position) { + changed = true; + myWorldTransform.setTranslation(position); + Transform::inverseMult(_transform, parentTransform, myWorldTransform); + } }); - if (success) { + if (success && changed) { locationChanged(tellPhysics); - } else { - qDebug() << "setPosition failed for" << getID(); } } @@ -363,14 +366,18 @@ void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& succe return; } + bool changed = false; Transform parentTransform = getParentTransform(success); Transform myWorldTransform; _transformLock.withWriteLock([&] { Transform::mult(myWorldTransform, parentTransform, _transform); - myWorldTransform.setRotation(orientation); - Transform::inverseMult(_transform, parentTransform, myWorldTransform); + if (myWorldTransform.getRotation() != orientation) { + changed = true; + myWorldTransform.setRotation(orientation); + Transform::inverseMult(_transform, parentTransform, myWorldTransform); + } }); - if (success) { + if (success && changed) { locationChanged(tellPhysics); } } @@ -558,11 +565,17 @@ void SpatiallyNestable::setTransform(const Transform& transform, bool& success) success = false; return; } + + bool changed = false; Transform parentTransform = getParentTransform(success); _transformLock.withWriteLock([&] { + Transform beforeTransform = _transform; Transform::inverseMult(_transform, parentTransform, transform); + if (_transform != beforeTransform) { + changed = true; + } }); - if (success) { + if (success && changed) { locationChanged(); } } @@ -593,11 +606,18 @@ void SpatiallyNestable::setScale(const glm::vec3& scale) { qDebug() << "SpatiallyNestable::setScale -- scale contains NaN"; return; } + + bool changed = false; // TODO: scale _transformLock.withWriteLock([&] { - _transform.setScale(scale); + if (_transform.getScale() != scale) { + _transform.setScale(scale); + changed = true; + } }); - dimensionsChanged(); + if (changed) { + dimensionsChanged(); + } } void SpatiallyNestable::setScale(float value) { @@ -606,11 +626,20 @@ void SpatiallyNestable::setScale(float value) { qDebug() << "SpatiallyNestable::setScale -- scale is zero or negative value"; return; } + + bool changed = false; // TODO: scale _transformLock.withWriteLock([&] { + glm::vec3 beforeScale = _transform.getScale(); _transform.setScale(value); + if (_transform.getScale() != beforeScale) { + changed = true; + } }); - dimensionsChanged(); + + if (changed) { + dimensionsChanged(); + } } const Transform SpatiallyNestable::getLocalTransform() const { @@ -627,10 +656,18 @@ void SpatiallyNestable::setLocalTransform(const Transform& transform) { qDebug() << "SpatiallyNestable::setLocalTransform -- transform contains NaN"; return; } + + bool changed = false; _transformLock.withWriteLock([&] { - _transform = transform; + if (_transform != transform) { + _transform = transform; + changed = true; + } }); - locationChanged(); + + if (changed) { + locationChanged(); + } } glm::vec3 SpatiallyNestable::getLocalPosition() const { @@ -647,10 +684,16 @@ void SpatiallyNestable::setLocalPosition(const glm::vec3& position, bool tellPhy qDebug() << "SpatiallyNestable::setLocalPosition -- position contains NaN"; return; } + bool changed = false; _transformLock.withWriteLock([&] { - _transform.setTranslation(position); + if (_transform.getTranslation() != position) { + _transform.setTranslation(position); + changed = true; + } }); - locationChanged(tellPhysics); + if (changed) { + locationChanged(tellPhysics); + } } glm::quat SpatiallyNestable::getLocalOrientation() const { @@ -667,10 +710,16 @@ void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) { qDebug() << "SpatiallyNestable::setLocalOrientation -- orientation contains NaN"; return; } + bool changed = false; _transformLock.withWriteLock([&] { - _transform.setRotation(orientation); + if (_transform.getRotation() != orientation) { + _transform.setRotation(orientation); + changed = true; + } }); - locationChanged(); + if (changed) { + locationChanged(); + } } glm::vec3 SpatiallyNestable::getLocalVelocity() const { @@ -716,9 +765,14 @@ void SpatiallyNestable::setLocalScale(const glm::vec3& scale) { qDebug() << "SpatiallyNestable::setLocalScale -- scale contains NaN"; return; } + + bool changed = false; // TODO: scale _transformLock.withWriteLock([&] { - _transform.setScale(scale); + if (_transform.getScale() != scale) { + _transform.setScale(scale); + changed = true; + } }); dimensionsChanged(); } @@ -914,12 +968,18 @@ void SpatiallyNestable::getLocalTransformAndVelocities( } void SpatiallyNestable::setLocalTransformAndVelocities( - const Transform& localTransform, - const glm::vec3& localVelocity, - const glm::vec3& localAngularVelocity) { + const Transform& localTransform, + const glm::vec3& localVelocity, + const glm::vec3& localAngularVelocity) { + + bool changed = false; + // transform _transformLock.withWriteLock([&] { - _transform = localTransform; + if (_transform != localTransform) { + _transform = localTransform; + changed = true; + } }); // linear velocity _velocityLock.withWriteLock([&] { @@ -929,5 +989,8 @@ void SpatiallyNestable::setLocalTransformAndVelocities( _angularVelocityLock.withWriteLock([&] { _angularVelocity = localAngularVelocity; }); - locationChanged(false); + + if (changed) { + locationChanged(false); + } } From bddff3341acae693741462551f7e3a4141c62f7b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Aug 2016 07:49:22 -0700 Subject: [PATCH 04/13] angry De Morgan --- interface/src/ui/overlays/Base3DOverlay.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index b6f1c1eadc..0dbbe16c3f 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -105,7 +105,7 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { if (!properties["position"].isValid() && !properties["localPosition"].isValid()) { properties["position"] = vec3toVariant(getPosition()); } - if (!properties["orientation"].isValid() || !properties["localOrientation"].isValid()) { + if (!properties["orientation"].isValid() && !properties["localOrientation"].isValid()) { properties["orientation"] = quatToVariant(getOrientation()); } } @@ -168,9 +168,11 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { if (properties["parentID"].isValid()) { setParentID(QUuid(properties["parentID"].toString())); + needRenderItemUpdate = true; } if (properties["parentJointIndex"].isValid()) { setParentJointIndex(properties["parentJointIndex"].toInt()); + needRenderItemUpdate = true; } // Communicate changes to the renderItem if needed From 182829e64c01f519bf8f71a11204736359dcf2b2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Aug 2016 07:49:57 -0700 Subject: [PATCH 05/13] get transform once rather than 3 times --- interface/src/ui/overlays/Image3DOverlay.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index d05eaac07c..e22a0826d7 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -190,7 +190,7 @@ bool Image3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec float& distance, BoxFace& face, glm::vec3& surfaceNormal) { if (_texture && _texture->isLoaded()) { // Make sure position and rotation is updated. - Transform transform; + Transform transform = getTransform(); applyTransformTo(transform, true); setTransform(transform); @@ -202,7 +202,10 @@ bool Image3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec glm::vec2 dimensions = _dimensions * glm::vec2(width / maxSize, height / maxSize); // FIXME - face and surfaceNormal not being set - return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), dimensions, distance); + return findRayRectangleIntersection(origin, direction, + transform.getRotation(), + transform.getTranslation(), + dimensions, distance); } return false; From 2d88e74841838ebb2c7fe04044fcb550d0f09575 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Aug 2016 07:50:12 -0700 Subject: [PATCH 06/13] added operator!= for Transform class --- libraries/shared/src/Transform.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/shared/src/Transform.h b/libraries/shared/src/Transform.h index 1e1d10c54b..38d47695f7 100644 --- a/libraries/shared/src/Transform.h +++ b/libraries/shared/src/Transform.h @@ -89,6 +89,10 @@ public: return _rotation == other._rotation && _scale == other._scale && _translation == other._translation; } + bool operator!=(const Transform& other) const { + return _rotation != other._rotation || _scale != other._scale || _translation != other._translation; + } + Transform& setIdentity(); const Vec3& getTranslation() const; From 6f3146f872b0313fccb5a812050c06f94d6112c9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Aug 2016 08:00:51 -0700 Subject: [PATCH 07/13] oops, position and rotation are local, by this point --- interface/src/ui/overlays/Base3DOverlay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 0dbbe16c3f..a5b5a2dd72 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -124,11 +124,11 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { } if (properties["position"].isValid()) { - setPosition(vec3FromVariant(properties["position"])); + setLocalPosition(vec3FromVariant(properties["position"])); needRenderItemUpdate = true; } if (properties["orientation"].isValid()) { - setOrientation(quatFromVariant(properties["orientation"])); + setLocalOrientation(quatFromVariant(properties["orientation"])); needRenderItemUpdate = true; } From 70becfaff1820b08dc73582e7b46bb2920875429 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Aug 2016 08:20:24 -0700 Subject: [PATCH 08/13] avoid some unneeded SpatiallyNestable transform-locks --- interface/src/ui/overlays/Image3DOverlay.cpp | 13 ++++++++----- interface/src/ui/overlays/Text3DOverlay.cpp | 8 +++++--- interface/src/ui/overlays/Web3DOverlay.cpp | 8 +++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index e22a0826d7..a384c992ad 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -37,9 +37,11 @@ Image3DOverlay::Image3DOverlay(const Image3DOverlay* image3DOverlay) : } void Image3DOverlay::update(float deltatime) { - Transform transform = getTransform(); - applyTransformTo(transform); - setTransform(transform); + if (usecTimestampNow() > _transformExpiry) { + Transform transform = getTransform(); + applyTransformTo(transform); + setTransform(transform); + } } void Image3DOverlay::render(RenderArgs* args) { @@ -191,8 +193,9 @@ bool Image3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec if (_texture && _texture->isLoaded()) { // Make sure position and rotation is updated. Transform transform = getTransform(); - applyTransformTo(transform, true); - setTransform(transform); + // XXX this code runs too often for this... + // applyTransformTo(transform, true); + // setTransform(transform); // Produce the dimensions of the overlay based on the image's aspect ratio and the overlay's scale. bool isNull = _fromImage.isNull(); diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 1fbf6a9bbd..153f787fc7 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -65,9 +65,11 @@ xColor Text3DOverlay::getBackgroundColor() { } void Text3DOverlay::update(float deltatime) { - Transform transform = getTransform(); - applyTransformTo(transform); - setTransform(transform); + if (usecTimestampNow() > _transformExpiry) { + Transform transform = getTransform(); + applyTransformTo(transform); + setTransform(transform); + } } void Text3DOverlay::render(RenderArgs* args) { diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 1b9adbfa95..6ca3e49569 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -57,9 +57,11 @@ Web3DOverlay::~Web3DOverlay() { } void Web3DOverlay::update(float deltatime) { - Transform transform = getTransform(); - applyTransformTo(transform); - setTransform(transform); + if (usecTimestampNow() > _transformExpiry) { + Transform transform = getTransform(); + applyTransformTo(transform); + setTransform(transform); + } } void Web3DOverlay::render(RenderArgs* args) { From 28e0ca2e49e7c57fca14cdf7a3259d7a27d8d366 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Aug 2016 10:55:34 -0700 Subject: [PATCH 09/13] when a parent of a 3d overlay is deleted, delete the overlay --- interface/src/ui/overlays/Base3DOverlay.cpp | 4 ++++ interface/src/ui/overlays/Base3DOverlay.h | 1 + interface/src/ui/overlays/Overlay.h | 10 ++++++++-- interface/src/ui/overlays/Overlays.cpp | 1 + libraries/shared/src/SpatiallyNestable.cpp | 6 ++++++ libraries/shared/src/SpatiallyNestable.h | 3 ++- 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index a5b5a2dd72..8f2149f02d 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -244,3 +244,7 @@ void Base3DOverlay::locationChanged(bool tellPhysics) { // Overlays can't currently have children. // SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also } + +void Base3DOverlay::parentDeleted() { + qApp->getOverlays().deleteOverlay(getOverlayID()); +} diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 551c1c3384..1860af4e85 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -57,6 +57,7 @@ public: protected: virtual void locationChanged(bool tellPhysics = true) override; + virtual void parentDeleted() override; float _lineWidth; bool _isSolid; diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 466ec0e913..51792b24b3 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -17,7 +17,7 @@ class Overlay : public QObject { Q_OBJECT - + public: enum Anchor { NO_ANCHOR, @@ -31,9 +31,13 @@ public: Overlay(); Overlay(const Overlay* overlay); ~Overlay(); + + unsigned int getOverlayID() { return _overlayID; } + void setOverlayID(unsigned int overlayID) { _overlayID = overlayID; } + virtual void update(float deltatime) {} virtual void render(RenderArgs* args) = 0; - + virtual AABox getBounds() const = 0; virtual bool supportsGetProperty() const { return true; } @@ -85,6 +89,8 @@ protected: render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID }; + unsigned int _overlayID; // what Overlays.cpp knows this instance as + bool _isLoaded; float _alpha; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 0b4bcc8652..2c1f7552cd 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -192,6 +192,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QVariant& propertie unsigned int Overlays::addOverlay(Overlay::Pointer overlay) { QWriteLocker lock(&_lock); unsigned int thisID = _nextOverlayID; + overlay->setOverlayID(thisID); _nextOverlayID++; if (overlay->is3D()) { _overlaysWorld[thisID] = overlay; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 6a9cdd0935..c912ecfc47 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -26,6 +26,12 @@ SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) : _transform.setRotation(glm::quat()); } +SpatiallyNestable::~SpatiallyNestable() { + forEachChild([&](SpatiallyNestablePointer object) { + object->parentDeleted(); + }); +} + const QUuid SpatiallyNestable::getID() const { QUuid result; _idLock.withReadLock([&] { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index a579c0dfe4..391f13cc27 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -35,7 +35,7 @@ enum class NestableType { class SpatiallyNestable : public std::enable_shared_from_this { public: SpatiallyNestable(NestableType nestableType, QUuid id); - virtual ~SpatiallyNestable() { } + virtual ~SpatiallyNestable(); virtual const QUuid getID() const; virtual void setID(const QUuid& id); @@ -178,6 +178,7 @@ protected: virtual void locationChanged(bool tellPhysics = true); // called when a this object's location has changed virtual void dimensionsChanged() { } // called when a this object's dimensions have changed + virtual void parentDeleted() { } // called on children of a deleted parent // _queryAACube is used to decide where something lives in the octree mutable AACube _queryAACube; From 2c449320d0a46ee23728a0d222b761d5072fa2ba Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 2 Aug 2016 08:20:48 -0700 Subject: [PATCH 10/13] when and ID of a SpatiallyNestable subclass is changed, update the parentID of any children --- libraries/shared/src/SpatiallyNestable.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index c912ecfc47..c3dbafa0d9 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -41,6 +41,10 @@ const QUuid SpatiallyNestable::getID() const { } void SpatiallyNestable::setID(const QUuid& id) { + // adjust the parentID of any children + forEachChild([&](SpatiallyNestablePointer object) { + object->setParentID(id); + }); _idLock.withWriteLock([&] { _id = id; }); From 4e16998b450f72e13fc376fa19efb1b29e3c0a54 Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Tue, 9 Aug 2016 17:36:59 -0700 Subject: [PATCH 11/13] Disable loading client scripts over ATP --- interface/src/Application.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3d519d1790..bf85c17370 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5114,8 +5114,10 @@ void Application::setPreviousScriptLocation(const QString& location) { } void Application::loadScriptURLDialog() const { - auto newScript = OffscreenUi::getText(nullptr, "Open and Run Script", "Script URL"); - if (!newScript.isEmpty()) { + auto newScript = OffscreenUi::getText(OffscreenUi::ICON_NONE, "Open and Run Script", "Script URL"); + if (QUrl(newScript).scheme() == "atp") { + OffscreenUi::warning("Error Loading Script", "Cannot load client script over ATP"); + } else if (!newScript.isEmpty()) { DependencyManager::get()->loadScript(newScript); } } From 0f988fb209cdc93a6a848495a6f66e7346e23fc9 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 11 Aug 2016 13:05:16 -0700 Subject: [PATCH 12/13] don't always mark _shaderDirty when user data changes unless url actually changes --- libraries/procedural/src/procedural/Procedural.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index 79a90ef72d..27662e96d0 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -115,6 +115,11 @@ bool Procedural::parseUrl(const QUrl& shaderUrl) { return false; } + // If the URL hasn't changed, don't mark the shader as dirty + if (_shaderUrl == shaderUrl) { + return true; + } + _shaderUrl = shaderUrl; _shaderDirty = true; From c363ca98873e77738969291cee70b3246f37bd42 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 11 Aug 2016 15:29:09 -0700 Subject: [PATCH 13/13] 3d-model overlays can now be children --- interface/src/ui/overlays/ModelOverlay.cpp | 9 +++++++++ interface/src/ui/overlays/ModelOverlay.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 9c203c0129..0a89268f6b 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -178,3 +178,12 @@ bool ModelOverlay::findRayIntersectionExtraInfo(const glm::vec3& origin, const g ModelOverlay* ModelOverlay::createClone() const { return new ModelOverlay(this); } + +void ModelOverlay::locationChanged(bool tellPhysics) { + Base3DOverlay::locationChanged(tellPhysics); + + if (_model && _model->isActive()) { + _model->setRotation(getRotation()); + _model->setTranslation(getPosition()); + } +} diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 091cab44c9..d5f709c2db 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -39,6 +39,8 @@ public: virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges) override; virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::PendingChanges& pendingChanges) override; + void locationChanged(bool tellPhysics) override; + private: ModelPointer _model;