diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index ce25df340d..342d7b37de 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -123,15 +123,36 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter qApp->getOverlays().editOverlay(renderState.getStartID(), startProps); } glm::vec3 endVec; - if (defaultState || !_lockEnd || type == IntersectionType::HUD) { + if (((defaultState || !_lockEnd) && _objectLockEnd.first.isNull()) || type == IntersectionType::HUD) { endVec = pickRay.origin + pickRay.direction * distance; } else { - if (type == IntersectionType::ENTITY) { - endVec = DependencyManager::get()->getEntityTransform(objectID)[3]; - } else if (type == IntersectionType::OVERLAY) { - endVec = vec3FromVariant(qApp->getOverlays().getProperty(objectID, "position").value); - } else if (type == IntersectionType::AVATAR) { - endVec = DependencyManager::get()->getAvatar(objectID)->getPosition(); + if (!_objectLockEnd.first.isNull()) { + glm::vec3 pos; + glm::quat rot; + glm::vec3 dim; + glm::vec3 registrationPoint; + if (_objectLockEnd.second) { + pos = vec3FromVariant(qApp->getOverlays().getProperty(_objectLockEnd.first, "position").value); + rot = quatFromVariant(qApp->getOverlays().getProperty(_objectLockEnd.first, "rotation").value); + dim = vec3FromVariant(qApp->getOverlays().getProperty(_objectLockEnd.first, "dimensions").value); + registrationPoint = glm::vec3(0.5f); + } else { + EntityItemProperties props = DependencyManager::get()->getEntityProperties(_objectLockEnd.first); + pos = props.getPosition(); + rot = props.getRotation(); + dim = props.getDimensions(); + registrationPoint = props.getRegistrationPoint(); + } + const glm::vec3 DEFAULT_REGISTRATION_POINT = glm::vec3(0.5f); + endVec = pos + rot * (dim * (DEFAULT_REGISTRATION_POINT - registrationPoint)); + } else { + if (type == IntersectionType::ENTITY) { + endVec = DependencyManager::get()->getEntityTransform(objectID)[3]; + } else if (type == IntersectionType::OVERLAY) { + endVec = vec3FromVariant(qApp->getOverlays().getProperty(objectID, "position").value); + } else if (type == IntersectionType::AVATAR) { + endVec = DependencyManager::get()->getAvatar(objectID)->getPosition(); + } } } QVariant end = vec3toVariant(endVec); diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 34d9ee50df..6f70268b8c 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -68,6 +68,8 @@ public: void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { DependencyManager::get()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); } void setIncludeAvatars(const QScriptValue& includeAvatars) { DependencyManager::get()->setIncludeAvatars(_rayPickUID, includeAvatars); } + void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = QPair(objectID, isOverlay); } + void update(); private: @@ -78,6 +80,7 @@ private: bool _faceAvatar; bool _centerEndY; bool _lockEnd; + QPair _objectLockEnd { QPair(QUuid(), false)}; QUuid _rayPickUID; diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index b05f56fa53..b852416463 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -143,4 +143,12 @@ void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& inclu QWriteLocker laserLock(_laserPointerLocks[uid].get()); _laserPointers[uid]->setIncludeAvatars(includeAvatars); } -} \ No newline at end of file +} + +void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) { + QReadLocker lock(&_containsLock); + if (_laserPointers.contains(uid)) { + QWriteLocker laserLock(_laserPointerLocks[uid].get()); + _laserPointers[uid]->setLockEndUUID(objectID, isOverlay); + } +} diff --git a/interface/src/raypick/LaserPointerManager.h b/interface/src/raypick/LaserPointerManager.h index db035b197f..dc9790af4e 100644 --- a/interface/src/raypick/LaserPointerManager.h +++ b/interface/src/raypick/LaserPointerManager.h @@ -41,6 +41,8 @@ public: void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars); void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars); + void setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay); + void update(); private: diff --git a/interface/src/raypick/LaserPointerScriptingInterface.h b/interface/src/raypick/LaserPointerScriptingInterface.h index a6b61446a7..f28a09dbbc 100644 --- a/interface/src/raypick/LaserPointerScriptingInterface.h +++ b/interface/src/raypick/LaserPointerScriptingInterface.h @@ -37,6 +37,8 @@ public slots: Q_INVOKABLE void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { DependencyManager::get()->setIgnoreAvatars(uid, ignoreAvatars); } Q_INVOKABLE void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { DependencyManager::get()->setIncludeAvatars(uid, includeAvatars); } + Q_INVOKABLE void setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay); } + private: const RenderState buildRenderState(const QVariantMap & propMap); diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index a3473df7e3..1651877407 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -266,7 +266,6 @@ function Grabber() { this.mouseRayEntities = LaserPointers.createLaserPointer({ joint: "Mouse", filter: RayPick.PICK_ENTITIES, - lockEnd: true, faceAvatar: true, enabled: true }); @@ -341,6 +340,7 @@ Grabber.prototype.pressEvent = function(event) { } LaserPointers.setRenderState(this.mouseRayEntities, "grabbed"); + LaserPointers.setLockEndUUID(this.mouseRayEntities, pickResults.objectID, false); mouse.startDrag(event); diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 855a50e009..dccf8e890b 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1438,6 +1438,11 @@ function MyController(hand) { } LaserPointers.enableLaserPointer(laserPointerID); LaserPointers.setRenderState(laserPointerID, mode); + if (this.state === STATE_DISTANCE_HOLDING || this.state === STATE_DISTANCE_ROTATING) { + LaserPointers.setLockEndUUID(laserPointerID, this.grabbedThingID, this.grabbedIsOverlay); + } else { + LaserPointers.setLockEndUUID(laserPointerID, null, false); + } }; this.laserPointerOff = function() {