From b590cd5b8928766d14f6e2cf4bb8b020a6f21a52 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 28 Nov 2017 17:51:06 -0800 Subject: [PATCH 01/26] avatar-entities which are children of an avatar will scale with the avatar --- interface/src/Application.cpp | 4 +- interface/src/Util.cpp | 2 +- interface/src/ui/overlays/Base3DOverlay.cpp | 10 +- interface/src/ui/overlays/Line3DOverlay.cpp | 8 +- .../src/avatars-renderer/Avatar.h | 1 + .../src/EntityTreeRenderer.cpp | 2 +- .../src/RenderableLightEntityItem.cpp | 2 +- .../src/RenderableModelEntityItem.cpp | 22 ++-- .../src/RenderableModelEntityItem.h | 2 +- .../src/RenderablePolyVoxEntityItem.cpp | 12 +- .../src/RenderableShapeEntityItem.cpp | 4 +- .../src/RenderableTextEntityItem.cpp | 4 +- .../src/RenderableWebEntityItem.cpp | 4 +- .../src/RenderableZoneEntityItem.cpp | 4 +- libraries/entities/src/EntityItem.cpp | 65 +++++++--- libraries/entities/src/EntityItem.h | 11 +- .../entities/src/EntityItemProperties.cpp | 21 ++++ libraries/entities/src/EntityItemProperties.h | 2 + libraries/entities/src/EntityPropertyFlags.h | 2 + .../entities/src/EntityScriptingInterface.cpp | 64 ++++++++-- libraries/entities/src/EntityTreeElement.cpp | 4 +- libraries/entities/src/LightEntityItem.cpp | 14 +-- libraries/entities/src/LightEntityItem.h | 2 +- libraries/entities/src/LineEntityItem.cpp | 6 +- libraries/entities/src/ModelEntityItem.cpp | 2 +- .../entities/src/ParticleEffectEntityItem.cpp | 4 +- libraries/entities/src/PolyLineEntityItem.cpp | 4 +- libraries/entities/src/PolyVoxEntityItem.cpp | 6 +- libraries/entities/src/ShapeEntityItem.cpp | 14 +-- libraries/entities/src/ShapeEntityItem.h | 2 +- libraries/entities/src/TextEntityItem.cpp | 6 +- libraries/entities/src/TextEntityItem.h | 2 +- libraries/entities/src/WebEntityItem.cpp | 6 +- libraries/entities/src/WebEntityItem.h | 2 +- libraries/entities/src/ZoneEntityItem.cpp | 2 +- libraries/shared/src/SpatiallyNestable.cpp | 119 ++++++++++++++++-- libraries/shared/src/SpatiallyNestable.h | 28 +++-- 37 files changed, 336 insertions(+), 133 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d7fcbf6467..45ede258b7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4238,7 +4238,7 @@ void Application::init() { getEntities()->init(); getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) { - auto dims = item.getDimensions(); + auto dims = item.getScaledDimensions(); auto maxSize = glm::compMax(dims); if (maxSize <= 0.0f) { @@ -4590,7 +4590,7 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) { _lastAcceptedKeyPress = usecTimestampNow(); setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(), - entity->getDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); + entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); } } } diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index aad7768b99..e5e94da68a 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -407,7 +407,7 @@ void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &s ShapeInfo::PointList points; pointCollection.push_back(points); - GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getDimensions(), pointCollection.back()); + GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getScaledDimensions(), pointCollection.back()); shapeInfo.setPointCollection(pointCollection); } diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 3e29395eba..884a174041 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -42,7 +42,7 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : setTransform(base3DOverlay->getTransform()); } -QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties) { +QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties, bool scalesWithParent) { // 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. @@ -56,7 +56,7 @@ QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& propert result["position"] = result["localPosition"]; } else if (result["position"].isValid()) { glm::vec3 localPosition = SpatiallyNestable::worldToLocal(vec3FromVariant(result["position"]), - parentID, parentJointIndex, success); + parentID, parentJointIndex, scalesWithParent, success); if (success) { result["position"] = vec3toVariant(localPosition); } @@ -66,7 +66,7 @@ QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& propert result["orientation"] = result["localOrientation"]; } else if (result["orientation"].isValid()) { glm::quat localOrientation = SpatiallyNestable::worldToLocal(quatFromVariant(result["orientation"]), - parentID, parentJointIndex, success); + parentID, parentJointIndex, scalesWithParent, success); if (success) { result["orientation"] = quatToVariant(localOrientation); } @@ -118,7 +118,7 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { } } - properties = convertOverlayLocationFromScriptSemantics(properties); + properties = convertOverlayLocationFromScriptSemantics(properties, getScalesWithParent()); Overlay::setProperties(properties); bool needRenderItemUpdate = false; @@ -310,4 +310,4 @@ SpatialParentTree* Base3DOverlay::getParentTree() const { void Base3DOverlay::setVisible(bool visible) { Parent::setVisible(visible); notifyRenderVariableChange(); -} \ No newline at end of file +} diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 66a6772aa5..2fa9f7c7d3 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -56,12 +56,12 @@ glm::vec3 Line3DOverlay::getEnd() const { if (_endParentID != QUuid()) { glm::vec3 localOffset = _direction * _length; bool success; - worldEnd = localToWorld(localOffset, _endParentID, _endParentJointIndex, success); + worldEnd = localToWorld(localOffset, _endParentID, _endParentJointIndex, getScalesWithParent(), success); return worldEnd; } localEnd = getLocalEnd(); - worldEnd = localToWorld(localEnd, getParentID(), getParentJointIndex(), success); + worldEnd = localToWorld(localEnd, getParentID(), getParentJointIndex(), getScalesWithParent(), success); if (!success) { qDebug() << "Line3DOverlay::getEnd failed"; } @@ -79,10 +79,10 @@ void Line3DOverlay::setEnd(const glm::vec3& end) { glm::vec3 offset; if (_endParentID != QUuid()) { - offset = worldToLocal(end, _endParentID, _endParentJointIndex, success); + offset = worldToLocal(end, _endParentID, _endParentJointIndex, getScalesWithParent(), success); } else { localStart = getLocalStart(); - localEnd = worldToLocal(end, getParentID(), getParentJointIndex(), success); + localEnd = worldToLocal(end, getParentID(), getParentJointIndex(), getScalesWithParent(), success); offset = localEnd - localStart; } if (!success) { diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index a723a8e1b0..959cb6912b 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -264,6 +264,7 @@ public: virtual float getModelScale() const { return _modelScale; } virtual void setModelScale(float scale) { _modelScale = scale; } + virtual glm::vec3 scaleForChildren() const override { return glm::vec3(getModelScale()); } virtual void setAvatarEntityDataChanged(bool value) override; diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 5f7899ae74..77c538619c 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -610,7 +610,7 @@ static glm::vec2 projectOntoEntityXYPlane(EntityItemPointer entity, const PickRa glm::vec3 entityPosition = entity->getWorldPosition(); glm::quat entityRotation = entity->getWorldOrientation(); - glm::vec3 entityDimensions = entity->getDimensions(); + glm::vec3 entityDimensions = entity->getScaledDimensions(); glm::vec3 entityRegistrationPoint = entity->getRegistrationPoint(); // project the intersection point onto the local xy plane of the object. diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp index 696d7ab8db..fc33ebc498 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp @@ -37,7 +37,7 @@ void LightEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint lightPayload.editBound() = render::Item::Bound(); } - glm::vec3 dimensions = entity->getDimensions(); + glm::vec3 dimensions = entity->getScaledDimensions(); float largestDiameter = glm::compMax(dimensions); light->setMaximumRadius(largestDiameter / 2.0f); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 06b81ff428..3921432a43 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -74,11 +74,11 @@ RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityI RenderableModelEntityItem::~RenderableModelEntityItem() { } -void RenderableModelEntityItem::setDimensions(const glm::vec3& value) { +void RenderableModelEntityItem::setUnscaledDimensions(const glm::vec3& value) { glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions - if (getDimensions() != newDimensions) { + if (getUnscaledDimensions() != newDimensions) { _dimensionsInitialized = true; - ModelEntityItem::setDimensions(value); + ModelEntityItem::setUnscaledDimensions(value); } } @@ -120,11 +120,11 @@ void RenderableModelEntityItem::doInitialModelSimulation() { // translation/rotation/scale/registration. The first two are straightforward, but the latter two have guards to // make sure they don't happen after they've already been set. Here we reset those guards. This doesn't cause the // entity values to change -- it just allows the model to match once it comes in. - model->setScaleToFit(false, getDimensions()); + model->setScaleToFit(false, getScaledDimensions()); model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); // now recalculate the bounds and registration - model->setScaleToFit(true, getDimensions()); + model->setScaleToFit(true, getScaledDimensions()); model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); model->setRotation(getWorldOrientation()); model->setTranslation(getWorldPosition()); @@ -165,7 +165,7 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const { return true; } - if (model->getScaleToFitDimensions() != getDimensions()) { + if (model->getScaleToFitDimensions() != getScaledDimensions()) { return true; } @@ -205,17 +205,17 @@ void RenderableModelEntityItem::updateModelBounds() { updateRenderItems = true; } - if (model->getScaleToFitDimensions() != getDimensions() || + if (model->getScaleToFitDimensions() != getScaledDimensions() || model->getRegistrationPoint() != getRegistrationPoint()) { // The machinery for updateModelBounds will give existing models the opportunity to fix their // translation/rotation/scale/registration. The first two are straightforward, but the latter two // have guards to make sure they don't happen after they've already been set. Here we reset those guards. // This doesn't cause the entity values to change -- it just allows the model to match once it comes in. - model->setScaleToFit(false, getDimensions()); + model->setScaleToFit(false, getScaledDimensions()); model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); // now recalculate the bounds and registration - model->setScaleToFit(true, getDimensions()); + model->setScaleToFit(true, getScaledDimensions()); model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); updateRenderItems = true; model->scaleToFit(); @@ -368,7 +368,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { const uint32_t QUAD_STRIDE = 4; ShapeType type = getShapeType(); - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); auto model = getModel(); if (type == SHAPE_TYPE_COMPOUND) { updateModelBounds(); @@ -1163,7 +1163,7 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin return true; } - if (model->getScaleToFitDimensions() != entity->getDimensions() || + if (model->getScaleToFitDimensions() != entity->getScaledDimensions() || model->getRegistrationPoint() != entity->getRegistrationPoint()) { return true; } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 0272bed575..34c0a8f81d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -60,7 +60,7 @@ public: RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized); virtual ~RenderableModelEntityItem(); - virtual void setDimensions(const glm::vec3& value) override; + virtual void setUnscaledDimensions(const glm::vec3& value) override; virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; void doInitialModelSimulation(); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 356bf3a69c..496f8b7323 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -213,7 +213,7 @@ void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxel glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const { glm::vec3 result; withReadLock([&] { - glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units + glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units if (isEdged(_voxelSurfaceStyle)) { result = scale / -2.0f; } @@ -228,7 +228,7 @@ glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const { voxelVolumeSize = _voxelVolumeSize; }); - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units bool success; // TODO -- Does this actually have to happen in world space? glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes @@ -393,7 +393,7 @@ bool RenderablePolyVoxEntityItem::setSphere(const vec3& centerWorldCoords, float glm::mat4 vtwMatrix = voxelToWorldMatrix(); glm::mat4 wtvMatrix = glm::inverse(vtwMatrix); - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec3 voxelSize = dimensions / _voxelVolumeSize; float smallestDimensionSize = voxelSize.x; smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y); @@ -454,7 +454,7 @@ bool RenderablePolyVoxEntityItem::setCapsule(const vec3& startWorldCoords, const glm::mat4 vtwMatrix = voxelToWorldMatrix(); glm::mat4 wtvMatrix = glm::inverse(vtwMatrix); - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec3 voxelSize = dimensions / _voxelVolumeSize; float smallestDimensionSize = voxelSize.x; smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y); @@ -580,7 +580,7 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o // the PolyVox ray intersection code requires a near and far point. // set ray cast length to long enough to cover all of the voxel space float distanceToEntity = glm::distance(origin, getWorldPosition()); - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); float largestDimension = glm::compMax(dimensions) * 2.0f; glm::vec3 farPoint = origin + normDirection * (distanceToEntity + largestDimension); @@ -668,7 +668,7 @@ bool RenderablePolyVoxEntityItem::isReadyToComputeShape() const { void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) { ShapeType shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_NONE) { - info.setParams(getShapeType(), 0.5f * getDimensions()); + info.setParams(getShapeType(), 0.5f * getScaledDimensions()); return; } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 3524709395..cbee221399 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -63,7 +63,7 @@ bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin return true; } - if (_dimensions != entity->getDimensions()) { + if (_dimensions != entity->getScaledDimensions()) { return true; } @@ -82,7 +82,7 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce _shape = entity->getShape(); _position = entity->getWorldPosition(); - _dimensions = entity->getDimensions(); + _dimensions = entity->getScaledDimensions(); _orientation = entity->getWorldOrientation(); _renderTransform = getModelTransform(); diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 6c0f4447ae..968c181940 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -54,7 +54,7 @@ bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint return true; } - if (_dimensions != entity->getDimensions()) { + if (_dimensions != entity->getScaledDimensions()) { return true; } @@ -67,7 +67,7 @@ bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { _textColor = toGlm(entity->getTextColorX()); _backgroundColor = toGlm(entity->getBackgroundColorX()); - _dimensions = entity->getDimensions(); + _dimensions = entity->getScaledDimensions(); _faceCamera = entity->getFaceCamera(); _lineHeight = entity->getLineHeight(); _text = entity->getText(); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index cdd260e73c..05a2228607 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -144,7 +144,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene glm::vec2 windowSize = getWindowSize(entity); _webSurface->resize(QSize(windowSize.x, windowSize.y)); _renderTransform = getModelTransform(); - _renderTransform.postScale(entity->getDimensions()); + _renderTransform.postScale(entity->getScaledDimensions()); }); } @@ -274,7 +274,7 @@ void WebEntityRenderer::destroyWebSurface() { } glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) const { - glm::vec2 dims = glm::vec2(entity->getDimensions()); + glm::vec2 dims = glm::vec2(entity->getScaledDimensions()); dims *= METERS_TO_INCHES * _lastDPI; // ensure no side is never larger then MAX_WINDOW_SIZE diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 7a5c50df50..784945f0bb 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -206,7 +206,7 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen entity->resetRenderingPropertiesChanged(); _lastPosition = entity->getWorldPosition(); _lastRotation = entity->getWorldOrientation(); - _lastDimensions = entity->getDimensions(); + _lastDimensions = entity->getScaledDimensions(); _keyLightProperties = entity->getKeyLightProperties(); _skyboxProperties = entity->getSkyboxProperties(); @@ -278,7 +278,7 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint if (entity->getWorldPosition() != _lastPosition) { return true; } - if (entity->getDimensions() != _lastDimensions) { + if (entity->getScaledDimensions() != _lastDimensions) { return true; } if (entity->getWorldOrientation() != _lastRotation) { diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index c8e7ce6c11..d244f6d557 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -49,6 +49,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : { setLocalVelocity(ENTITY_ITEM_DEFAULT_VELOCITY); setLocalAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY); + setUnscaledDimensions(ENTITY_ITEM_DEFAULT_DIMENSIONS); // explicitly set transform parts to set dirty flags used by batch rendering locationChanged(); dimensionsChanged(); @@ -241,7 +242,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getLocalAngularVelocity()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration()); - APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getDimensions()); + APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getUnscaledDimensions()); APPEND_ENTITY_PROPERTY(PROP_DENSITY, getDensity()); APPEND_ENTITY_PROPERTY(PROP_GRAVITY, getGravity()); APPEND_ENTITY_PROPERTY(PROP_DAMPING, getDamping()); @@ -776,7 +777,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, customSetAcceleration); } - READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setDimensions); + READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setUnscaledDimensions); READ_ENTITY_PROPERTY(PROP_DENSITY, float, setDensity); READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, setGravity); @@ -894,7 +895,7 @@ void EntityItem::debugDump() const { qCDebug(entities) << "EntityItem id:" << getEntityItemID(); qCDebug(entities, " edited ago:%f", (double)getEditedAgo()); qCDebug(entities, " position:%f,%f,%f", (double)position.x, (double)position.y, (double)position.z); - qCDebug(entities) << " dimensions:" << getDimensions(); + qCDebug(entities) << " dimensions:" << getScaledDimensions(); } // adjust any internal timestamps to fix clock skew for this server @@ -919,7 +920,7 @@ void EntityItem::adjustEditPacketForClockSkew(QByteArray& buffer, qint64 clockSk } float EntityItem::computeMass() const { - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); return getDensity() * _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z; } @@ -938,7 +939,7 @@ void EntityItem::setMass(float mass) { // we must protect the density range to help maintain stability of physics simulation // therefore this method might not accept the mass that is supplied. - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); float volume = _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z; // compute new density @@ -1172,7 +1173,7 @@ bool EntityItem::wantTerseEditLogging() const { glm::mat4 EntityItem::getEntityToWorldMatrix() const { glm::mat4 translation = glm::translate(getWorldPosition()); glm::mat4 rotation = glm::mat4_cast(getWorldOrientation()); - glm::mat4 scale = glm::scale(getDimensions()); + glm::mat4 scale = glm::scale(getScaledDimensions()); glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()); return translation * rotation * scale * registration; } @@ -1212,7 +1213,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner); COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getLocalPosition); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getDimensions); // NOTE: radius is obsolete + COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getUnscaledDimensions); COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getLocalOrientation); COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity); COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getLocalVelocity); @@ -1319,7 +1320,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(acceleration, setAcceleration); // these (along with "position" above) affect tree structure - SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setDimensions); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setUnscaledDimensions); SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint); // these (along with all properties above) affect the simulation @@ -1421,7 +1422,7 @@ void EntityItem::recordCreationTime() { 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()) * getDimensions()); // Position to center + result.postTranslate((ENTITY_ITEM_HALF_VEC3 - getRegistrationPoint()) * getScaledDimensions()); // Position to center } return result; } @@ -1437,7 +1438,7 @@ AACube EntityItem::getMaximumAACube(bool& success) const { // we want to compute the furthestExtent that an entity can extend out from its "position" // to do this we compute the max of these two vec3s: registration and 1-registration // and then scale by dimensions - glm::vec3 maxExtents = getDimensions() * glm::max(_registrationPoint, glm::vec3(1.0f) - _registrationPoint); + glm::vec3 maxExtents = getScaledDimensions() * glm::max(_registrationPoint, glm::vec3(1.0f) - _registrationPoint); // there exists a sphere that contains maxExtents for all rotations float radius = glm::length(maxExtents); @@ -1462,7 +1463,7 @@ AACube EntityItem::getMinimumAACube(bool& success) const { glm::vec3 position = getWorldPosition(success); if (success) { _recalcMinAACube = false; - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint); glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint); Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; @@ -1492,7 +1493,7 @@ AABox EntityItem::getAABox(bool& success) const { glm::vec3 position = getWorldPosition(success); if (success) { _recalcAABox = false; - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint); glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint); Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; @@ -1532,12 +1533,12 @@ bool EntityItem::shouldPuffQueryAACube() const { // ... cornerToCornerLength = sqrt(3 x maxDimension ^ 2) // ... radius = sqrt(3 x maxDimension ^ 2) / 2.0f; float EntityItem::getRadius() const { - return 0.5f * glm::length(getDimensions()); + return 0.5f * glm::length(getScaledDimensions()); } void EntityItem::adjustShapeInfoByRegistration(ShapeInfo& info) const { if (_registrationPoint != ENTITY_ITEM_DEFAULT_REGISTRATION_POINT) { - glm::mat4 scale = glm::scale(getDimensions()); + glm::mat4 scale = glm::scale(getScaledDimensions()); glm::mat4 registration = scale * glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()); glm::vec3 regTransVec = glm::vec3(registration[3]); // extract position component from matrix info.setOffset(regTransVec); @@ -1558,12 +1559,12 @@ bool EntityItem::contains(const glm::vec3& point) const { } void EntityItem::computeShapeInfo(ShapeInfo& info) { - info.setParams(getShapeType(), 0.5f * getDimensions()); + info.setParams(getShapeType(), 0.5f * getScaledDimensions()); adjustShapeInfoByRegistration(info); } float EntityItem::getVolumeEstimate() const { - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); return dimensions.x * dimensions.y * dimensions.z; } @@ -1617,11 +1618,25 @@ void EntityItem::setParentID(const QUuid& value) { } } -void EntityItem::setDimensions(const glm::vec3& value) { +glm::vec3 EntityItem::getScaledDimensions() const { + glm::vec3 scale = getSNScale(); + return glm::vec3(_unscaledDimensions.x * scale.x, + _unscaledDimensions.y * scale.y, + _unscaledDimensions.z * scale.z); +} + +void EntityItem::setScaledDimensions(const glm::vec3& value) { + glm::vec3 parentScale = getSNScale(); + setUnscaledDimensions(glm::vec3(value.x / parentScale.x, + value.y / parentScale.y, + value.z / parentScale.z)); +} + +void EntityItem::setUnscaledDimensions(const glm::vec3& value) { glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions - if (getDimensions() != newDimensions) { + if (getUnscaledDimensions() != newDimensions) { withWriteLock([&] { - _dimensions = newDimensions; + _unscaledDimensions = newDimensions; }); locationChanged(); dimensionsChanged(); @@ -2292,6 +2307,16 @@ void EntityItem::dimensionsChanged() { somethingChangedNotification(); } +bool EntityItem::getScalesWithParent() const { + // keep this logic the same as in EntityItemProperties::getScalesWithParent + if (getClientOnly()) { + QUuid ancestorID = findAncestorOfType(NestableType::Avatar); + return !ancestorID.isNull(); + } else { + return false; + } +} + void EntityItem::globalizeProperties(EntityItemProperties& properties, const QString& messageTemplate, const glm::vec3& offset) const { // TODO -- combine this with convertLocationToScriptSemantics bool success; @@ -2299,7 +2324,7 @@ void EntityItem::globalizeProperties(EntityItemProperties& properties, const QSt if (success) { properties.setPosition(globalPosition + offset); properties.setRotation(getWorldOrientation()); - properties.setDimensions(getDimensions()); + properties.setDimensions(getScaledDimensions()); // Should we do velocities and accelerations, too? This could end up being quite involved, which is why the method exists. } else { properties.setPosition(getQueryAACube().calcCenter() + offset); // best we can do diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 882b8e6812..985dbdcaae 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -180,8 +180,11 @@ public: void setDescription(const QString& value); /// Dimensions in meters (0.0 - TREE_SCALE) - inline const glm::vec3 getDimensions() const { return _dimensions; } - virtual void setDimensions(const glm::vec3& value); + glm::vec3 getScaledDimensions() const; + virtual void setScaledDimensions(const glm::vec3& value); + + inline const glm::vec3 getUnscaledDimensions() const { return _unscaledDimensions; } + virtual void setUnscaledDimensions(const glm::vec3& value); float getLocalRenderAlpha() const; void setLocalRenderAlpha(float localRenderAlpha); @@ -454,6 +457,8 @@ public: virtual void locationChanged(bool tellPhysics = true) override; + virtual bool getScalesWithParent() const override; + using ChangeHandlerCallback = std::function; using ChangeHandlerId = QUuid; ChangeHandlerId registerChangeHandler(const ChangeHandlerCallback& handler); @@ -474,7 +479,7 @@ protected: virtual void dimensionsChanged() override; - glm::vec3 _dimensions { ENTITY_ITEM_DEFAULT_DIMENSIONS }; + glm::vec3 _unscaledDimensions { ENTITY_ITEM_DEFAULT_DIMENSIONS }; EntityTypes::EntityType _type { EntityTypes::Unknown }; quint64 _lastSimulated { 0 }; // last time this entity called simulate(), this includes velocity, angular velocity, // and physics changes diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 5ab4bdee01..8f57db772a 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -365,6 +365,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation); CHECK_PROPERTY_CHANGE(PROP_LOCAL_VELOCITY, localVelocity); CHECK_PROPERTY_CHANGE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity); + CHECK_PROPERTY_CHANGE(PROP_LOCAL_DIMENSIONS, localDimensions); CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed); CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed); @@ -627,6 +628,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_VELOCITY, localVelocity); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_DIMENSIONS, localDimensions); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID); @@ -803,6 +805,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation); COPY_PROPERTY_FROM_QSCRIPTVALUE(localVelocity, glmVec3, setLocalVelocity); COPY_PROPERTY_FROM_QSCRIPTVALUE(localAngularVelocity, glmVec3, setLocalAngularVelocity); + COPY_PROPERTY_FROM_QSCRIPTVALUE(localDimensions, glmVec3, setLocalDimensions); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations); @@ -950,6 +953,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) { COPY_PROPERTY_IF_CHANGED(localRotation); COPY_PROPERTY_IF_CHANGED(localVelocity); COPY_PROPERTY_IF_CHANGED(localAngularVelocity); + COPY_PROPERTY_IF_CHANGED(localDimensions); COPY_PROPERTY_IF_CHANGED(jointRotationsSet); COPY_PROPERTY_IF_CHANGED(jointRotations); @@ -1128,6 +1132,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glm::quat); ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector); @@ -2460,9 +2465,25 @@ bool EntityItemProperties::transformChanged() const { localPositionChanged() || localRotationChanged(); } +bool EntityItemProperties::getScalesWithParent() const { + // keep this logic the same as in EntityItem::getScalesWithParent + bool scalesWithParent { false }; + if (parentIDChanged()) { + bool success; + SpatiallyNestablePointer parent = SpatiallyNestable::findByID(getParentID(), success); + if (success && parent) { + bool avatarAncestor = (parent->getNestableType() == NestableType::Avatar || + parent->hasAncestorOfType(NestableType::Avatar)); + scalesWithParent = getClientOnly() && avatarAncestor; + } + } + return scalesWithParent; +} + bool EntityItemProperties::parentRelatedPropertyChanged() const { return positionChanged() || rotationChanged() || localPositionChanged() || localRotationChanged() || + localDimensionsChanged() || parentIDChanged() || parentJointIndexChanged(); } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index ec192d7c9f..a1118e8441 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -88,6 +88,7 @@ public: EntityPropertyFlags getChangedProperties() const; bool transformChanged() const; + bool getScalesWithParent() const; bool parentRelatedPropertyChanged() const; bool queryAACubeRelatedPropertyChanged() const; @@ -226,6 +227,7 @@ public: DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glmQuat, ENTITY_ITEM_DEFAULT_ROTATION); DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3); + DEFINE_PROPERTY_REF(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glmVec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector, QVector()); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector, QVector()); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 35d40b669a..c44f8091e0 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -219,6 +219,8 @@ enum EntityPropertyList { PROP_HAZE_KEYLIGHT_RANGE, PROP_HAZE_KEYLIGHT_ALTITUDE, + PROP_LOCAL_DIMENSIONS, // only used to convert values to and from scripts + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 35941c09d3..25eb126704 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -117,7 +117,8 @@ void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) { } } -EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties& entitySideProperties) { +EntityItemProperties convertPropertiesToScriptSemantics(const EntityItemProperties& entitySideProperties, + bool scalesWithParent) { // In EntityTree code, properties.position and properties.rotation are relative to the parent. In javascript, // they are in world-space. The local versions are put into localPosition and localRotation and position and // rotation are converted from local to world space. @@ -126,35 +127,48 @@ EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties scriptSideProperties.setLocalRotation(entitySideProperties.getRotation()); scriptSideProperties.setLocalVelocity(entitySideProperties.getLocalVelocity()); scriptSideProperties.setLocalAngularVelocity(entitySideProperties.getLocalAngularVelocity()); + scriptSideProperties.setLocalDimensions(entitySideProperties.getDimensions()); bool success; glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(), entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), + scalesWithParent, success); glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(), entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), + scalesWithParent, success); glm::vec3 worldVelocity = SpatiallyNestable::localToWorldVelocity(entitySideProperties.getVelocity(), entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), + scalesWithParent, success); glm::vec3 worldAngularVelocity = SpatiallyNestable::localToWorldAngularVelocity(entitySideProperties.getAngularVelocity(), entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), + scalesWithParent, success); + glm::vec3 worldDimensions = SpatiallyNestable::localToWorldDimensions(entitySideProperties.getDimensions(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex(), + scalesWithParent, + success); + scriptSideProperties.setPosition(worldPosition); scriptSideProperties.setRotation(worldRotation); scriptSideProperties.setVelocity(worldVelocity); scriptSideProperties.setAngularVelocity(worldAngularVelocity); + scriptSideProperties.setDimensions(worldDimensions); return scriptSideProperties; } -EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperties& scriptSideProperties) { +EntityItemProperties convertPropertiesFromScriptSemantics(const EntityItemProperties& scriptSideProperties, + bool scalesWithParent) { // 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; @@ -168,7 +182,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(), entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), - success); + scalesWithParent, success); entitySideProperties.setPosition(localPosition); } @@ -178,7 +192,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(), entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), - success); + scalesWithParent, success); entitySideProperties.setRotation(localRotation); } @@ -188,7 +202,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti glm::vec3 localVelocity = SpatiallyNestable::worldToLocalVelocity(entitySideProperties.getVelocity(), entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), - success); + scalesWithParent, success); entitySideProperties.setVelocity(localVelocity); } @@ -199,10 +213,20 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti SpatiallyNestable::worldToLocalAngularVelocity(entitySideProperties.getAngularVelocity(), entitySideProperties.getParentID(), entitySideProperties.getParentJointIndex(), - success); + scalesWithParent, success); entitySideProperties.setAngularVelocity(localAngularVelocity); } + if (scriptSideProperties.localDimensionsChanged()) { + entitySideProperties.setDimensions(scriptSideProperties.getLocalDimensions()); + } else if (scriptSideProperties.dimensionsChanged()) { + glm::vec3 localDimensions = SpatiallyNestable::worldToLocalDimensions(entitySideProperties.getDimensions(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex(), + scalesWithParent, success); + entitySideProperties.setDimensions(localDimensions); + } + return entitySideProperties; } @@ -212,9 +236,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties _activityTracking.addedEntityCount++; - EntityItemProperties propertiesWithSimID = convertLocationFromScriptSemantics(properties); - propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged()); - + EntityItemProperties propertiesWithSimID = properties; if (clientOnly) { auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); @@ -222,6 +244,11 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties propertiesWithSimID.setOwningAvatarID(myNodeID); } + bool scalesWithParent = propertiesWithSimID.getScalesWithParent(); + + propertiesWithSimID = convertPropertiesFromScriptSemantics(propertiesWithSimID, scalesWithParent); + propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged()); + auto dimensions = propertiesWithSimID.getDimensions(); float volume = dimensions.x * dimensions.y * dimensions.z; auto density = propertiesWithSimID.getDensity(); @@ -295,15 +322,20 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties) { PROFILE_RANGE(script_entities, __FUNCTION__); + bool scalesWithParent { false }; EntityItemProperties results; if (_entityTree) { _entityTree->withReadLock([&] { EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity)); if (entity) { + scalesWithParent = entity->getScalesWithParent(); if (desiredProperties.getHasProperty(PROP_POSITION) || desiredProperties.getHasProperty(PROP_ROTATION) || desiredProperties.getHasProperty(PROP_LOCAL_POSITION) || - desiredProperties.getHasProperty(PROP_LOCAL_ROTATION)) { + desiredProperties.getHasProperty(PROP_LOCAL_ROTATION) || + desiredProperties.getHasProperty(PROP_LOCAL_VELOCITY) || + desiredProperties.getHasProperty(PROP_LOCAL_ANGULAR_VELOCITY) || + desiredProperties.getHasProperty(PROP_LOCAL_DIMENSIONS)) { // if we are explicitly getting position or rotation, we need parent information to make sense of them. desiredProperties.setHasProperty(PROP_PARENT_ID); desiredProperties.setHasProperty(PROP_PARENT_JOINT_INDEX); @@ -316,6 +348,9 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit desiredProperties = entity->getEntityProperties(params); desiredProperties.setHasProperty(PROP_LOCAL_POSITION); desiredProperties.setHasProperty(PROP_LOCAL_ROTATION); + desiredProperties.setHasProperty(PROP_LOCAL_VELOCITY); + desiredProperties.setHasProperty(PROP_LOCAL_ANGULAR_VELOCITY); + desiredProperties.setHasProperty(PROP_LOCAL_DIMENSIONS); } results = entity->getProperties(desiredProperties); @@ -323,7 +358,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit }); } - return convertLocationToScriptSemantics(results); + return convertPropertiesToScriptSemantics(results, scalesWithParent); } QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) { @@ -390,10 +425,13 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& if (!scriptSideProperties.localRotationChanged() && !scriptSideProperties.rotationChanged()) { properties.setRotation(entity->getWorldOrientation()); } + if (!scriptSideProperties.localDimensionsChanged() && !scriptSideProperties.dimensionsChanged()) { + properties.setDimensions(entity->getScaledDimensions()); + } } - properties = convertLocationFromScriptSemantics(properties); properties.setClientOnly(entity->getClientOnly()); properties.setOwningAvatarID(entity->getOwningAvatarID()); + properties = convertPropertiesFromScriptSemantics(properties, properties.getScalesWithParent()); float cost = calculateCost(density * volume, oldVelocity, newVelocity); cost *= costMultiplier; @@ -529,7 +567,7 @@ void EntityScriptingInterface::deleteEntity(QUuid id) { return; } - auto dimensions = entity->getDimensions(); + auto dimensions = entity->getScaledDimensions(); float volume = dimensions.x * dimensions.y * dimensions.z; auto density = entity->getDensity(); auto velocity = entity->getWorldVelocity().length(); diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 7e2958583d..926975f735 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -667,7 +667,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con glm::mat4 entityToWorldMatrix = translation * rotation; glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix); - glm::vec3 dimensions = entity->getDimensions(); + glm::vec3 dimensions = entity->getScaledDimensions(); glm::vec3 registrationPoint = entity->getRegistrationPoint(); glm::vec3 corner = -(dimensions * registrationPoint); @@ -763,7 +763,7 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc glm::vec3 penetration; if (!success || entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) { - glm::vec3 dimensions = entity->getDimensions(); + glm::vec3 dimensions = entity->getScaledDimensions(); // FIXME - consider allowing the entity to determine penetration so that // entities could presumably dull actuall hull testing if they wanted to diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index f4944603f1..45f36a1744 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -41,16 +41,16 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID) : EntityItem( _color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0; } -void LightEntityItem::setDimensions(const glm::vec3& value) { +void LightEntityItem::setUnscaledDimensions(const glm::vec3& value) { if (_isSpotlight) { // If we are a spotlight, treat the z value as our radius or length, and // recalculate the x/y dimensions to properly encapsulate the spotlight. const float length = value.z; const float width = length * glm::sin(glm::radians(_cutoff)); - EntityItem::setDimensions(glm::vec3(width, width, length)); + EntityItem::setUnscaledDimensions(glm::vec3(width, width, length)); } else { float maxDimension = glm::compMax(value); - EntityItem::setDimensions(glm::vec3(maxDimension, maxDimension, maxDimension)); + EntityItem::setUnscaledDimensions(glm::vec3(maxDimension, maxDimension, maxDimension)); } } @@ -98,7 +98,7 @@ void LightEntityItem::setIsSpotlight(bool value) { return; } - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec3 newDimensions; if (value) { const float length = dimensions.z; @@ -112,7 +112,7 @@ void LightEntityItem::setIsSpotlight(bool value) { _isSpotlight = value; _lightPropertiesChanged = true; }); - setDimensions(newDimensions); + setScaledDimensions(newDimensions); } void LightEntityItem::setCutoff(float value) { @@ -128,9 +128,9 @@ void LightEntityItem::setCutoff(float value) { if (getIsSpotlight()) { // If we are a spotlight, adjusting the cutoff will affect the area we encapsulate, // so update the dimensions to reflect this. - const float length = getDimensions().z; + const float length = getScaledDimensions().z; const float width = length * glm::sin(glm::radians(_cutoff)); - setDimensions(glm::vec3(width, width, length)); + setScaledDimensions(glm::vec3(width, width, length)); } withWriteLock([&] { diff --git a/libraries/entities/src/LightEntityItem.h b/libraries/entities/src/LightEntityItem.h index edc7376079..870b283c26 100644 --- a/libraries/entities/src/LightEntityItem.h +++ b/libraries/entities/src/LightEntityItem.h @@ -29,7 +29,7 @@ public: ALLOW_INSTANTIATION // This class can be instantiated /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately - virtual void setDimensions(const glm::vec3& value) override; + virtual void setUnscaledDimensions(const glm::vec3& value) override; virtual bool setProperties(const EntityItemProperties& properties) override; virtual bool setSubClassProperties(const EntityItemProperties& properties) override; diff --git a/libraries/entities/src/LineEntityItem.cpp b/libraries/entities/src/LineEntityItem.cpp index 02d16f2537..00196d7b23 100644 --- a/libraries/entities/src/LineEntityItem.cpp +++ b/libraries/entities/src/LineEntityItem.cpp @@ -80,7 +80,7 @@ bool LineEntityItem::appendPoint(const glm::vec3& point) { qCDebug(entities) << "MAX POINTS REACHED!"; return false; } - glm::vec3 halfBox = getDimensions() * 0.5f; + glm::vec3 halfBox = getScaledDimensions() * 0.5f; if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) { qCDebug(entities) << "Point is outside entity's bounding box"; return false; @@ -96,7 +96,7 @@ bool LineEntityItem::setLinePoints(const QVector& points) { if (points.size() > MAX_POINTS_PER_LINE) { return false; } - glm::vec3 halfBox = getDimensions() * 0.5f; + glm::vec3 halfBox = getScaledDimensions() * 0.5f; for (int i = 0; i < points.size(); i++) { glm::vec3 point = points.at(i); if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) { @@ -157,7 +157,7 @@ void LineEntityItem::debugDump() const { qCDebug(entities) << " LINE EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); - qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); + qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 313721ff54..5ec86e2f76 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -190,7 +190,7 @@ void ModelEntityItem::debugDump() const { qCDebug(entities) << "ModelEntityItem id:" << getEntityItemID(); qCDebug(entities) << " edited ago:" << getEditedAgo(); qCDebug(entities) << " position:" << getWorldPosition(); - qCDebug(entities) << " dimensions:" << getDimensions(); + qCDebug(entities) << " dimensions:" << getScaledDimensions(); qCDebug(entities) << " model URL:" << getModelURL(); qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL(); } diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index bc0c093518..c20572a491 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -353,7 +353,7 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() { float maxDistanceValue = glm::compMax(maxDistance); //times 2 because dimensions are diameters not radii glm::vec3 dims(2.0f * maxDistanceValue); - EntityItem::setDimensions(dims); + EntityItem::setScaledDimensions(dims); } @@ -593,7 +593,7 @@ void ParticleEffectEntityItem::debugDump() const { _particleProperties.color.gradient.target.green << "," << _particleProperties.color.gradient.target.blue; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); - qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); + qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); } diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index e69fb2e100..498d13058e 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -191,7 +191,7 @@ void PolyLineEntityItem::calculateScaleAndRegistrationPoint() { } // if Polyline has only one or fewer points, use default dimension settings - setDimensions(newScale); + setScaledDimensions(newScale); EntityItem::setRegistrationPoint(newRegistrationPoint); } @@ -257,7 +257,7 @@ void PolyLineEntityItem::debugDump() const { qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); - qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); + qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); } diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp index b08d94ca7e..84ce83d3a1 100644 --- a/libraries/entities/src/PolyVoxEntityItem.cpp +++ b/libraries/entities/src/PolyVoxEntityItem.cpp @@ -229,7 +229,7 @@ void PolyVoxEntityItem::debugDump() const { quint64 now = usecTimestampNow(); qCDebug(entities) << " POLYVOX EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); - qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); + qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); } @@ -377,7 +377,7 @@ EntityItemID PolyVoxEntityItem::getZPNeighborID() const { glm::vec3 PolyVoxEntityItem::getSurfacePositionAdjustment() const { glm::vec3 result; withReadLock([&] { - glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units + glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units if (isEdged()) { result = scale / -2.0f; } @@ -392,7 +392,7 @@ glm::mat4 PolyVoxEntityItem::voxelToLocalMatrix() const { voxelVolumeSize = _voxelVolumeSize; }); - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units bool success; // TODO -- Does this actually have to happen in world space? glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 15704ebc17..f564c89d21 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -106,11 +106,11 @@ void ShapeEntityItem::setShape(const entity::Shape& shape) { break; case entity::Shape::Circle: // Circle is implicitly flat so we enforce flat dimensions - setDimensions(getDimensions()); + setUnscaledDimensions(getUnscaledDimensions()); break; case entity::Shape::Quad: // Quad is implicitly flat so we enforce flat dimensions - setDimensions(getDimensions()); + setUnscaledDimensions(getUnscaledDimensions()); break; default: _type = EntityTypes::Shape; @@ -204,15 +204,15 @@ void ShapeEntityItem::setColor(const QColor& value) { setAlpha(value.alpha()); } -void ShapeEntityItem::setDimensions(const glm::vec3& value) { +void ShapeEntityItem::setUnscaledDimensions(const glm::vec3& value) { const float MAX_FLAT_DIMENSION = 0.0001f; if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) { // enforce flatness in Y glm::vec3 newDimensions = value; newDimensions.y = MAX_FLAT_DIMENSION; - EntityItem::setDimensions(newDimensions); + EntityItem::setUnscaledDimensions(newDimensions); } else { - EntityItem::setDimensions(value); + EntityItem::setUnscaledDimensions(value); } } @@ -256,7 +256,7 @@ void ShapeEntityItem::debugDump() const { qCDebug(entities) << " collisionShapeType:" << ShapeInfo::getNameForShapeType(getShapeType()); qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); - qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); + qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); qCDebug(entities) << "SHAPE EntityItem Ptr:" << this; } @@ -266,7 +266,7 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { // This will be called whenever DIRTY_SHAPE flag (set by dimension change, etc) // is set. - const glm::vec3 entityDimensions = getDimensions(); + const glm::vec3 entityDimensions = getScaledDimensions(); switch (_shape){ case entity::Shape::Quad: diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index 20e36c88e6..c5df17db54 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -80,7 +80,7 @@ public: const rgbColor& getColor() const { return _color; } void setColor(const rgbColor& value); - void setDimensions(const glm::vec3& value) override; + void setUnscaledDimensions(const glm::vec3& value) override; xColor getXColor() const; void setColor(const xColor& value); diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp index 67e83ab3fd..639da69a17 100644 --- a/libraries/entities/src/TextEntityItem.cpp +++ b/libraries/entities/src/TextEntityItem.cpp @@ -41,9 +41,9 @@ TextEntityItem::TextEntityItem(const EntityItemID& entityItemID) : EntityItem(en const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f; -void TextEntityItem::setDimensions(const glm::vec3& value) { +void TextEntityItem::setUnscaledDimensions(const glm::vec3& value) { // NOTE: Text Entities always have a "depth" of 1cm. - EntityItem::setDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH)); + EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH)); } EntityItemProperties TextEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { @@ -132,7 +132,7 @@ bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject, bool precisionPicking) const { - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::quat rotation = getWorldOrientation(); glm::vec3 position = getWorldPosition() + rotation * diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h index 8db929fa47..520a935e55 100644 --- a/libraries/entities/src/TextEntityItem.h +++ b/libraries/entities/src/TextEntityItem.h @@ -23,7 +23,7 @@ public: ALLOW_INSTANTIATION // This class can be instantiated /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately - virtual void setDimensions(const glm::vec3& value) override; + virtual void setUnscaledDimensions(const glm::vec3& value) override; virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; } // methods for getting/setting all properties of an entity diff --git a/libraries/entities/src/WebEntityItem.cpp b/libraries/entities/src/WebEntityItem.cpp index 5ee630d8ed..54db6e7c3b 100644 --- a/libraries/entities/src/WebEntityItem.cpp +++ b/libraries/entities/src/WebEntityItem.cpp @@ -36,9 +36,9 @@ WebEntityItem::WebEntityItem(const EntityItemID& entityItemID) : EntityItem(enti const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f; -void WebEntityItem::setDimensions(const glm::vec3& value) { +void WebEntityItem::setUnscaledDimensions(const glm::vec3& value) { // NOTE: Web Entities always have a "depth" of 1cm. - EntityItem::setDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH)); + EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH)); } EntityItemProperties WebEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { @@ -109,7 +109,7 @@ bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const g bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject, bool precisionPicking) const { - glm::vec3 dimensions = getDimensions(); + glm::vec3 dimensions = getScaledDimensions(); glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::quat rotation = getWorldOrientation(); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); diff --git a/libraries/entities/src/WebEntityItem.h b/libraries/entities/src/WebEntityItem.h index 9e84a3a776..f5066beebc 100644 --- a/libraries/entities/src/WebEntityItem.h +++ b/libraries/entities/src/WebEntityItem.h @@ -22,7 +22,7 @@ public: ALLOW_INSTANTIATION // This class can be instantiated /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately - virtual void setDimensions(const glm::vec3& value) override; + virtual void setUnscaledDimensions(const glm::vec3& value) override; virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; } // methods for getting/setting all properties of an entity diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 0ed523202b..fbfbc71a85 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -242,7 +242,7 @@ void ZoneEntityItem::debugDump() const { quint64 now = usecTimestampNow(); qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); - qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); + qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode); qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getHazeModeString(_hazeMode); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 2114cbf944..20a5a76b73 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -19,7 +19,7 @@ #include "SharedLogging.h" const float defaultAACubeSize = 1.0f; -const int maxParentingChain = 30; +const int MAX_PARENTING_CHAIN_SIZE = 30; SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) : _nestableType(nestableType), @@ -28,6 +28,7 @@ SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) : // set flags in _transform _transform.setTranslation(glm::vec3(0.0f)); _transform.setRotation(glm::quat()); + _transform.setScale(1.0f); _scaleChanged = usecTimestampNow(); _translationChanged = usecTimestampNow(); _rotationChanged = usecTimestampNow(); @@ -85,6 +86,9 @@ Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const } if (parent) { result = parent->getTransform(_parentJointIndex, success, depth + 1); + if (getScalesWithParent()) { + result.setScale(parent->scaleForChildren()); + } } return result; } @@ -165,7 +169,7 @@ void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) { glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, - bool& success) { + bool scalesWithParent, bool& success) { QSharedPointer parentFinder = DependencyManager::get(); if (!parentFinder) { success = false; @@ -189,6 +193,9 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, if (!success) { return glm::vec3(0.0f); } + if (scalesWithParent) { + parentTransform.setScale(parent->scaleForChildren()); + } } success = true; @@ -199,7 +206,7 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, - bool& success) { + bool scalesWithParent, bool& success) { QSharedPointer parentFinder = DependencyManager::get(); if (!parentFinder) { success = false; @@ -223,6 +230,9 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, if (!success) { return glm::quat(); } + if (scalesWithParent) { + parentTransform.setScale(parent->scaleForChildren()); + } } success = true; @@ -231,7 +241,7 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, } glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID, - int parentJointIndex, bool& success) { + int parentJointIndex, bool scalesWithParent, bool& success) { SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); if (!success || !parent) { return velocity; @@ -240,6 +250,9 @@ glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, con if (!success) { return velocity; } + if (scalesWithParent) { + parentTransform.setScale(parent->scaleForChildren()); + } glm::vec3 parentVelocity = parent->getWorldVelocity(success); if (!success) { return velocity; @@ -249,7 +262,7 @@ glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, con } glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, - int parentJointIndex, bool& success) { + int parentJointIndex, bool scalesWithParent, bool& success) { SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); if (!success || !parent) { return angularVelocity; @@ -258,12 +271,50 @@ glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angula if (!success) { return angularVelocity; } + if (scalesWithParent) { + parentTransform.setScale(parent->scaleForChildren()); + } return glm::inverse(parentTransform.getRotation()) * angularVelocity; } + +glm::vec3 SpatiallyNestable::worldToLocalDimensions(const glm::vec3& dimensions, + const QUuid& parentID, int parentJointIndex, + bool scalesWithParent, bool& success) { + if (!scalesWithParent) { + success = true; + return dimensions; + } + + QSharedPointer parentFinder = DependencyManager::get(); + if (!parentFinder) { + success = false; + return dimensions; + } + + Transform parentTransform; + auto parentWP = parentFinder->find(parentID, success); + if (!success) { + return dimensions; + } + + auto parent = parentWP.lock(); + if (!parentID.isNull() && !parent) { + success = false; + return dimensions; + } + + success = true; + if (parent) { + return dimensions / parent->scaleForChildren(); + } + return dimensions; +} + glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, + bool scalesWithParent, bool& success) { Transform result; QSharedPointer parentFinder = DependencyManager::get(); @@ -289,6 +340,9 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, if (!success) { return glm::vec3(0.0f); } + if (scalesWithParent) { + parentTransform.setScale(parent->scaleForChildren()); + } } success = true; @@ -300,6 +354,7 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, + bool scalesWithParent, bool& success) { Transform result; QSharedPointer parentFinder = DependencyManager::get(); @@ -325,7 +380,9 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, if (!success) { return glm::quat(); } - parentTransform.setScale(1.0f); + if (scalesWithParent) { + parentTransform.setScale(parent->scaleForChildren()); + } } success = true; @@ -336,7 +393,7 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, } glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, const QUuid& parentID, - int parentJointIndex, bool& success) { + int parentJointIndex, bool scalesWithParent, bool& success) { SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); if (!success || !parent) { return velocity; @@ -345,6 +402,9 @@ glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, con if (!success) { return velocity; } + if (scalesWithParent) { + parentTransform.setScale(parent->scaleForChildren()); + } glm::vec3 parentVelocity = parent->getWorldVelocity(success); if (!success) { return velocity; @@ -354,7 +414,7 @@ glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, con } glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, - int parentJointIndex, bool& success) { + int parentJointIndex, bool scalesWithParent, bool& success) { SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); if (!success || !parent) { return angularVelocity; @@ -363,10 +423,47 @@ glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angula if (!success) { return angularVelocity; } - + if (scalesWithParent) { + parentTransform.setScale(parent->scaleForChildren()); + } return parentTransform.getRotation() * angularVelocity; } + +glm::vec3 SpatiallyNestable::localToWorldDimensions(const glm::vec3& dimensions, + const QUuid& parentID, int parentJointIndex, bool scalesWithParent, + bool& success) { + if (!scalesWithParent) { + success = true; + return dimensions; + } + + Transform result; + QSharedPointer parentFinder = DependencyManager::get(); + if (!parentFinder) { + success = false; + return dimensions; + } + + Transform parentTransform; + auto parentWP = parentFinder->find(parentID, success); + if (!success) { + return dimensions; + } + + auto parent = parentWP.lock(); + if (!parentID.isNull() && !parent) { + success = false; + return dimensions; + } + + success = true; + if (parent) { + return dimensions * parent->scaleForChildren(); + } + return dimensions; +} + glm::vec3 SpatiallyNestable::getWorldPosition(bool& success) const { return getTransform(success).getTranslation(); } @@ -615,10 +712,10 @@ const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, i // cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it. Transform jointInWorldFrame; - if (depth > maxParentingChain) { + if (depth > MAX_PARENTING_CHAIN_SIZE) { success = false; // someone created a loop. break it... - qCDebug(shared) << "Parenting loop detected."; + qCDebug(shared) << "Parenting loop detected: " << getID(); SpatiallyNestablePointer _this = getThisPointer(); _this->setParentID(QUuid()); bool setPositionSuccess; diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 9cd38f9ce9..2a315e9230 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -50,19 +50,28 @@ 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, bool& success); - static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success); + static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, + bool scalesWithParent, bool& success); + static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, + bool scalesWithParent, bool& success); static glm::vec3 worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID, - int parentJointIndex, bool& success); + int parentJointIndex, bool scalesWithParent, bool& success); static glm::vec3 worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, - int parentJointIndex, bool& success); + int parentJointIndex, bool scalesWithParent, bool& success); + static glm::vec3 worldToLocalDimensions(const glm::vec3& dimensions, const QUuid& parentID, + int parentJointIndex, bool scalesWithParent, bool& success); - 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); + static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, + bool scalesWithParent, bool& success); + static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, + bool scalesWithParent, bool& success); static glm::vec3 localToWorldVelocity(const glm::vec3& velocity, - const QUuid& parentID, int parentJointIndex, bool& success); + const QUuid& parentID, int parentJointIndex, bool scalesWithParent, bool& success); static glm::vec3 localToWorldAngularVelocity(const glm::vec3& angularVelocity, - const QUuid& parentID, int parentJointIndex, bool& success); + const QUuid& parentID, int parentJointIndex, + bool scalesWithParent, bool& success); + static glm::vec3 localToWorldDimensions(const glm::vec3& dimensions, const QUuid& parentID, + int parentJointIndex, bool scalesWithParent, bool& success); static QString nestableTypeToString(NestableType nestableType); @@ -140,6 +149,9 @@ public: virtual glm::vec3 getLocalSNScale() const; virtual void setLocalSNScale(const glm::vec3& scale); + virtual bool getScalesWithParent() const { return false; } + virtual glm::vec3 scaleForChildren() const { return glm::vec3(1.0f); } + QList getChildren() const; bool hasChildren() const; From 7bb44f413948cc4d45c5c3fedd590c317a01772d Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Mon, 4 Dec 2017 16:46:58 -0800 Subject: [PATCH 02/26] Created poly scripting interface template --- interface/src/Application.cpp | 3 ++ .../GooglePolyScriptingInterface.cpp | 21 ++++++++++++++ .../scripting/GooglePolyScriptingInterface.h | 28 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 interface/src/scripting/GooglePolyScriptingInterface.cpp create mode 100644 interface/src/scripting/GooglePolyScriptingInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d7fcbf6467..38ec8ea05b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -191,6 +191,7 @@ #include #include #include +#include #include #include @@ -698,6 +699,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(nullptr, qApp->getOcteeSceneStats()); DependencyManager::set(); DependencyManager::set(); @@ -5900,6 +5902,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerGlobalObject("Users", DependencyManager::get().data()); scriptEngine->registerGlobalObject("LimitlessSpeechRecognition", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("GooglePoly", DependencyManager::get().data()); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { scriptEngine->registerGlobalObject("Steam", new SteamScriptingInterface(scriptEngine.data(), steamClient.get())); diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp new file mode 100644 index 0000000000..bad9b39972 --- /dev/null +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -0,0 +1,21 @@ +// +// GooglePolyScriptingInterface.cpp +// interface/src/scripting +// +// Created by Elisa Lupin-Jimenez on 12/3/2017. +// Copyright 2017 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 "GooglePolyScriptingInterface.h" +#include "ScriptEngineLogging.h" + +GooglePolyScriptingInterface::GooglePolyScriptingInterface() { + +} + +void GooglePolyScriptingInterface::testPrint() { + qCDebug(scriptengine) << "Google Poly interface exists"; +} \ No newline at end of file diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h new file mode 100644 index 0000000000..04afef8a58 --- /dev/null +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -0,0 +1,28 @@ +// +// GooglePolyScriptingInterface.h +// interface/src/scripting +// +// Created by Elisa Lupin-Jimenez on 12/3/2017. +// Copyright 2017 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 +// + +#ifndef hifi_GooglePolyScriptingInterface_h +#define hifi_GooglePolyScriptingInterface_h + +#include +#include + +class GooglePolyScriptingInterface : public QObject, public Dependency { + Q_OBJECT +public: + GooglePolyScriptingInterface(); + +public slots: + void testPrint(); + +}; + +#endif // hifi_GooglePolyScriptingInterface_h \ No newline at end of file From d6e1a9defe9e411acb7780c07b7d85ceb8c81ae8 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Mon, 4 Dec 2017 16:46:58 -0800 Subject: [PATCH 03/26] Created poly scripting interface template --- interface/src/Application.cpp | 3 ++ .../GooglePolyScriptingInterface.cpp | 21 ++++++++++++++ .../scripting/GooglePolyScriptingInterface.h | 28 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 interface/src/scripting/GooglePolyScriptingInterface.cpp create mode 100644 interface/src/scripting/GooglePolyScriptingInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d7fcbf6467..38ec8ea05b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -191,6 +191,7 @@ #include #include #include +#include #include #include @@ -698,6 +699,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(nullptr, qApp->getOcteeSceneStats()); DependencyManager::set(); DependencyManager::set(); @@ -5900,6 +5902,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerGlobalObject("Users", DependencyManager::get().data()); scriptEngine->registerGlobalObject("LimitlessSpeechRecognition", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("GooglePoly", DependencyManager::get().data()); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { scriptEngine->registerGlobalObject("Steam", new SteamScriptingInterface(scriptEngine.data(), steamClient.get())); diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp new file mode 100644 index 0000000000..bad9b39972 --- /dev/null +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -0,0 +1,21 @@ +// +// GooglePolyScriptingInterface.cpp +// interface/src/scripting +// +// Created by Elisa Lupin-Jimenez on 12/3/2017. +// Copyright 2017 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 "GooglePolyScriptingInterface.h" +#include "ScriptEngineLogging.h" + +GooglePolyScriptingInterface::GooglePolyScriptingInterface() { + +} + +void GooglePolyScriptingInterface::testPrint() { + qCDebug(scriptengine) << "Google Poly interface exists"; +} \ No newline at end of file diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h new file mode 100644 index 0000000000..04afef8a58 --- /dev/null +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -0,0 +1,28 @@ +// +// GooglePolyScriptingInterface.h +// interface/src/scripting +// +// Created by Elisa Lupin-Jimenez on 12/3/2017. +// Copyright 2017 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 +// + +#ifndef hifi_GooglePolyScriptingInterface_h +#define hifi_GooglePolyScriptingInterface_h + +#include +#include + +class GooglePolyScriptingInterface : public QObject, public Dependency { + Q_OBJECT +public: + GooglePolyScriptingInterface(); + +public slots: + void testPrint(); + +}; + +#endif // hifi_GooglePolyScriptingInterface_h \ No newline at end of file From 26cb275b897caea78565ee2921f0c3f1d8487652 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 5 Dec 2017 11:11:56 -0800 Subject: [PATCH 04/26] adjust wearables with saved offsets after WEAR IT --- scripts/system/marketplaces/marketplaces.js | 57 ++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 646e5452df..8cd56211d4 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -8,7 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* global Tablet, Script, HMD, UserActivityLogger, Entities */ +/* global Tablet, Script, HMD, UserActivityLogger, Entities, Account, Wallet, ContextOverlay, Settings, Camera, Vec3, + Quat, MyAvatar, Clipboard, Menu */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ (function () { // BEGIN LOCAL_SCOPE @@ -188,6 +189,41 @@ function rezEntity(itemHref, isWearable) { var success = Clipboard.importEntities(itemHref); + var wearableLocalPosition = null; + var wearableLocalRotation = null; + var wearableLocalDimensions = null; + var wearableDimensions = null; + + if (isWearable) { + var wearableTransforms = Settings.getValue("io.highfidelity.avatarStore.checkOut.transforms"); + if (!wearableTransforms) { + // TODO delete this clause + wearableTransforms = Settings.getValue("io.highfidelity.avatarStore.checkOut.tranforms"); + } + var certPos = itemHref.search("certificate_id="); // TODO how do I parse a URL from here? + if (certPos >= 0) { + certPos += 15; // length of "certificate_id=" + var certURLEncoded = itemHref.substring(certPos); + var certB64Encoded = decodeURIComponent(certURLEncoded); + for (var key in wearableTransforms) { + if (wearableTransforms.hasOwnProperty(key)) { + var certificateTransforms = wearableTransforms[key].certificateTransforms; + if (certificateTransforms) { + for (var certID in certificateTransforms) { + if (certificateTransforms.hasOwnProperty(certID) && + certID == certB64Encoded) { + var certificateTransform = certificateTransforms[certID]; + wearableLocalPosition = certificateTransform.localPosition; + wearableLocalRotation = certificateTransform.localRotation; + wearableLocalDimensions = certificateTransform.localDimensions; + wearableDimensions = certificateTransform.dimensions; + } + } + } + } + } + } + } if (success) { var VERY_LARGE = 10000; @@ -257,6 +293,24 @@ } } + if (isWearable) { + // apply the relative offsets saved during checkout + var offsets = {}; + if (wearableLocalPosition) { + offsets.localPosition = wearableLocalPosition; + } + if (wearableLocalRotation) { + offsets.localRotation = wearableLocalRotation; + } + if (wearableLocalDimensions) { + offsets.localDimensions = wearableLocalDimensions; + } else if (wearableDimensions) { + offsets.dimensions = wearableDimensions; + } + // we currently assume a wearable is a single entity + Entities.editEntity(pastedEntityIDs[0], offsets); + } + if (isActive) { selectionManager.setSelections(pastedEntityIDs); } @@ -399,6 +453,7 @@ referrer: "purchases" }); openWallet(); + break; case 'checkout_walletNotSetUp': wireEventBridge(true); tablet.sendToQml({ From c4e5c53eeef89f91e4a1606a76a63fd4a1445dad Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 5 Dec 2017 11:17:31 -0800 Subject: [PATCH 05/26] jshint cleanups --- scripts/system/marketplaces/marketplaces.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index d35aeebb6b..d0530dc775 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -9,7 +9,7 @@ // /* global Tablet, Script, HMD, UserActivityLogger, Entities, Account, Wallet, ContextOverlay, Settings, Camera, Vec3, - Quat, MyAvatar, Clipboard, Menu */ + Quat, MyAvatar, Clipboard, Menu, Grid, Uuid, GlobalServices, openLoginWindow */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ (function () { // BEGIN LOCAL_SCOPE @@ -338,10 +338,6 @@ // we currently assume a wearable is a single entity Entities.editEntity(pastedEntityIDs[0], offsets); } - - if (isActive) { - selectionManager.setSelections(pastedEntityIDs); - } } else { Window.notifyEditError("Can't import entities: entities would be out of bounds."); } From 3642d6cfdfb72f25df66ce1339c6ec39888ead1a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 5 Dec 2017 11:26:36 -0800 Subject: [PATCH 06/26] fix includes --- scripts/system/marketplaces/marketplaces.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index d0530dc775..c591c088c8 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -14,8 +14,9 @@ (function () { // BEGIN LOCAL_SCOPE - Script.include("../libraries/WebTablet.js"); - Script.include("../libraries/gridTool.js"); + Script.include("/~/system/libraries/accountUtils.js"); + Script.include("/~/system/libraries/WebTablet.js"); + Script.include("/~/system/libraries/gridTool.js"); var METAVERSE_SERVER_URL = Account.metaverseServerURL; var MARKETPLACE_URL = METAVERSE_SERVER_URL + "/marketplace"; From 4ed689672ea2a9b0783b0eb516ac8facb9d2d73b Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Wed, 6 Dec 2017 16:07:29 -0800 Subject: [PATCH 07/26] can fetch poly asset list synchronously --- .../GooglePolyScriptingInterface.cpp | 179 +++++++++++++++++- .../scripting/GooglePolyScriptingInterface.h | 12 ++ 2 files changed, 189 insertions(+), 2 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index bad9b39972..99e2d699d0 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -9,13 +9,188 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + #include "GooglePolyScriptingInterface.h" #include "ScriptEngineLogging.h" -GooglePolyScriptingInterface::GooglePolyScriptingInterface() { +QString listPolyUrl = "https://poly.googleapis.com/v1/assets?"; +QString getPolyUrl = "https://poly.googleapis.com/v1/assets/model?"; +GooglePolyScriptingInterface::GooglePolyScriptingInterface() { + // nothing to be implemented } void GooglePolyScriptingInterface::testPrint() { qCDebug(scriptengine) << "Google Poly interface exists"; -} \ No newline at end of file +} + +void GooglePolyScriptingInterface::setAPIKey(QString key) { + authCode = key; +} + +void GooglePolyScriptingInterface::getAssetList() { + authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; + //authCode = "broke"; + QUrl url(listPolyUrl + "key=" + authCode); + QByteArray jsonString = getHTTPRequest(url); + qCDebug(scriptengine) << "the list: " << jsonString; + QJsonObject json = makeJSONObject(&jsonString, true); + +} + +// FIXME: synchronous = not good code +QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { + QNetworkAccessManager manager; + QNetworkReply *response = manager.get(QNetworkRequest(url)); + QEventLoop event; + connect(response, SIGNAL(finished()), &event, SLOT(quit())); + event.exec(); + + return response->readAll(); + +} + +QJsonObject GooglePolyScriptingInterface::makeJSONObject(QByteArray* response, bool isList) { + //QString firstItem = QString::fromUtf8(response->readAll()); + QJsonDocument doc = QJsonDocument::fromJson(*response); + qCDebug(scriptengine) << "json doc is empty: " << doc.isEmpty(); + QJsonObject obj = doc.object(); + qCDebug(scriptengine) << "json obj: " << obj; + qCDebug(scriptengine) << "json list: " << obj.keys(); + if (obj.keys().first() == "error") { + qCDebug(scriptengine) << "Invalid API key"; + return obj; + } + qCDebug(scriptengine) << "total size: " << obj.value("totalSize").toString(); + qCDebug(scriptengine) << "in assets: " << obj.value("assets"); + return obj; +} + +/*void GooglePolyScriptingInterface::getAssetList() { + authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; + QUrl url(listPolyUrl + "key=" + authCode); + QByteArray reply = getHTTPRequest(url); + qCDebug(scriptengine) << "the list: " << test; +} + +// FIXME: synchronous = not good code +QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { + QNetworkAccessManager manager; + QNetworkReply *response = manager.get(QNetworkRequest(url)); + QEventLoop event; + connect(response, SIGNAL(finished()), &event, SLOT(quit())); + event.exec(); + return response->readAll(); +} + +*/ + +/* useful for constructing the url? + + QUrl url("http://gdata.youtube.com/feeds/api/standardfeeds/"); + QString method = "most_popular"; + url.setPath(QString("%1%2").arg(url.path()).arg(method)); + + QMap params; + params["alt"] = "json"; + params["v"] = "2"; + + foreach(QString param, params.keys()) { + url.addQueryItem(param, params[param].toString()); + } + +*/ + +/* NONE OF THESE HTTP GET METHODS WORK D: +https://stackoverflow.com/questions/28267477/getting-a-page-content-with-qt kinda used rn + +this correctly returns the asset list but is apparently synchronous and not a good way to do it +https://stackoverflow.com/questions/24965972/qt-getting-source-html-code-of-a-web-page-hosted-on-the-internet +void GooglePolyScriptingInterface::getAssetList() { + authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; + QUrl url(listPolyUrl + "key=" + authCode); + QNetworkAccessManager manager; + QNetworkReply *response = manager.get(QNetworkRequest(url)); + QEventLoop event; + connect(response, SIGNAL(finished()), &event, SLOT(quit())); + event.exec(); + QString firstItem = response->readAll(); + //QJsonArray arr; + //QJsonObject jsonObject = QJsonDocument::fromJson(response->readAll()).object(); + //QString firstItem = jsonObject["assets"].toString(); + qCDebug(scriptengine) << "first item: " << firstItem; + //qCDebug(scriptengine) << "api key: " << authCode; + //return arr; +} + +this didn't work either https://stackoverflow.com/a/24966317 + QScopedPointer manager(new QNetworkAccessManager); + QNetworkReply* response = manager->get(QNetworkRequest(url)); + QObject::connect(manager, &QNetworkAccessManager::finished, [manager, response] { + response->deleteLater(); + manager->deleteLater(); + if (response->error() != QNetworkReply::NoError) return; + QString contentType = + response->header(QNetworkRequest::ContentTypeHeader).toString(); + if (!contentType.contains("charset=utf-8")) { + qWarning() << "Content charsets other than utf-8 are not implemented yet."; + return; + } + QString html = QString::fromUtf8(response->readAll()); + // do something with the data + }) && manager.take(); + + +or this :( https://stackoverflow.com/questions/39518749/make-get-request-to-web-service-get-json-response-and-update-gui-in-qt + qCDebug(scriptengine) << "gonna get assets with " << url; + QNetworkAccessManager manager; + QNetworkReply* reply = manager.get(QNetworkRequest(url)); + QObject::connect(&manager, &QNetworkAccessManager::finished, + [reply]{ + qCDebug(scriptengine) << "boo radley"; + if (reply->error() != QNetworkReply::NoError) { + qCDebug(scriptengine) << "Poly API failed to respond"; + //manager.clearAccessCache(); + } else { + QJsonObject jsonObject = QJsonDocument::fromJson(reply->readAll()).object(); + QString firstItem = jsonObject["assets"].toString(); + qCDebug(scriptengine) << "first item: " << firstItem; + } + reply->deleteLater(); + }); + +or this :(( http://blog.mathieu-leplatre.info/access-a-json-webservice-with-qt-c.html + //QJsonArray arr; + //QJsonObject jsonObject = QJsonDocument::fromJson(response->readAll()).object(); + //QString firstItem = jsonObject["assets"].toString(); + qCDebug(scriptengine) << "first item: " << firstItem; + //qCDebug(scriptengine) << "api key: " << authCode; + //return arr; + QNetworkAccessManager manager; + QNetworkReply* response = manager.get(QNetworkRequest(url)); + QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onResult(QNetworkReply*))); + + return ""; + } + + void GooglePolyScriptingInterface::onResult(QNetworkReply* reply) { + if (reply->error() != QNetworkReply::NoError) { + qCDebug(scriptengine) << "Poly API failed to respond"; + return; + } + QString firstItem = reply->readAll(); + + qCDebug(scriptengine) << "first item: " << firstItem; + } + +*/ \ No newline at end of file diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index 04afef8a58..37b7395914 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -22,6 +22,18 @@ public: public slots: void testPrint(); + void setAPIKey(QString key); + + //QJsonArray GooglePolyScriptingInterface::getAssetList(); + void getAssetList(); + +private: + QByteArray getHTTPRequest(QUrl url); + QJsonObject makeJSONObject(QByteArray* response, bool isList); + //void onResult(QNetworkReply* reply); + + QString authCode; + }; From 1d5875c45b92f6683d25b902f55dab93ef5ceff1 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Wed, 6 Dec 2017 17:40:39 -0800 Subject: [PATCH 08/26] removed key --- .../scripting/GooglePolyScriptingInterface.cpp | 15 ++++++++++----- .../src/scripting/GooglePolyScriptingInterface.h | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index 20e83fd14e..78cf6e1fc7 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -39,12 +39,11 @@ void GooglePolyScriptingInterface::setAPIKey(QString key) { } void GooglePolyScriptingInterface::getAssetList() { - authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; //authCode = "broke"; QUrl url(listPolyUrl + "key=" + authCode); QByteArray jsonString = getHTTPRequest(url); qCDebug(scriptengine) << "the list: " << jsonString; - QJsonObject json = makeJSONObject(&jsonString, true); + QJsonObject json = makeJSON(&jsonString, true).toJsonObject; } @@ -60,7 +59,8 @@ QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { } -QJsonObject GooglePolyScriptingInterface::makeJSONObject(QByteArray* response, bool isList) { +// since the list is a QJsonArray and a single model is a QJsonObject +QVariant GooglePolyScriptingInterface::makeJSON(QByteArray* response, bool isList) { //QString firstItem = QString::fromUtf8(response->readAll()); QJsonDocument doc = QJsonDocument::fromJson(*response); qCDebug(scriptengine) << "json doc is empty: " << doc.isEmpty(); @@ -71,8 +71,13 @@ QJsonObject GooglePolyScriptingInterface::makeJSONObject(QByteArray* response, b qCDebug(scriptengine) << "Invalid API key"; return obj; } - qCDebug(scriptengine) << "total size: " << obj.value("totalSize").toString(); - qCDebug(scriptengine) << "in assets: " << obj.value("assets"); + qCDebug(scriptengine) << "total size: " << obj.value("totalSize"); + qCDebug(scriptengine) << "the assets: " << obj.value("assets"); + QJsonArray arr = obj.value("assets").toArray(); + qCDebug(scriptengine) << "in array: " << arr; + QJsonObject first = arr.takeAt(0).toObject(); + qCDebug(scriptengine) << "first asset: " << first; + qCDebug(scriptengine) << "first asset description: " << first.value("description"); return obj; } diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index 37b7395914..707eabc0af 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -29,7 +29,7 @@ public slots: private: QByteArray getHTTPRequest(QUrl url); - QJsonObject makeJSONObject(QByteArray* response, bool isList); + QVariant makeJSON(QByteArray* response, bool isList); //void onResult(QNetworkReply* reply); QString authCode; From 4659d22021b9b201e505673a2847c176b668c971 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 7 Dec 2017 21:32:18 -0800 Subject: [PATCH 09/26] work around a crash when closing CREATE --- scripts/system/libraries/gridTool.js | 4 +++- scripts/system/marketplaces/marketplaces.js | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/system/libraries/gridTool.js b/scripts/system/libraries/gridTool.js index 2c417a9dde..19d4417a12 100644 --- a/scripts/system/libraries/gridTool.js +++ b/scripts/system/libraries/gridTool.js @@ -242,7 +242,9 @@ GridTool = function(opts) { horizontalGrid.addListener(function(data) { webView.emitScriptEvent(JSON.stringify(data)); - selectionDisplay.updateHandles(); + if (selectionDisplay) { + selectionDisplay.updateHandles(); + } }); webView.webEventReceived.connect(function(data) { diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index c9c439e57d..19b45be015 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -12,6 +12,8 @@ Quat, MyAvatar, Clipboard, Menu, Grid, Uuid, GlobalServices, openLoginWindow */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ +var selectionDisplay = null; // for gridTool.js to ignore + (function () { // BEGIN LOCAL_SCOPE Script.include("/~/system/libraries/accountUtils.js"); From dc999401d598a4e04ca826f9ccf257be88463701 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Mon, 4 Dec 2017 16:46:58 -0800 Subject: [PATCH 10/26] Created poly scripting interface template --- interface/src/Application.cpp | 3 ++ .../GooglePolyScriptingInterface.cpp | 21 ++++++++++++++ .../scripting/GooglePolyScriptingInterface.h | 28 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 interface/src/scripting/GooglePolyScriptingInterface.cpp create mode 100644 interface/src/scripting/GooglePolyScriptingInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0176acf108..a5ba4f86bd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -191,6 +191,7 @@ #include #include #include +#include #include #include @@ -698,6 +699,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(nullptr, qApp->getOcteeSceneStats()); DependencyManager::set(); DependencyManager::set(); @@ -5900,6 +5902,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerGlobalObject("Users", DependencyManager::get().data()); scriptEngine->registerGlobalObject("LimitlessSpeechRecognition", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("GooglePoly", DependencyManager::get().data()); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { scriptEngine->registerGlobalObject("Steam", new SteamScriptingInterface(scriptEngine.data(), steamClient.get())); diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp new file mode 100644 index 0000000000..bad9b39972 --- /dev/null +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -0,0 +1,21 @@ +// +// GooglePolyScriptingInterface.cpp +// interface/src/scripting +// +// Created by Elisa Lupin-Jimenez on 12/3/2017. +// Copyright 2017 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 "GooglePolyScriptingInterface.h" +#include "ScriptEngineLogging.h" + +GooglePolyScriptingInterface::GooglePolyScriptingInterface() { + +} + +void GooglePolyScriptingInterface::testPrint() { + qCDebug(scriptengine) << "Google Poly interface exists"; +} \ No newline at end of file diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h new file mode 100644 index 0000000000..04afef8a58 --- /dev/null +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -0,0 +1,28 @@ +// +// GooglePolyScriptingInterface.h +// interface/src/scripting +// +// Created by Elisa Lupin-Jimenez on 12/3/2017. +// Copyright 2017 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 +// + +#ifndef hifi_GooglePolyScriptingInterface_h +#define hifi_GooglePolyScriptingInterface_h + +#include +#include + +class GooglePolyScriptingInterface : public QObject, public Dependency { + Q_OBJECT +public: + GooglePolyScriptingInterface(); + +public slots: + void testPrint(); + +}; + +#endif // hifi_GooglePolyScriptingInterface_h \ No newline at end of file From 392f290dd62e1ba986af78bb6020dc83710184a0 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Wed, 6 Dec 2017 16:07:29 -0800 Subject: [PATCH 11/26] can fetch poly asset list synchronously --- .../GooglePolyScriptingInterface.cpp | 179 +++++++++++++++++- .../scripting/GooglePolyScriptingInterface.h | 12 ++ 2 files changed, 189 insertions(+), 2 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index bad9b39972..99e2d699d0 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -9,13 +9,188 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + #include "GooglePolyScriptingInterface.h" #include "ScriptEngineLogging.h" -GooglePolyScriptingInterface::GooglePolyScriptingInterface() { +QString listPolyUrl = "https://poly.googleapis.com/v1/assets?"; +QString getPolyUrl = "https://poly.googleapis.com/v1/assets/model?"; +GooglePolyScriptingInterface::GooglePolyScriptingInterface() { + // nothing to be implemented } void GooglePolyScriptingInterface::testPrint() { qCDebug(scriptengine) << "Google Poly interface exists"; -} \ No newline at end of file +} + +void GooglePolyScriptingInterface::setAPIKey(QString key) { + authCode = key; +} + +void GooglePolyScriptingInterface::getAssetList() { + authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; + //authCode = "broke"; + QUrl url(listPolyUrl + "key=" + authCode); + QByteArray jsonString = getHTTPRequest(url); + qCDebug(scriptengine) << "the list: " << jsonString; + QJsonObject json = makeJSONObject(&jsonString, true); + +} + +// FIXME: synchronous = not good code +QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { + QNetworkAccessManager manager; + QNetworkReply *response = manager.get(QNetworkRequest(url)); + QEventLoop event; + connect(response, SIGNAL(finished()), &event, SLOT(quit())); + event.exec(); + + return response->readAll(); + +} + +QJsonObject GooglePolyScriptingInterface::makeJSONObject(QByteArray* response, bool isList) { + //QString firstItem = QString::fromUtf8(response->readAll()); + QJsonDocument doc = QJsonDocument::fromJson(*response); + qCDebug(scriptengine) << "json doc is empty: " << doc.isEmpty(); + QJsonObject obj = doc.object(); + qCDebug(scriptengine) << "json obj: " << obj; + qCDebug(scriptengine) << "json list: " << obj.keys(); + if (obj.keys().first() == "error") { + qCDebug(scriptengine) << "Invalid API key"; + return obj; + } + qCDebug(scriptengine) << "total size: " << obj.value("totalSize").toString(); + qCDebug(scriptengine) << "in assets: " << obj.value("assets"); + return obj; +} + +/*void GooglePolyScriptingInterface::getAssetList() { + authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; + QUrl url(listPolyUrl + "key=" + authCode); + QByteArray reply = getHTTPRequest(url); + qCDebug(scriptengine) << "the list: " << test; +} + +// FIXME: synchronous = not good code +QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { + QNetworkAccessManager manager; + QNetworkReply *response = manager.get(QNetworkRequest(url)); + QEventLoop event; + connect(response, SIGNAL(finished()), &event, SLOT(quit())); + event.exec(); + return response->readAll(); +} + +*/ + +/* useful for constructing the url? + + QUrl url("http://gdata.youtube.com/feeds/api/standardfeeds/"); + QString method = "most_popular"; + url.setPath(QString("%1%2").arg(url.path()).arg(method)); + + QMap params; + params["alt"] = "json"; + params["v"] = "2"; + + foreach(QString param, params.keys()) { + url.addQueryItem(param, params[param].toString()); + } + +*/ + +/* NONE OF THESE HTTP GET METHODS WORK D: +https://stackoverflow.com/questions/28267477/getting-a-page-content-with-qt kinda used rn + +this correctly returns the asset list but is apparently synchronous and not a good way to do it +https://stackoverflow.com/questions/24965972/qt-getting-source-html-code-of-a-web-page-hosted-on-the-internet +void GooglePolyScriptingInterface::getAssetList() { + authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; + QUrl url(listPolyUrl + "key=" + authCode); + QNetworkAccessManager manager; + QNetworkReply *response = manager.get(QNetworkRequest(url)); + QEventLoop event; + connect(response, SIGNAL(finished()), &event, SLOT(quit())); + event.exec(); + QString firstItem = response->readAll(); + //QJsonArray arr; + //QJsonObject jsonObject = QJsonDocument::fromJson(response->readAll()).object(); + //QString firstItem = jsonObject["assets"].toString(); + qCDebug(scriptengine) << "first item: " << firstItem; + //qCDebug(scriptengine) << "api key: " << authCode; + //return arr; +} + +this didn't work either https://stackoverflow.com/a/24966317 + QScopedPointer manager(new QNetworkAccessManager); + QNetworkReply* response = manager->get(QNetworkRequest(url)); + QObject::connect(manager, &QNetworkAccessManager::finished, [manager, response] { + response->deleteLater(); + manager->deleteLater(); + if (response->error() != QNetworkReply::NoError) return; + QString contentType = + response->header(QNetworkRequest::ContentTypeHeader).toString(); + if (!contentType.contains("charset=utf-8")) { + qWarning() << "Content charsets other than utf-8 are not implemented yet."; + return; + } + QString html = QString::fromUtf8(response->readAll()); + // do something with the data + }) && manager.take(); + + +or this :( https://stackoverflow.com/questions/39518749/make-get-request-to-web-service-get-json-response-and-update-gui-in-qt + qCDebug(scriptengine) << "gonna get assets with " << url; + QNetworkAccessManager manager; + QNetworkReply* reply = manager.get(QNetworkRequest(url)); + QObject::connect(&manager, &QNetworkAccessManager::finished, + [reply]{ + qCDebug(scriptengine) << "boo radley"; + if (reply->error() != QNetworkReply::NoError) { + qCDebug(scriptengine) << "Poly API failed to respond"; + //manager.clearAccessCache(); + } else { + QJsonObject jsonObject = QJsonDocument::fromJson(reply->readAll()).object(); + QString firstItem = jsonObject["assets"].toString(); + qCDebug(scriptengine) << "first item: " << firstItem; + } + reply->deleteLater(); + }); + +or this :(( http://blog.mathieu-leplatre.info/access-a-json-webservice-with-qt-c.html + //QJsonArray arr; + //QJsonObject jsonObject = QJsonDocument::fromJson(response->readAll()).object(); + //QString firstItem = jsonObject["assets"].toString(); + qCDebug(scriptengine) << "first item: " << firstItem; + //qCDebug(scriptengine) << "api key: " << authCode; + //return arr; + QNetworkAccessManager manager; + QNetworkReply* response = manager.get(QNetworkRequest(url)); + QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onResult(QNetworkReply*))); + + return ""; + } + + void GooglePolyScriptingInterface::onResult(QNetworkReply* reply) { + if (reply->error() != QNetworkReply::NoError) { + qCDebug(scriptengine) << "Poly API failed to respond"; + return; + } + QString firstItem = reply->readAll(); + + qCDebug(scriptengine) << "first item: " << firstItem; + } + +*/ \ No newline at end of file diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index 04afef8a58..37b7395914 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -22,6 +22,18 @@ public: public slots: void testPrint(); + void setAPIKey(QString key); + + //QJsonArray GooglePolyScriptingInterface::getAssetList(); + void getAssetList(); + +private: + QByteArray getHTTPRequest(QUrl url); + QJsonObject makeJSONObject(QByteArray* response, bool isList); + //void onResult(QNetworkReply* reply); + + QString authCode; + }; From f7be67b5b2277056097fb97e6ae0060306eb1e8e Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Wed, 6 Dec 2017 17:40:39 -0800 Subject: [PATCH 12/26] removed key --- .../scripting/GooglePolyScriptingInterface.cpp | 15 ++++++++++----- .../src/scripting/GooglePolyScriptingInterface.h | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index 99e2d699d0..b353b4b3b4 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -39,12 +39,11 @@ void GooglePolyScriptingInterface::setAPIKey(QString key) { } void GooglePolyScriptingInterface::getAssetList() { - authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; //authCode = "broke"; QUrl url(listPolyUrl + "key=" + authCode); QByteArray jsonString = getHTTPRequest(url); qCDebug(scriptengine) << "the list: " << jsonString; - QJsonObject json = makeJSONObject(&jsonString, true); + QJsonObject json = makeJSON(&jsonString, true).toJsonObject; } @@ -60,7 +59,8 @@ QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { } -QJsonObject GooglePolyScriptingInterface::makeJSONObject(QByteArray* response, bool isList) { +// since the list is a QJsonArray and a single model is a QJsonObject +QVariant GooglePolyScriptingInterface::makeJSON(QByteArray* response, bool isList) { //QString firstItem = QString::fromUtf8(response->readAll()); QJsonDocument doc = QJsonDocument::fromJson(*response); qCDebug(scriptengine) << "json doc is empty: " << doc.isEmpty(); @@ -71,8 +71,13 @@ QJsonObject GooglePolyScriptingInterface::makeJSONObject(QByteArray* response, b qCDebug(scriptengine) << "Invalid API key"; return obj; } - qCDebug(scriptengine) << "total size: " << obj.value("totalSize").toString(); - qCDebug(scriptengine) << "in assets: " << obj.value("assets"); + qCDebug(scriptengine) << "total size: " << obj.value("totalSize"); + qCDebug(scriptengine) << "the assets: " << obj.value("assets"); + QJsonArray arr = obj.value("assets").toArray(); + qCDebug(scriptengine) << "in array: " << arr; + QJsonObject first = arr.takeAt(0).toObject(); + qCDebug(scriptengine) << "first asset: " << first; + qCDebug(scriptengine) << "first asset description: " << first.value("description"); return obj; } diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index 37b7395914..707eabc0af 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -29,7 +29,7 @@ public slots: private: QByteArray getHTTPRequest(QUrl url); - QJsonObject makeJSONObject(QByteArray* response, bool isList); + QVariant makeJSON(QByteArray* response, bool isList); //void onResult(QNetworkReply* reply); QString authCode; From e49181c3a22505900cedc39a1b5da2b22fbd1cc9 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Wed, 13 Dec 2017 17:45:57 -0800 Subject: [PATCH 13/26] added getAssetList() and getFBX() --- .../GooglePolyScriptingInterface.cpp | 113 ++++++++++++++---- .../scripting/GooglePolyScriptingInterface.h | 12 +- 2 files changed, 99 insertions(+), 26 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index b353b4b3b4..8b48f1d115 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -10,6 +10,7 @@ // #include +#include #include #include #include @@ -18,7 +19,9 @@ #include //#include #include +#include #include +#include #include "GooglePolyScriptingInterface.h" #include "ScriptEngineLogging.h" @@ -26,28 +29,81 @@ QString listPolyUrl = "https://poly.googleapis.com/v1/assets?"; QString getPolyUrl = "https://poly.googleapis.com/v1/assets/model?"; +//authCode = "broke"; + +QStringList validFormats = QStringList() << "BLOCKS" << "FBX" << "GLTF" << "GLTF2" << "OBJ" << "TILT" << ""; +QStringList validCategories = QStringList() << "animals" << "architecture" << "art" << "food" << + "nature" << "objects" << "people" << "scenes" << "technology" << "transport" << ""; + GooglePolyScriptingInterface::GooglePolyScriptingInterface() { // nothing to be implemented } -void GooglePolyScriptingInterface::testPrint() { - qCDebug(scriptengine) << "Google Poly interface exists"; +QJsonArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { + QUrl url = formatURLQuery(keyword, category, format); + if (!url.isEmpty()) { + QByteArray jsonString = getHTTPRequest(url); + QJsonArray json = parseJSON(&jsonString, 0).toJsonArray(); + qCDebug(scriptengine) << "first asset name: " << json.at(0).toObject().value("displayName"); + return json; + } else { + qCDebug(scriptengine) << "Invalid filters were specified."; + return QJsonArray(); + } +} + +QString GooglePolyScriptingInterface::getFBX(QString keyword, QString category) { + QUrl url = formatURLQuery(keyword, category, "FBX"); + qCDebug(scriptengine) << "google url: " << url; + if (!url.isEmpty()) { + QByteArray jsonString = getHTTPRequest(url); + qCDebug(scriptengine) << "the list: " << jsonString; + QString modelURL = parseJSON(&jsonString, 1).toString(); + + qCDebug(scriptengine) << "the model url: " << modelURL; + return modelURL; + } else { + qCDebug(scriptengine) << "Invalid filters were specified."; + return ""; + } + +} + +void GooglePolyScriptingInterface::testPrint(QString input) { + qCDebug(scriptengine) << "Google message: " << input; } void GooglePolyScriptingInterface::setAPIKey(QString key) { authCode = key; } -void GooglePolyScriptingInterface::getAssetList() { - //authCode = "broke"; - QUrl url(listPolyUrl + "key=" + authCode); - QByteArray jsonString = getHTTPRequest(url); - qCDebug(scriptengine) << "the list: " << jsonString; - QJsonObject json = makeJSON(&jsonString, true).toJsonObject; - +int GooglePolyScriptingInterface::getRandIntInRange(int length) { + QTime time = QTime::currentTime(); + qsrand((uint)time.msec()); + return qrand() % length; } -// FIXME: synchronous = not good code +QUrl GooglePolyScriptingInterface::formatURLQuery(QString keyword, QString category, QString format) { + QString queries; + if (!validFormats.contains(format) || !validCategories.contains(category)) { + return QUrl(""); + } else { + if (!keyword.isEmpty()) { + keyword.replace(" ", "+"); + queries.append("&keywords=" + keyword); + } + if (!category.isEmpty()) { + queries.append("&category=" + category); + } + if (!format.isEmpty()) { + queries.append("&format=" + format); + } + QString urlString = QString(listPolyUrl + "key=" + authCode + queries); + return QUrl(urlString); + } +} + +// FIXME: synchronous QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { QNetworkAccessManager manager; QNetworkReply *response = manager.get(QNetworkRequest(url)); @@ -56,31 +112,46 @@ QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { event.exec(); return response->readAll(); - + } // since the list is a QJsonArray and a single model is a QJsonObject -QVariant GooglePolyScriptingInterface::makeJSON(QByteArray* response, bool isList) { +QVariant GooglePolyScriptingInterface::parseJSON(QByteArray* response, int fileType) { //QString firstItem = QString::fromUtf8(response->readAll()); QJsonDocument doc = QJsonDocument::fromJson(*response); - qCDebug(scriptengine) << "json doc is empty: " << doc.isEmpty(); QJsonObject obj = doc.object(); qCDebug(scriptengine) << "json obj: " << obj; qCDebug(scriptengine) << "json list: " << obj.keys(); if (obj.keys().first() == "error") { qCDebug(scriptengine) << "Invalid API key"; + return QJsonObject(); + } + qCDebug(scriptengine) << "the assets: " << obj.value("assets"); + if (fileType == 0 || fileType == 1) { + QJsonArray arr = obj.value("assets").toArray(); + qCDebug(scriptengine) << "in array: " << arr; + // return model url + if (fileType == 1) { + int random = getRandIntInRange(arr.size()); + QJsonObject json = arr.at(random).toObject(); + qCDebug(scriptengine) << random << "th object: " << json; + qCDebug(scriptengine) << random << "th asset name: " << json.value("displayName"); + // nested JSONs + return json.value("formats").toArray().at(0).toObject().value("root").toObject().value("url"); + } + // return whole asset list + return arr; + // return specific object + } else { return obj; } - qCDebug(scriptengine) << "total size: " << obj.value("totalSize"); - qCDebug(scriptengine) << "the assets: " << obj.value("assets"); - QJsonArray arr = obj.value("assets").toArray(); - qCDebug(scriptengine) << "in array: " << arr; - QJsonObject first = arr.takeAt(0).toObject(); - qCDebug(scriptengine) << "first asset: " << first; - qCDebug(scriptengine) << "first asset description: " << first.value("description"); - return obj; } + + + + + /*void GooglePolyScriptingInterface::getAssetList() { authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; QUrl url(listPolyUrl + "key=" + authCode); diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index 707eabc0af..a90557e593 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -21,18 +21,20 @@ public: GooglePolyScriptingInterface(); public slots: - void testPrint(); + void testPrint(QString input); void setAPIKey(QString key); - //QJsonArray GooglePolyScriptingInterface::getAssetList(); - void getAssetList(); + QJsonArray getAssetList(QString keyword, QString category, QString format); + QString getFBX(QString keyword, QString category); private: + QUrl formatURLQuery(QString keyword, QString category, QString format); QByteArray getHTTPRequest(QUrl url); - QVariant makeJSON(QByteArray* response, bool isList); + QVariant parseJSON(QByteArray* response, int fileType); + int getRandIntInRange(int length); //void onResult(QNetworkReply* reply); - QString authCode; + //QString authCode; }; From e7fad0586713bb13074836532fd8a13562235520 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Mon, 18 Dec 2017 14:20:51 -0800 Subject: [PATCH 14/26] enabled fbx, obj, and blocks model url retrieval --- .../GooglePolyScriptingInterface.cpp | 105 +++++++++--------- .../scripting/GooglePolyScriptingInterface.h | 10 +- 2 files changed, 63 insertions(+), 52 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index 7ec6cd343d..8080456e0d 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -17,7 +17,6 @@ #include #include #include -//#include #include #include #include @@ -26,10 +25,8 @@ #include "GooglePolyScriptingInterface.h" #include "ScriptEngineLogging.h" -QString listPolyUrl = "https://poly.googleapis.com/v1/assets?"; -QString getPolyUrl = "https://poly.googleapis.com/v1/assets/model?"; - -QString authCode = "broke"; +const QString listPolyUrl = "https://poly.googleapis.com/v1/assets?"; +const QString getPolyUrl = "https://poly.googleapis.com/v1/assets/model?"; QStringList validFormats = QStringList() << "BLOCKS" << "FBX" << "GLTF" << "GLTF2" << "OBJ" << "TILT" << ""; QStringList validCategories = QStringList() << "animals" << "architecture" << "art" << "food" << @@ -42,8 +39,7 @@ GooglePolyScriptingInterface::GooglePolyScriptingInterface() { QJsonArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { QUrl url = formatURLQuery(keyword, category, format); if (!url.isEmpty()) { - QByteArray jsonString = getHTTPRequest(url); - QJsonArray json = parseJSON(&jsonString, 0).toJsonArray(); + QJsonArray json = parseJSON(url, 0).toJsonArray(); qCDebug(scriptengine) << "first asset name: " << json.at(0).toObject().value("displayName"); return json; } else { @@ -54,19 +50,40 @@ QJsonArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString c QString GooglePolyScriptingInterface::getFBX(QString keyword, QString category) { QUrl url = formatURLQuery(keyword, category, "FBX"); - qCDebug(scriptengine) << "google url: " << url; - if (!url.isEmpty()) { - QByteArray jsonString = getHTTPRequest(url); - qCDebug(scriptengine) << "the list: " << jsonString; - QString modelURL = parseJSON(&jsonString, 1).toString(); - - qCDebug(scriptengine) << "the model url: " << modelURL; - return modelURL; - } else { - qCDebug(scriptengine) << "Invalid filters were specified."; - return ""; - } + return getModelURL(url); +} +QString GooglePolyScriptingInterface::getOBJ(QString keyword, QString category) { + QUrl url = formatURLQuery(keyword, category, "OBJ"); + return getModelURL(url); +} + +QString GooglePolyScriptingInterface::getBlocks(QString keyword, QString category) { + QUrl url = formatURLQuery(keyword, category, "BLOCKS"); + qCDebug(scriptengine) << "Google url request: " << url; + return getModelURL(url); +} + +/* +// This method will not work until we support Tilt models +QString GooglePolyScriptingInterface::getTilt(QString keyword, QString category) { + QUrl url = formatURLQuery(keyword, category, "TILT"); + return getModelURL(url); +} +*/ + +// can provide asset name or full URL to model +QString GooglePolyScriptingInterface::getModelInfo(QString name) { + if (name.contains("poly.googleapis")) { + QStringList list = name.split("/"); + name = list[4]; + } + QString urlString = QString(getPolyUrl); + urlString = urlString.replace("model", name) + "key=" + authCode; + qCDebug(scriptengine) << "google get url: " << urlString; + QUrl url(urlString); + QByteArray json = parseJSON(url, 2).toByteArray(); + return json; } void GooglePolyScriptingInterface::testPrint(QString input) { @@ -103,6 +120,16 @@ QUrl GooglePolyScriptingInterface::formatURLQuery(QString keyword, QString categ } } +QString GooglePolyScriptingInterface::getModelURL(QUrl url) { + qCDebug(scriptengine) << "Google url request: " << url; + if (!url.isEmpty()) { + return parseJSON(url, 1).toString(); + } else { + qCDebug(scriptengine) << "Invalid filters were specified."; + return ""; + } +} + // FIXME: synchronous QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { QNetworkAccessManager manager; @@ -115,26 +142,23 @@ QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { } // since the list is a QJsonArray and a single model is a QJsonObject -QVariant GooglePolyScriptingInterface::parseJSON(QByteArray* response, int fileType) { +QVariant GooglePolyScriptingInterface::parseJSON(QUrl url, int fileType) { //QString firstItem = QString::fromUtf8(response->readAll()); - QJsonDocument doc = QJsonDocument::fromJson(*response); + QByteArray jsonString = getHTTPRequest(url); + QJsonDocument doc = QJsonDocument::fromJson(jsonString); QJsonObject obj = doc.object(); - qCDebug(scriptengine) << "json obj: " << obj; - qCDebug(scriptengine) << "json list: " << obj.keys(); if (obj.keys().first() == "error") { - qCDebug(scriptengine) << "Invalid API key"; + QString error = obj.value("error").toObject().value("message").toString(); + qCDebug(scriptengine) << error; return QJsonObject(); } qCDebug(scriptengine) << "the assets: " << obj.value("assets"); if (fileType == 0 || fileType == 1) { QJsonArray arr = obj.value("assets").toArray(); - qCDebug(scriptengine) << "in array: " << arr; // return model url if (fileType == 1) { int random = getRandIntInRange(arr.size()); QJsonObject json = arr.at(random).toObject(); - qCDebug(scriptengine) << random << "th object: " << json; - qCDebug(scriptengine) << random << "th asset name: " << json.value("displayName"); // nested JSONs return json.value("formats").toArray().at(0).toObject().value("root").toObject().value("url"); } @@ -142,17 +166,14 @@ QVariant GooglePolyScriptingInterface::parseJSON(QByteArray* response, int fileT return arr; // return specific object } else { - return obj; + //return obj; + //return doc.toJson(); + return jsonString; } } -/*void GooglePolyScriptingInterface::getAssetList() { - authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; - QUrl url(listPolyUrl + "key=" + authCode); - QByteArray reply = getHTTPRequest(url); - qCDebug(scriptengine) << "the list: " << test; -} +/* // FIXME: synchronous = not good code QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { @@ -164,23 +185,7 @@ QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { return response->readAll(); } -*/ -/* useful for constructing the url? - - QUrl url("http://gdata.youtube.com/feeds/api/standardfeeds/"); - QString method = "most_popular"; - url.setPath(QString("%1%2").arg(url.path()).arg(method)); - - QMap params; - params["alt"] = "json"; - params["v"] = "2"; - - foreach(QString param, params.keys()) { - url.addQueryItem(param, params[param].toString()); - } - -*/ /* NONE OF THESE HTTP GET METHODS WORK D: https://stackoverflow.com/questions/28267477/getting-a-page-content-with-qt kinda used rn diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index 1ae7554a9d..acbc27b90c 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -17,6 +17,7 @@ class GooglePolyScriptingInterface : public QObject, public Dependency { Q_OBJECT + public: GooglePolyScriptingInterface(); @@ -26,15 +27,20 @@ public slots: QJsonArray getAssetList(QString keyword, QString category, QString format); QString getFBX(QString keyword, QString category); + QString getOBJ(QString keyword, QString category); + QString getBlocks(QString keyword, QString category); + //QString getTilt(QString keyword, QString category); + QString getModelInfo(QString name); private: QUrl formatURLQuery(QString keyword, QString category, QString format); + QString getModelURL(QUrl url); QByteArray getHTTPRequest(QUrl url); - QVariant parseJSON(QByteArray* response, int fileType); + QVariant parseJSON(QUrl url, int fileType); int getRandIntInRange(int length); //void onResult(QNetworkReply* reply); - //QString authCode; + QString authCode; }; From 1ee8445f433c77d7310bc7cad0e873c79e804318 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Mon, 18 Dec 2017 17:47:21 -0800 Subject: [PATCH 15/26] added gltf import feature, getAssetList() not working --- .../GooglePolyScriptingInterface.cpp | 60 +++++++++++++------ .../scripting/GooglePolyScriptingInterface.h | 5 +- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index 8080456e0d..42c3b825ba 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -36,17 +36,39 @@ GooglePolyScriptingInterface::GooglePolyScriptingInterface() { // nothing to be implemented } -QJsonArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { +void GooglePolyScriptingInterface::setAPIKey(QString key) { + authCode = key; +} + +QByteArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { QUrl url = formatURLQuery(keyword, category, format); if (!url.isEmpty()) { + //QJsonArray json = parseJSON(url, 0).toJsonArray(); + //qCDebug(scriptengine) << "first asset name: " << json.at(0).toObject().value("displayName"); + QByteArray json = parseJSON(url, 0).toJsonDocument().toJson(); + qCDebug(scriptengine) << "asset list as string is: " << json; + return json; + } else { + qCDebug(scriptengine) << "Invalid filters were specified."; + //return QJsonArray(); + return ""; + } +} + +/*QJsonArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { + QUrl url = formatURLQuery(keyword, category, format); + if (!url.isEmpty()) { + //QJsonArray json = parseJSON(url, 0).toJsonArray(); + //qCDebug(scriptengine) << "first asset name: " << json.at(0).toObject().value("displayName"); QJsonArray json = parseJSON(url, 0).toJsonArray(); - qCDebug(scriptengine) << "first asset name: " << json.at(0).toObject().value("displayName"); + qCDebug(scriptengine) << "asset list as array is: " << json; return json; } else { qCDebug(scriptengine) << "Invalid filters were specified."; return QJsonArray(); + //return ""; } -} +}*/ QString GooglePolyScriptingInterface::getFBX(QString keyword, QString category) { QUrl url = formatURLQuery(keyword, category, "FBX"); @@ -60,7 +82,16 @@ QString GooglePolyScriptingInterface::getOBJ(QString keyword, QString category) QString GooglePolyScriptingInterface::getBlocks(QString keyword, QString category) { QUrl url = formatURLQuery(keyword, category, "BLOCKS"); - qCDebug(scriptengine) << "Google url request: " << url; + return getModelURL(url); +} + +QString GooglePolyScriptingInterface::getGLTF(QString keyword, QString category) { + QUrl url = formatURLQuery(keyword, category, "GLTF"); + return getModelURL(url); +} + +QString GooglePolyScriptingInterface::getGLTF2(QString keyword, QString category) { + QUrl url = formatURLQuery(keyword, category, "GLTF2"); return getModelURL(url); } @@ -74,15 +105,15 @@ QString GooglePolyScriptingInterface::getTilt(QString keyword, QString category) // can provide asset name or full URL to model QString GooglePolyScriptingInterface::getModelInfo(QString name) { - if (name.contains("poly.googleapis")) { + if (name.contains("poly.googleapis") || name.contains("poly.google.com")) { QStringList list = name.split("/"); name = list[4]; } QString urlString = QString(getPolyUrl); urlString = urlString.replace("model", name) + "key=" + authCode; - qCDebug(scriptengine) << "google get url: " << urlString; + qCDebug(scriptengine) << "Google URL request: " << urlString; QUrl url(urlString); - QByteArray json = parseJSON(url, 2).toByteArray(); + QString json = parseJSON(url, 2).toString(); return json; } @@ -90,10 +121,6 @@ void GooglePolyScriptingInterface::testPrint(QString input) { qCDebug(scriptengine) << "Google message: " << input; } -void GooglePolyScriptingInterface::setAPIKey(QString key) { - authCode = key; -} - int GooglePolyScriptingInterface::getRandIntInRange(int length) { QTime time = QTime::currentTime(); qsrand((uint)time.msec()); @@ -121,7 +148,7 @@ QUrl GooglePolyScriptingInterface::formatURLQuery(QString keyword, QString categ } QString GooglePolyScriptingInterface::getModelURL(QUrl url) { - qCDebug(scriptengine) << "Google url request: " << url; + qCDebug(scriptengine) << "Google URL request: " << url; if (!url.isEmpty()) { return parseJSON(url, 1).toString(); } else { @@ -150,9 +177,8 @@ QVariant GooglePolyScriptingInterface::parseJSON(QUrl url, int fileType) { if (obj.keys().first() == "error") { QString error = obj.value("error").toObject().value("message").toString(); qCDebug(scriptengine) << error; - return QJsonObject(); + return ""; } - qCDebug(scriptengine) << "the assets: " << obj.value("assets"); if (fileType == 0 || fileType == 1) { QJsonArray arr = obj.value("assets").toArray(); // return model url @@ -163,11 +189,10 @@ QVariant GooglePolyScriptingInterface::parseJSON(QUrl url, int fileType) { return json.value("formats").toArray().at(0).toObject().value("root").toObject().value("url"); } // return whole asset list - return arr; + //return arr; + return QJsonDocument(arr); // return specific object } else { - //return obj; - //return doc.toJson(); return jsonString; } } @@ -269,5 +294,4 @@ or this :(( http://blog.mathieu-leplatre.info/access-a-json-webservice-with-qt-c qCDebug(scriptengine) << "first item: " << firstItem; } -<<<<<<< HEAD */ diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index acbc27b90c..f8b00462f3 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -25,10 +25,13 @@ public slots: void testPrint(QString input); void setAPIKey(QString key); - QJsonArray getAssetList(QString keyword, QString category, QString format); + //QJsonArray getAssetList(QString keyword, QString category, QString format); + QByteArray getAssetList(QString keyword, QString category, QString format); QString getFBX(QString keyword, QString category); QString getOBJ(QString keyword, QString category); QString getBlocks(QString keyword, QString category); + QString getGLTF(QString keyword, QString category); + QString getGLTF2(QString keyword, QString category); //QString getTilt(QString keyword, QString category); QString getModelInfo(QString name); From 34d8fe307df1c736f0d5ea77649b6b63990458a5 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Tue, 19 Dec 2017 11:25:15 -0800 Subject: [PATCH 16/26] fixed getAssetList() --- .../GooglePolyScriptingInterface.cpp | 20 ++----------------- .../scripting/GooglePolyScriptingInterface.h | 3 +-- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index 42c3b825ba..6387295315 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -40,14 +40,13 @@ void GooglePolyScriptingInterface::setAPIKey(QString key) { authCode = key; } -QByteArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { +QString GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { QUrl url = formatURLQuery(keyword, category, format); if (!url.isEmpty()) { //QJsonArray json = parseJSON(url, 0).toJsonArray(); //qCDebug(scriptengine) << "first asset name: " << json.at(0).toObject().value("displayName"); QByteArray json = parseJSON(url, 0).toJsonDocument().toJson(); - qCDebug(scriptengine) << "asset list as string is: " << json; - return json; + return (QString) json; } else { qCDebug(scriptengine) << "Invalid filters were specified."; //return QJsonArray(); @@ -55,21 +54,6 @@ QByteArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString c } } -/*QJsonArray GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { - QUrl url = formatURLQuery(keyword, category, format); - if (!url.isEmpty()) { - //QJsonArray json = parseJSON(url, 0).toJsonArray(); - //qCDebug(scriptengine) << "first asset name: " << json.at(0).toObject().value("displayName"); - QJsonArray json = parseJSON(url, 0).toJsonArray(); - qCDebug(scriptengine) << "asset list as array is: " << json; - return json; - } else { - qCDebug(scriptengine) << "Invalid filters were specified."; - return QJsonArray(); - //return ""; - } -}*/ - QString GooglePolyScriptingInterface::getFBX(QString keyword, QString category) { QUrl url = formatURLQuery(keyword, category, "FBX"); return getModelURL(url); diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index f8b00462f3..7c6d810d13 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -25,8 +25,7 @@ public slots: void testPrint(QString input); void setAPIKey(QString key); - //QJsonArray getAssetList(QString keyword, QString category, QString format); - QByteArray getAssetList(QString keyword, QString category, QString format); + QString getAssetList(QString keyword, QString category, QString format); QString getFBX(QString keyword, QString category); QString getOBJ(QString keyword, QString category); QString getBlocks(QString keyword, QString category); From 1b6c85edb01812db3d349e6911bd167b00a362a7 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Tue, 19 Dec 2017 13:22:31 -0800 Subject: [PATCH 17/26] cleaned up code --- .../GooglePolyScriptingInterface.cpp | 111 +----------------- .../scripting/GooglePolyScriptingInterface.h | 2 - 2 files changed, 2 insertions(+), 111 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index 6387295315..6f4735f4b1 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -43,13 +43,10 @@ void GooglePolyScriptingInterface::setAPIKey(QString key) { QString GooglePolyScriptingInterface::getAssetList(QString keyword, QString category, QString format) { QUrl url = formatURLQuery(keyword, category, format); if (!url.isEmpty()) { - //QJsonArray json = parseJSON(url, 0).toJsonArray(); - //qCDebug(scriptengine) << "first asset name: " << json.at(0).toObject().value("displayName"); QByteArray json = parseJSON(url, 0).toJsonDocument().toJson(); return (QString) json; } else { qCDebug(scriptengine) << "Invalid filters were specified."; - //return QJsonArray(); return ""; } } @@ -87,7 +84,7 @@ QString GooglePolyScriptingInterface::getTilt(QString keyword, QString category) } */ -// can provide asset name or full URL to model +// Can provide asset name or full URL to model QString GooglePolyScriptingInterface::getModelInfo(QString name) { if (name.contains("poly.googleapis") || name.contains("poly.google.com")) { QStringList list = name.split("/"); @@ -101,10 +98,6 @@ QString GooglePolyScriptingInterface::getModelInfo(QString name) { return json; } -void GooglePolyScriptingInterface::testPrint(QString input) { - qCDebug(scriptengine) << "Google message: " << input; -} - int GooglePolyScriptingInterface::getRandIntInRange(int length) { QTime time = QTime::currentTime(); qsrand((uint)time.msec()); @@ -152,7 +145,7 @@ QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { return response->readAll(); } -// since the list is a QJsonArray and a single model is a QJsonObject +// 0 = asset list, 1 = model from asset list, 2 = specific model QVariant GooglePolyScriptingInterface::parseJSON(QUrl url, int fileType) { //QString firstItem = QString::fromUtf8(response->readAll()); QByteArray jsonString = getHTTPRequest(url); @@ -173,109 +166,9 @@ QVariant GooglePolyScriptingInterface::parseJSON(QUrl url, int fileType) { return json.value("formats").toArray().at(0).toObject().value("root").toObject().value("url"); } // return whole asset list - //return arr; return QJsonDocument(arr); // return specific object } else { return jsonString; } } - - -/* - -// FIXME: synchronous = not good code -QByteArray GooglePolyScriptingInterface::getHTTPRequest(QUrl url) { - QNetworkAccessManager manager; - QNetworkReply *response = manager.get(QNetworkRequest(url)); - QEventLoop event; - connect(response, SIGNAL(finished()), &event, SLOT(quit())); - event.exec(); - return response->readAll(); -} - - - -/* NONE OF THESE HTTP GET METHODS WORK D: -https://stackoverflow.com/questions/28267477/getting-a-page-content-with-qt kinda used rn - -this correctly returns the asset list but is apparently synchronous and not a good way to do it -https://stackoverflow.com/questions/24965972/qt-getting-source-html-code-of-a-web-page-hosted-on-the-internet -void GooglePolyScriptingInterface::getAssetList() { - authCode = "AIzaSyDamk7Vth52j7aU9JVKn3ungFS0kGJYc8A"; - QUrl url(listPolyUrl + "key=" + authCode); - QNetworkAccessManager manager; - QNetworkReply *response = manager.get(QNetworkRequest(url)); - QEventLoop event; - connect(response, SIGNAL(finished()), &event, SLOT(quit())); - event.exec(); - QString firstItem = response->readAll(); - //QJsonArray arr; - //QJsonObject jsonObject = QJsonDocument::fromJson(response->readAll()).object(); - //QString firstItem = jsonObject["assets"].toString(); - qCDebug(scriptengine) << "first item: " << firstItem; - //qCDebug(scriptengine) << "api key: " << authCode; - //return arr; -} - -this didn't work either https://stackoverflow.com/a/24966317 - QScopedPointer manager(new QNetworkAccessManager); - QNetworkReply* response = manager->get(QNetworkRequest(url)); - QObject::connect(manager, &QNetworkAccessManager::finished, [manager, response] { - response->deleteLater(); - manager->deleteLater(); - if (response->error() != QNetworkReply::NoError) return; - QString contentType = - response->header(QNetworkRequest::ContentTypeHeader).toString(); - if (!contentType.contains("charset=utf-8")) { - qWarning() << "Content charsets other than utf-8 are not implemented yet."; - return; - } - QString html = QString::fromUtf8(response->readAll()); - // do something with the data - }) && manager.take(); - - -or this :( https://stackoverflow.com/questions/39518749/make-get-request-to-web-service-get-json-response-and-update-gui-in-qt - qCDebug(scriptengine) << "gonna get assets with " << url; - QNetworkAccessManager manager; - QNetworkReply* reply = manager.get(QNetworkRequest(url)); - QObject::connect(&manager, &QNetworkAccessManager::finished, - [reply]{ - qCDebug(scriptengine) << "boo radley"; - if (reply->error() != QNetworkReply::NoError) { - qCDebug(scriptengine) << "Poly API failed to respond"; - //manager.clearAccessCache(); - } else { - QJsonObject jsonObject = QJsonDocument::fromJson(reply->readAll()).object(); - QString firstItem = jsonObject["assets"].toString(); - qCDebug(scriptengine) << "first item: " << firstItem; - } - reply->deleteLater(); - }); - -or this :(( http://blog.mathieu-leplatre.info/access-a-json-webservice-with-qt-c.html - //QJsonArray arr; - //QJsonObject jsonObject = QJsonDocument::fromJson(response->readAll()).object(); - //QString firstItem = jsonObject["assets"].toString(); - qCDebug(scriptengine) << "first item: " << firstItem; - //qCDebug(scriptengine) << "api key: " << authCode; - //return arr; - QNetworkAccessManager manager; - QNetworkReply* response = manager.get(QNetworkRequest(url)); - QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onResult(QNetworkReply*))); - - return ""; - } - - void GooglePolyScriptingInterface::onResult(QNetworkReply* reply) { - if (reply->error() != QNetworkReply::NoError) { - qCDebug(scriptengine) << "Poly API failed to respond"; - return; - } - QString firstItem = reply->readAll(); - - qCDebug(scriptengine) << "first item: " << firstItem; - } - -*/ diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index 7c6d810d13..cdfeddd5fe 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -22,7 +22,6 @@ public: GooglePolyScriptingInterface(); public slots: - void testPrint(QString input); void setAPIKey(QString key); QString getAssetList(QString keyword, QString category, QString format); @@ -40,7 +39,6 @@ private: QByteArray getHTTPRequest(QUrl url); QVariant parseJSON(QUrl url, int fileType); int getRandIntInRange(int length); - //void onResult(QNetworkReply* reply); QString authCode; From 14935e5924c38f71a3185be79bd2ddb9ff793980 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Tue, 19 Dec 2017 15:11:24 -0800 Subject: [PATCH 18/26] added const to valid inputs --- interface/src/scripting/GooglePolyScriptingInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index 6f4735f4b1..c9699a2a68 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -28,8 +28,8 @@ const QString listPolyUrl = "https://poly.googleapis.com/v1/assets?"; const QString getPolyUrl = "https://poly.googleapis.com/v1/assets/model?"; -QStringList validFormats = QStringList() << "BLOCKS" << "FBX" << "GLTF" << "GLTF2" << "OBJ" << "TILT" << ""; -QStringList validCategories = QStringList() << "animals" << "architecture" << "art" << "food" << +const QStringList validFormats = QStringList() << "BLOCKS" << "FBX" << "GLTF" << "GLTF2" << "OBJ" << "TILT" << ""; +const QStringList validCategories = QStringList() << "animals" << "architecture" << "art" << "food" << "nature" << "objects" << "people" << "scenes" << "technology" << "transport" << ""; GooglePolyScriptingInterface::GooglePolyScriptingInterface() { From ca062f923278dbccff1e7cd68e153bdf8cc1d8fe Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Tue, 19 Dec 2017 15:41:42 -0800 Subject: [PATCH 19/26] changed qtglobal include --- interface/src/scripting/GooglePolyScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index c9699a2a68..d3b24f79f0 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -10,7 +10,7 @@ // #include -#include +#include #include #include #include From 7de2918b9b9da99fbf03c793ca4e22c32146b400 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Wed, 20 Dec 2017 12:44:47 -0800 Subject: [PATCH 20/26] added newline to header --- interface/src/scripting/GooglePolyScriptingInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index cdfeddd5fe..758926aed5 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -44,4 +44,4 @@ private: }; -#endif // hifi_GooglePolyScriptingInterface_h \ No newline at end of file +#endif // hifi_GooglePolyScriptingInterface_h From 533aa3d91896c4f4d16e65d90c2b9d9f125b94b8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 22 Dec 2017 09:07:16 -0800 Subject: [PATCH 21/26] code review --- libraries/entities/src/EntityItem.cpp | 8 ++------ libraries/entities/src/ShapeEntityItem.cpp | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index fcf7519bbd..d0dca2d43e 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1674,16 +1674,12 @@ void EntityItem::setParentID(const QUuid& value) { glm::vec3 EntityItem::getScaledDimensions() const { glm::vec3 scale = getSNScale(); - return glm::vec3(_unscaledDimensions.x * scale.x, - _unscaledDimensions.y * scale.y, - _unscaledDimensions.z * scale.z); + return _unscaledDimensions * scale; } void EntityItem::setScaledDimensions(const glm::vec3& value) { glm::vec3 parentScale = getSNScale(); - setUnscaledDimensions(glm::vec3(value.x / parentScale.x, - value.y / parentScale.y, - value.z / parentScale.z)); + setUnscaledDimensions(value * parentScale); } void EntityItem::setUnscaledDimensions(const glm::vec3& value) { diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index f564c89d21..3750bc3b57 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -206,12 +206,12 @@ void ShapeEntityItem::setColor(const QColor& value) { void ShapeEntityItem::setUnscaledDimensions(const glm::vec3& value) { const float MAX_FLAT_DIMENSION = 0.0001f; - if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) { + if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) { // enforce flatness in Y glm::vec3 newDimensions = value; newDimensions.y = MAX_FLAT_DIMENSION; EntityItem::setUnscaledDimensions(newDimensions); - } else { + } else { EntityItem::setUnscaledDimensions(value); } } From e1b344e36de8aefa0433c5491dfcabb2bb373554 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Tue, 26 Dec 2017 10:50:10 -0800 Subject: [PATCH 22/26] handles empty json object return --- interface/src/scripting/GooglePolyScriptingInterface.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index d3b24f79f0..9629ae9b2e 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -151,6 +151,10 @@ QVariant GooglePolyScriptingInterface::parseJSON(QUrl url, int fileType) { QByteArray jsonString = getHTTPRequest(url); QJsonDocument doc = QJsonDocument::fromJson(jsonString); QJsonObject obj = doc.object(); + if (obj.isEmpty()) { + qCDebug(scriptengine) << "Assets with specified filters not found"; + return ""; + } if (obj.keys().first() == "error") { QString error = obj.value("error").toObject().value("message").toString(); qCDebug(scriptengine) << error; From 03f06aadf4a4282bf87372d698c8e30e1fd729d9 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Tue, 26 Dec 2017 11:08:10 -0800 Subject: [PATCH 23/26] keyword filters case insensitive now --- interface/src/scripting/GooglePolyScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index 9629ae9b2e..f164d6e825 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -106,7 +106,7 @@ int GooglePolyScriptingInterface::getRandIntInRange(int length) { QUrl GooglePolyScriptingInterface::formatURLQuery(QString keyword, QString category, QString format) { QString queries; - if (!validFormats.contains(format) || !validCategories.contains(category)) { + if (!validFormats.contains(format, Qt::CaseInsensitive) || !validCategories.contains(category, Qt::CaseInsensitive)) { return QUrl(""); } else { if (!keyword.isEmpty()) { From 01c1032540b9ff26b575e1b96ca983f0bcb200a5 Mon Sep 17 00:00:00 2001 From: Elisa Lupin-Jimenez Date: Wed, 27 Dec 2017 10:51:58 -0800 Subject: [PATCH 24/26] fixed constant names, added another URL check --- interface/resources/qml/js/Utils.jsc | Bin 6596 -> 0 bytes .../GooglePolyScriptingInterface.cpp | 27 +++++++++--------- .../scripting/GooglePolyScriptingInterface.h | 6 ++-- 3 files changed, 17 insertions(+), 16 deletions(-) delete mode 100644 interface/resources/qml/js/Utils.jsc diff --git a/interface/resources/qml/js/Utils.jsc b/interface/resources/qml/js/Utils.jsc deleted file mode 100644 index ab20e996b9469915ac6a89901da175143e6b5024..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6596 zcmcIoZD?EP6@Kh1ckah_<+cmm)~+s7*+{cEDOm|)Y*uPBiCux$Iwl#JYtNP&7t3}W zIXI&o4oU8EkM2n zXjl7O2dDtRuNCd{@)jY-)d!#zenqKY4sn&W{weu)twmlb!$4JTzv65rm+K1vDC#!F zU$|ZVIZ9zlW+S<`HL;hgR&M8~1sQiLyXg~6*Kx4qHtya=?){4Iz`gR%B^6)FqD(EX zPx0NgjXdr9YAbNP75KOnxYqy<89DFo`<=jA05hh+!CUJc)7q5K-I-U<4BwMhw#!Kold03qHB1qPh=(m57jV zQZO*TlsKpO<^4D&)ji|-UBpF<$-`KmCFTK~acFxKqv8qb`vJ}(jwnv6ynF{ogq(=F zep_Ap)wNGud)4)O>UtbUguEF{VOB&&#)x21=BI^yoeI;=cpet< z8yEavN0<0LF8)1^DU2eDE}X7EzTC=9#(VVvU%?VLXPX@E8u^tC$cdhzrY~ z5|TzSE|9{#2}}z<=It55SzSj%iNA*yHv6nZbjwP_N>*aF82-K7|F|4Z{3((gYY*l1 z1HmPNES&HK!VAmo!G#Z7%nSc2m&=jFSbJz;vopy0hR~Acw-O%(%P$^o0YVGQoxRBc zfA58N%nJ{-l0bHGCbwg^#q(qrrDi+!w<_$cdfT#JQtVa6B|0HZKTvD>SPT8{3FK*i zWU(iZU!oSteUbW{j!MrrowDh%hwMA*Wz%5~+1G_Km+UHco!!3?d2`uawWQAO`Fhz^ zFY9DKQ7^k1!8+Li%B~H>BZmbX7dAVWSkh#gI3&0r zaF0rAW;@0YRTR^~w|fH1=rq7T1!gIn>dAFt!Sy*C45#|hZ zyKMQfPE=zR8BZ12Iu&e;jZ`qZ;(XBNe0X7VdI#CX&hyK$=>L{qIw{h|R_2l4RI7AY z^-G-Fg*Pl@c)U6&I`)6~vWKqD3?b!JxCu1uN`cA?Q-i-75ra?*w4> z7DLeZEXfck*xy13exhOT)~XM$^JKYWuGBjYFUK{J-kQV9*AmCcI=9Ipz3t&zt&~o& zbp5o=j@d0M5iMDXSkX$%t~YJ^dxYvnP2X7@RT0fd+JSJgHI(cgqRD9&=_E-h7ipTL zi!Ra}N%Kz9JRJ@v&Ijf=afs?ImCUopaAUf5Bc(P@)^4QL#!&4B4=hC;lN+q^_W+Q1 zP^n|i{5|@(6kNweRp@!g!IB0$&XzP(9WOq8UKl6|MM0Czbbp-MJtdAmS4|C?43SDf)z9}dNlLtGo5xl*UM-i)V9TyEvOFWw5I(m_-&8|fx011{`>NNH;(6Df(rr#QsN>-}$CJna|wOpzoRcq-Fq`bAH8fghvwNyJ`N_RlpJYiGQZuHu}HZ5Pa zdE8c|q5`8P==g;$uId?L_>-ZdTT7Ja(9^jWIyw}4%`oqUj`vkn%QKo+>hkt%Am^R8 zT%)}GyrqJUtqMAFDsNlV@ Date: Wed, 27 Dec 2017 12:49:16 -0800 Subject: [PATCH 26/26] changed api key variable name --- interface/src/scripting/GooglePolyScriptingInterface.cpp | 6 +++--- interface/src/scripting/GooglePolyScriptingInterface.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/scripting/GooglePolyScriptingInterface.cpp b/interface/src/scripting/GooglePolyScriptingInterface.cpp index f164724d37..8ed5d59d07 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.cpp +++ b/interface/src/scripting/GooglePolyScriptingInterface.cpp @@ -37,7 +37,7 @@ GooglePolyScriptingInterface::GooglePolyScriptingInterface() { } void GooglePolyScriptingInterface::setAPIKey(const QString& key) { - authCode = key; + _authCode = key; } QString GooglePolyScriptingInterface::getAssetList(const QString& keyword, const QString& category, const QString& format) { @@ -94,7 +94,7 @@ QString GooglePolyScriptingInterface::getModelInfo(const QString& input) { } } QString urlString(GET_POLY_URL); - urlString = urlString.replace("model", name) + "key=" + authCode; + urlString = urlString.replace("model", name) + "key=" + _authCode; qCDebug(scriptengine) << "Google URL request: " << urlString; QUrl url(urlString); QString json = parseJSON(url, 2).toString(); @@ -123,7 +123,7 @@ QUrl GooglePolyScriptingInterface::formatURLQuery(const QString& keyword, const if (!format.isEmpty()) { queries.append("&format=" + format); } - QString urlString(LIST_POLY_URL + "key=" + authCode + queries); + QString urlString(LIST_POLY_URL + "key=" + _authCode + queries); return QUrl(urlString); } } diff --git a/interface/src/scripting/GooglePolyScriptingInterface.h b/interface/src/scripting/GooglePolyScriptingInterface.h index 04a60f0614..fdd3597bec 100644 --- a/interface/src/scripting/GooglePolyScriptingInterface.h +++ b/interface/src/scripting/GooglePolyScriptingInterface.h @@ -34,7 +34,7 @@ public slots: QString getModelInfo(const QString& input); private: - QString authCode; + QString _authCode; QUrl formatURLQuery(const QString& keyword, const QString& category, const QString& format); QString getModelURL(const QUrl& url);