From 42da429414b23c16b4b6307dd08213fb0692cc5d Mon Sep 17 00:00:00 2001 From: Ryan Huffman <ryanhuffman@gmail.com> Date: Thu, 27 Apr 2017 12:01:37 -0700 Subject: [PATCH 1/8] Fix NetworkTexture self possibly being null when attempting request --- .../model-networking/src/model-networking/TextureCache.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 55704236e3..c2d947baab 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -394,12 +394,17 @@ void NetworkTexture::startRequestForNextMipLevel() { } if (_ktxResourceState == WAITING_FOR_MIP_REQUEST) { + auto self = _self.lock(); + if (!self) { + return; + } + _ktxResourceState = PENDING_MIP_REQUEST; init(); setLoadPriority(this, -static_cast<int>(_originalKtxDescriptor->header.numberOfMipmapLevels) + _lowestKnownPopulatedMip); _url.setFragment(QString::number(_lowestKnownPopulatedMip - 1)); - TextureCache::attemptRequest(_self); + TextureCache::attemptRequest(self); } } From 149f87e734e454d09c3754e4a35058d8c18e9b2d Mon Sep 17 00:00:00 2001 From: Ryan Huffman <ryanhuffman@gmail.com> Date: Thu, 27 Apr 2017 12:01:55 -0700 Subject: [PATCH 2/8] Fix style in NetworkTexture --- .../src/model-networking/TextureCache.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index c2d947baab..680550d9a1 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -473,19 +473,16 @@ void NetworkTexture::ktxMipRequestFinished() { texture->assignStoredMip(_ktxMipLevelRangeInFlight.first, _ktxMipRequest->getData().size(), reinterpret_cast<uint8_t*>(_ktxMipRequest->getData().data())); _lowestKnownPopulatedMip = _textureSource->getGPUTexture()->minAvailableMipLevel(); - } - else { + } else { qWarning(networking) << "Trying to update mips but texture is null"; } finishedLoading(true); _ktxResourceState = WAITING_FOR_MIP_REQUEST; - } - else { + } else { finishedLoading(false); if (handleFailedRequest(_ktxMipRequest->getResult())) { _ktxResourceState = PENDING_MIP_REQUEST; - } - else { + } else { qWarning(networking) << "Failed to load mip: " << _url; _ktxResourceState = FAILED_TO_LOAD; } @@ -497,8 +494,7 @@ void NetworkTexture::ktxMipRequestFinished() { if (_ktxResourceState == WAITING_FOR_MIP_REQUEST && _lowestRequestedMipLevel < _lowestKnownPopulatedMip) { startRequestForNextMipLevel(); } - } - else { + } else { qWarning() << "Mip request finished in an unexpected state: " << _ktxResourceState; } } From d8e4604b18ccdcf3d8c714ff1a265fc49321d1a0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman <ryanhuffman@gmail.com> Date: Thu, 27 Apr 2017 13:03:04 -0700 Subject: [PATCH 3/8] Fix gpu access of ktx file not being thread-safe --- libraries/gpu/src/gpu/Texture.h | 8 ++++---- libraries/gpu/src/gpu/Texture_ktx.cpp | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 9b23b4e695..3b8ae508eb 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -324,11 +324,11 @@ public: void reset() override { } protected: - std::shared_ptr<storage::FileStorage> maybeOpenFile(); + std::shared_ptr<storage::FileStorage> maybeOpenFile() const; - std::mutex _cacheFileCreateMutex; - std::mutex _cacheFileWriteMutex; - std::weak_ptr<storage::FileStorage> _cacheFile; + mutable std::mutex _cacheFileCreateMutex; + mutable std::mutex _cacheFileWriteMutex; + mutable std::weak_ptr<storage::FileStorage> _cacheFile; std::string _filename; std::atomic<uint8_t> _minMipLevelAvailable; diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index efff6c7afe..d2f93c0036 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -128,7 +128,7 @@ KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) { } } -std::shared_ptr<storage::FileStorage> KtxStorage::maybeOpenFile() { +std::shared_ptr<storage::FileStorage> KtxStorage::maybeOpenFile() const { std::shared_ptr<storage::FileStorage> file = _cacheFile.lock(); if (file) { return file; @@ -154,7 +154,8 @@ PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const { auto faceOffset = _ktxDescriptor->getMipFaceTexelsOffset(level, face); auto faceSize = _ktxDescriptor->getMipFaceTexelsSize(level, face); if (faceSize != 0 && faceOffset != 0) { - result = std::make_shared<storage::FileStorage>(_filename.c_str())->createView(faceSize, faceOffset)->toMemoryStorage(); + auto file = maybeOpenFile(); + result = file->createView(faceSize, faceOffset)->toMemoryStorage(); } return result; } From 4b0bd80c270254ead7f22ffe09934a9f99bfff6d Mon Sep 17 00:00:00 2001 From: Ryan Huffman <ryanhuffman@gmail.com> Date: Thu, 27 Apr 2017 13:03:42 -0700 Subject: [PATCH 4/8] Fix NetworkTexture not cleaning itself up on destruction --- .../src/model-networking/TextureCache.cpp | 16 ++++++++++++++++ .../src/model-networking/TextureCache.h | 1 + libraries/networking/src/ResourceCache.h | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 680550d9a1..7aee95c758 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -330,6 +330,22 @@ private: int _maxNumPixels; }; +NetworkTexture::~NetworkTexture() { + if (_ktxHeaderRequest || _ktxMipRequest) { + if (_ktxHeaderRequest) { + _ktxHeaderRequest->disconnect(this); + _ktxHeaderRequest->deleteLater(); + _ktxHeaderRequest = nullptr; + } + if (_ktxMipRequest) { + _ktxMipRequest->disconnect(this); + _ktxMipRequest->deleteLater(); + _ktxMipRequest = nullptr; + } + ResourceCache::requestCompleted(_self); + } +} + const uint16_t NetworkTexture::NULL_MIP_LEVEL = std::numeric_limits<uint16_t>::max(); void NetworkTexture::makeRequest() { if (!_sourceIsKTX) { diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 1e61b9ecee..c7a7799216 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -46,6 +46,7 @@ class NetworkTexture : public Resource, public Texture { public: NetworkTexture(const QUrl& url, image::TextureUsage::Type type, const QByteArray& content, int maxNumPixels); + ~NetworkTexture() override; QString getType() const override { return "NetworkTexture"; } diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index d4c7d63ee5..51c8d8554a 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -344,7 +344,7 @@ class Resource : public QObject { public: Resource(const QUrl& url); - ~Resource(); + virtual ~Resource(); virtual QString getType() const { return "Resource"; } From 2faa8fb671508dcf85841ba82a3fd6b0bfd1fe99 Mon Sep 17 00:00:00 2001 From: Ryan Huffman <ryanhuffman@gmail.com> Date: Thu, 27 Apr 2017 14:01:55 -0700 Subject: [PATCH 5/8] Fix ResourceCache warning on OSX --- .../model-networking/src/model-networking/TextureCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 7aee95c758..12ec6eca24 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -342,7 +342,7 @@ NetworkTexture::~NetworkTexture() { _ktxMipRequest->deleteLater(); _ktxMipRequest = nullptr; } - ResourceCache::requestCompleted(_self); + TextureCache::requestCompleted(_self); } } From eed4da3570833de3667d7f41931d505921f1cf98 Mon Sep 17 00:00:00 2001 From: Seth Alves <seth.alves@gmail.com> Date: Tue, 2 May 2017 15:36:38 -0700 Subject: [PATCH 6/8] some cleanups, delete far-grabs during transition to near-grab rather than set ttl to zero --- .../system/controllers/handControllerGrab.js | 95 +++++++------------ 1 file changed, 36 insertions(+), 59 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index ec70b0b1c8..33fd2b8fd9 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -14,7 +14,7 @@ /* global getEntityCustomData, flatten, Xform, Script, Quat, Vec3, MyAvatar, Entities, Overlays, Settings, Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset, - setGrabCommunications, Menu, HMD, isInEditMode */ + setGrabCommunications, Menu, HMD, isInEditMode, AvatarManager */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ (function() { // BEGIN LOCAL_SCOPE @@ -75,7 +75,6 @@ var WEB_TOUCH_Y_OFFSET = 0.05; // how far forward (or back with a negative numbe // // distant manipulation // -var linearTimeScale = 0; var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_UNITY_MASS = 1200; // The mass at which the distance holding action timeframe is unmodified @@ -155,7 +154,6 @@ var INCHES_TO_METERS = 1.0 / 39.3701; // these control how long an abandoned pointer line or action will hang around var ACTION_TTL = 15; // seconds -var ACTION_TTL_ZERO = 0; // seconds var ACTION_TTL_REFRESH = 5; var PICKS_PER_SECOND_PER_HAND = 60; var MSECS_PER_SEC = 1000.0; @@ -193,7 +191,6 @@ var FORBIDDEN_GRAB_TYPES = ["Unknown", "Light", "PolyLine", "Zone"]; var holdEnabled = true; var nearGrabEnabled = true; var farGrabEnabled = true; -var farToNearGrab = false; var myAvatarScalingEnabled = true; var objectScalingEnabled = true; var mostRecentSearchingHand = RIGHT_HAND; @@ -300,14 +297,13 @@ function getFingerWorldLocation(hand) { // Object assign polyfill if (typeof Object.assign != 'function') { Object.assign = function(target, varArgs) { - 'use strict'; - if (target == null) { + if (target === null) { throw new TypeError('Cannot convert undefined or null to object'); } var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index]; - if (nextSource != null) { + if (nextSource !== null) { for (var nextKey in nextSource) { if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; @@ -801,7 +797,7 @@ function calculateNearestStylusTarget(stylusTargets) { } return nearestStylusTarget; -}; +} // EntityPropertiesCache is a helper class that contains a cache of entity properties. // the hope is to prevent excess calls to Entity.getEntityProperties() @@ -1229,8 +1225,9 @@ function MyController(hand) { newState !== STATE_OVERLAY_LASER_TOUCHING)) { return; } - setGrabCommunications((newState === STATE_DISTANCE_HOLDING) || (newState === STATE_DISTANCE_ROTATING) - || (newState === STATE_NEAR_GRABBING)); + setGrabCommunications((newState === STATE_DISTANCE_HOLDING) || + (newState === STATE_DISTANCE_ROTATING) || + (newState === STATE_NEAR_GRABBING)); if (WANT_DEBUG || WANT_DEBUG_STATE) { var oldStateName = stateToName(this.state); var newStateName = stateToName(newState); @@ -1428,7 +1425,7 @@ function MyController(hand) { if (PICK_WITH_HAND_RAY) { this.overlayLineOff(); } - } + }; this.otherGrabbingLineOn = function(avatarPosition, entityPosition, color) { if (this.otherGrabbingLine === null) { @@ -1641,11 +1638,6 @@ function MyController(hand) { var tipPosition = this.stylusTip.position; - var candidates = { - entities: [], - overlays: [] - }; - // build list of stylus targets, near the stylusTip var stylusTargets = []; var candidateEntities = Entities.findEntities(tipPosition, WEB_DISPLAY_STYLUS_DISTANCE); @@ -1972,9 +1964,10 @@ function MyController(hand) { var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); var otherHandControllerState = this.getOtherHandController().state; - var okToEquipFromOtherHand = ((otherHandControllerState === STATE_NEAR_GRABBING - || otherHandControllerState === STATE_DISTANCE_HOLDING || otherHandControllerState === STATE_DISTANCE_ROTATING) - && this.getOtherHandController().grabbedThingID === hotspot.entityID); + var okToEquipFromOtherHand = ((otherHandControllerState === STATE_NEAR_GRABBING || + otherHandControllerState === STATE_DISTANCE_HOLDING || + otherHandControllerState === STATE_DISTANCE_ROTATING) && + this.getOtherHandController().grabbedThingID === hotspot.entityID); var hasParent = true; if (props.parentID === NULL_UUID) { hasParent = false; @@ -1999,7 +1992,7 @@ function MyController(hand) { return entityProps.cloneable; } return false; - } + }; this.entityIsGrabbable = function(entityID) { var grabbableProps = entityPropertiesCache.getGrabbableProps(entityID); var props = entityPropertiesCache.getProps(entityID); @@ -2346,7 +2339,7 @@ function MyController(hand) { this.otherGrabbingLineOff(); } else if (this.otherGrabbingUUID !== null) { if (this.triggerSmoothedGrab() && !isEditing() && farGrabEnabled && farSearching) { - var avatar = AvatarList.getAvatar(this.otherGrabbingUUID); + var avatar = AvatarManager.getAvatar(this.otherGrabbingUUID); var IN_FRONT_OF_AVATAR = { x: 0, y: 0.2, z: 0.4 }; // Up from hips and in front of avatar. var startPosition = Vec3.sum(avatar.position, Vec3.multiplyQbyV(avatar.rotation, IN_FRONT_OF_AVATAR)); var finishPisition = Vec3.sum(rayPickInfo.properties.position, // Entity's centroid. @@ -2720,7 +2713,8 @@ function MyController(hand) { var distanceToObject = Vec3.length(Vec3.subtract(MyAvatar.position, this.currentObjectPosition)); - var candidateHotSpotEntities = Entities.findEntities(controllerLocation.position,MAX_FAR_TO_NEAR_EQUIP_HOTSPOT_RADIUS); + var candidateHotSpotEntities = + Entities.findEntities(controllerLocation.position,MAX_FAR_TO_NEAR_EQUIP_HOTSPOT_RADIUS); entityPropertiesCache.addEntities(candidateHotSpotEntities); var potentialEquipHotspot = this.chooseBestEquipHotspotForFarToNearEquip(candidateHotSpotEntities); @@ -2730,40 +2724,23 @@ function MyController(hand) { this.grabbedThingID = potentialEquipHotspot.entityID; this.grabbedIsOverlay = false; - var success = Entities.updateAction(this.grabbedThingID, this.actionID, { - targetPosition: newTargetPosition, - linearTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject), - targetRotation: this.currentObjectRotation, - angularTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject), - ttl: ACTION_TTL_ZERO - }); - - if (success) { - this.actionTimeout = now + (ACTION_TTL_ZERO * MSECS_PER_SEC); - } else { - print("continueDistanceHolding -- updateAction failed"); - } + Entities.deleteAction(this.grabbedThingID, this.actionID); + this.actionID = null; + this.setState(STATE_HOLD, "equipping '" + entityPropertiesCache.getProps(this.grabbedThingID).name + "'"); return; } } var rayPositionOnEntity = Vec3.subtract(grabbedProperties.position, this.offsetPosition); //Far to Near Grab: If object is draw by user inside FAR_TO_NEAR_GRAB_MAX_DISTANCE, grab it - if (this.entityIsFarToNearGrabbable(rayPositionOnEntity, controllerLocation.position, FAR_TO_NEAR_GRAB_MAX_DISTANCE)) { + if (this.entityIsFarToNearGrabbable(rayPositionOnEntity, + controllerLocation.position, + FAR_TO_NEAR_GRAB_MAX_DISTANCE)) { this.farToNearGrab = true; - var success = Entities.updateAction(this.grabbedThingID, this.actionID, { - targetPosition: newTargetPosition, - linearTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject), - targetRotation: this.currentObjectRotation, - angularTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject), - ttl: ACTION_TTL_ZERO // Overriding ACTION_TTL,Assign ACTION_TTL_ZERO so that the object is dropped down immediately after the trigger is released. - }); - if (success) { - this.actionTimeout = now + (ACTION_TTL_ZERO * MSECS_PER_SEC); - } else { - print("continueDistanceHolding -- updateAction failed"); - } + Entities.deleteAction(this.grabbedThingID, this.actionID); + this.actionID = null; + this.setState(STATE_NEAR_GRABBING , "near grab entity '" + this.grabbedThingID + "'"); return; } @@ -2844,7 +2821,7 @@ function MyController(hand) { COLORS_GRAB_DISTANCE_HOLD, this.grabbedThingID); this.previousWorldControllerRotation = worldControllerRotation; - } + }; this.setupHoldAction = function() { this.actionID = Entities.addAction("hold", this.grabbedThingID, { @@ -3043,15 +3020,14 @@ function MyController(hand) { var worldEntities = Entities.findEntities(MyAvatar.position, 50); var count = 0; worldEntities.forEach(function(item) { - var item = Entities.getEntityProperties(item, ["name"]); - if (item.name.indexOf('-clone-' + grabbedProperties.id) !== -1) { + var itemWE = Entities.getEntityProperties(itemWE, ["name"]); + if (itemWE.name.indexOf('-clone-' + grabbedProperties.id) !== -1) { count++; } - }) + }); var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 0; if (count >= limit && limit !== 0) { - delete limit; return; } @@ -3067,7 +3043,7 @@ function MyController(hand) { delete cUserData.grabbableKey.cloneable; delete cUserData.grabbableKey.cloneDynamic; delete cUserData.grabbableKey.cloneLimit; - delete cProperties.id + delete cProperties.id; cProperties.dynamic = dynamic; cProperties.locked = false; @@ -3133,7 +3109,7 @@ function MyController(hand) { _this.currentAngularVelocity = ZERO_VEC; _this.prevDropDetected = false; - } + }; if (isClone) { // 100 ms seems to be sufficient time to force the check even occur after the object has been initialized. @@ -3149,7 +3125,6 @@ function MyController(hand) { var ttl = ACTION_TTL; if (this.farToNearGrab) { - ttl = ACTION_TTL_ZERO; // farToNearGrab - Assign ACTION_TTL_ZERO so that, the object is dropped down immediately after the trigger is released. if(!this.triggerClicked){ this.farToNearGrab = false; } @@ -3322,7 +3297,7 @@ function MyController(hand) { this.maybeScale(props); } - if (this.actionID && this.actionTimeout - now < ttl * MSECS_PER_SEC) { + if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSECS_PER_SEC) { // if less than a 5 seconds left, refresh the actions ttl var success = Entities.updateAction(this.grabbedThingID, this.actionID, { hand: this.hand === RIGHT_HAND ? "right" : "left", @@ -3761,10 +3736,12 @@ function MyController(hand) { var TABLET_MAX_TOUCH_DISTANCE = 0.01; if (this.stylusTarget) { - if (this.stylusTarget.distance > TABLET_MIN_TOUCH_DISTANCE && this.stylusTarget.distance < TABLET_MAX_TOUCH_DISTANCE) { + if (this.stylusTarget.distance > TABLET_MIN_TOUCH_DISTANCE && + this.stylusTarget.distance < TABLET_MAX_TOUCH_DISTANCE) { var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY || - distance2D(this.stylusTarget.position2D, this.touchingEnterStylusTarget.position2D) > this.deadspotRadius) { + distance2D(this.stylusTarget.position2D, + this.touchingEnterStylusTarget.position2D) > this.deadspotRadius) { sendTouchMoveEventToStylusTarget(this.hand, this.stylusTarget); this.deadspotExpired = true; } From f1170dc17dbd7ead1a8c0353ed2268e93ad04340 Mon Sep 17 00:00:00 2001 From: Seth Alves <seth.alves@gmail.com> Date: Tue, 2 May 2017 15:48:12 -0700 Subject: [PATCH 7/8] AvatarList not AvatarManager --- scripts/system/controllers/handControllerGrab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 33fd2b8fd9..15aa52b5c0 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -14,7 +14,7 @@ /* global getEntityCustomData, flatten, Xform, Script, Quat, Vec3, MyAvatar, Entities, Overlays, Settings, Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset, - setGrabCommunications, Menu, HMD, isInEditMode, AvatarManager */ + setGrabCommunications, Menu, HMD, isInEditMode, AvatarList */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ (function() { // BEGIN LOCAL_SCOPE @@ -2339,7 +2339,7 @@ function MyController(hand) { this.otherGrabbingLineOff(); } else if (this.otherGrabbingUUID !== null) { if (this.triggerSmoothedGrab() && !isEditing() && farGrabEnabled && farSearching) { - var avatar = AvatarManager.getAvatar(this.otherGrabbingUUID); + var avatar = AvatarList.getAvatar(this.otherGrabbingUUID); var IN_FRONT_OF_AVATAR = { x: 0, y: 0.2, z: 0.4 }; // Up from hips and in front of avatar. var startPosition = Vec3.sum(avatar.position, Vec3.multiplyQbyV(avatar.rotation, IN_FRONT_OF_AVATAR)); var finishPisition = Vec3.sum(rayPickInfo.properties.position, // Entity's centroid. From 0cd0e46ca5a42835d6e9bb742cf917d7417c1bca Mon Sep 17 00:00:00 2001 From: Seth Alves <seth.alves@gmail.com> Date: Tue, 2 May 2017 16:20:59 -0700 Subject: [PATCH 8/8] make clone work again --- scripts/system/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 15aa52b5c0..db0840b078 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -3020,7 +3020,7 @@ function MyController(hand) { var worldEntities = Entities.findEntities(MyAvatar.position, 50); var count = 0; worldEntities.forEach(function(item) { - var itemWE = Entities.getEntityProperties(itemWE, ["name"]); + var itemWE = Entities.getEntityProperties(item, ["name"]); if (itemWE.name.indexOf('-clone-' + grabbedProperties.id) !== -1) { count++; }