From 022bf6de8c4b76bf55bdd7afc6f204bc8be9d0ab Mon Sep 17 00:00:00 2001 From: ksuprynowicz Date: Sun, 16 Apr 2023 17:01:38 +0200 Subject: [PATCH] Laser pointer fixes --- .../src/raypick/PointerScriptingInterface.cpp | 121 ++++++++++++++++++ .../src/raypick/PointerScriptingInterface.h | 8 ++ .../debugging/debugWorkloadWithMouseHover.js | 4 +- .../utilities/render/debugHighlight.js | 5 +- .../utilities/render/debugTransition.js | 8 +- .../controllers/controllerDispatcher.js | 2 +- .../controllerModules/stylusInput.js | 3 +- .../controllers/controllerModules/teleport.js | 12 +- scripts/system/controllers/grab.js | 7 +- scripts/system/libraries/pointersUtils.js | 12 +- 10 files changed, 160 insertions(+), 22 deletions(-) diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp index 2ad27274c8..61c75ee016 100644 --- a/interface/src/raypick/PointerScriptingInterface.cpp +++ b/interface/src/raypick/PointerScriptingInterface.cpp @@ -28,6 +28,8 @@ STATIC_SCRIPT_TYPES_INITIALIZER((+[](ScriptManager* manager){ qDebug() << "STATIC_SCRIPT_TYPES_INITIALIZER PointerScriptingInterface"; auto scriptEngine = manager->engine().get(); scriptRegisterMetaType(scriptEngine); + scriptRegisterMetaType(scriptEngine); + scriptRegisterMetaType(scriptEngine); })); static const glm::quat X_ROT_NEG_90{ 0.70710678f, -0.70710678f, 0.0f, 0.0f }; @@ -82,6 +84,15 @@ unsigned int PointerScriptingInterface::createRayPointer(RayPointerProperties pr return createPointerInternal(PickQuery::PickType::Ray, properties); } +unsigned int PointerScriptingInterface::createStylusPointer(StylusPointerProperties properties) { + return createPointerInternal(PickQuery::PickType::Stylus, properties); +} + +unsigned int PointerScriptingInterface::createParabolaPointer(ParabolaPointerProperties properties) { + return createPointerInternal(PickQuery::PickType::Parabola, properties); +} + + bool PointerScriptingInterface::isPointerEnabled(unsigned int uid) const { return DependencyManager::get()->isPointerEnabled(uid); } @@ -614,3 +625,113 @@ bool rayPointerPropertiesFromScriptValue(const ScriptValue& value, RayPointerPro qDebug() << "rayPointerPropertiesFromScriptValue" << out.properties; return true; } + +ScriptValue stylusPointerPropertiesToScriptValue(ScriptEngine* engine, const StylusPointerProperties& in) { + return engine->newVariant(QVariant(in.properties)); +} + +//V8TODO: adapt render states to what parabola expects +bool stylusPointerPropertiesFromScriptValue(const ScriptValue& value, StylusPointerProperties& out) { + // This copies properties from script value, but also converts entity properties of entities used in render states + // from JS objects into EntityItemProperties + out.properties = value.engine()->fromScriptValue(value); + QList renderStatesNames; + renderStatesNames.append("renderStates"); + renderStatesNames.append("defaultRenderStates"); + for (auto renderStatesName = renderStatesNames.cbegin(); renderStatesName!=renderStatesNames.cend(); renderStatesName++) { + if (out.properties[*renderStatesName].canConvert()) { + QVariantList renderStates = out.properties[*renderStatesName].value(); + for (int i = 0; i < renderStates.length(); i++) { + if (renderStates[i].canConvert()) { + QVariantMap stateMap = renderStates[i].value(); + if (stateMap["name"].canConvert()) { + stateMap["name"].value(); + } + if (stateMap["start"].isValid()) { + ScriptValue start = value.property(*renderStatesName).property(i).property("start"); + EntityItemProperties startProperties; + startProperties.copyFromScriptValue(start, false); + stateMap.insert("startPropertyIndex", QVariant(out.entityProperties.length())); + out.entityProperties.append(startProperties); + } + + if (stateMap["path"].isValid()) { + ScriptValue path = value.property(*renderStatesName).property(i).property("path"); + EntityItemProperties pathProperties; + pathProperties.copyFromScriptValue(path, false); + stateMap.insert("pathPropertyIndex", QVariant(out.entityProperties.length())); + out.entityProperties.append(pathProperties); + } + + if (stateMap["end"].isValid()) { + ScriptValue end = value.property(*renderStatesName).property(i).property("end"); + EntityItemProperties endProperties; + endProperties.copyFromScriptValue(end, false); + stateMap.insert("endPropertyIndex", QVariant(out.entityProperties.length())); + out.entityProperties.append(endProperties); + } + // V8TODO: Check if path is a polyline and if values are valid + renderStates[i].setValue(stateMap); + } + } + out.properties[*renderStatesName].setValue(renderStates); + } + } + qDebug() << "rayPointerPropertiesFromScriptValue" << out.properties; + return true; +} + +ScriptValue parabolaPointerPropertiesToScriptValue(ScriptEngine* engine, const ParabolaPointerProperties& in) { + return engine->newVariant(QVariant(in.properties)); +} + +//V8TODO: adapt render states to what parabola expects +bool parabolaPointerPropertiesFromScriptValue(const ScriptValue& value, ParabolaPointerProperties& out) { + // This copies properties from script value, but also converts entity properties of entities used in render states + // from JS objects into EntityItemProperties + out.properties = value.engine()->fromScriptValue(value); + QList renderStatesNames; + renderStatesNames.append("renderStates"); + renderStatesNames.append("defaultRenderStates"); + for (auto renderStatesName = renderStatesNames.cbegin(); renderStatesName!=renderStatesNames.cend(); renderStatesName++) { + if (out.properties[*renderStatesName].canConvert()) { + QVariantList renderStates = out.properties[*renderStatesName].value(); + for (int i = 0; i < renderStates.length(); i++) { + if (renderStates[i].canConvert()) { + QVariantMap stateMap = renderStates[i].value(); + if (stateMap["name"].canConvert()) { + stateMap["name"].value(); + } + if (stateMap["start"].isValid()) { + ScriptValue start = value.property(*renderStatesName).property(i).property("start"); + EntityItemProperties startProperties; + startProperties.copyFromScriptValue(start, false); + stateMap.insert("startPropertyIndex", QVariant(out.entityProperties.length())); + out.entityProperties.append(startProperties); + } + + if (stateMap["path"].isValid()) { + ScriptValue path = value.property(*renderStatesName).property(i).property("path"); + EntityItemProperties pathProperties; + pathProperties.copyFromScriptValue(path, false); + stateMap.insert("pathPropertyIndex", QVariant(out.entityProperties.length())); + out.entityProperties.append(pathProperties); + } + + if (stateMap["end"].isValid()) { + ScriptValue end = value.property(*renderStatesName).property(i).property("end"); + EntityItemProperties endProperties; + endProperties.copyFromScriptValue(end, false); + stateMap.insert("endPropertyIndex", QVariant(out.entityProperties.length())); + out.entityProperties.append(endProperties); + } + // V8TODO: Check if path is a polyline and if values are valid + renderStates[i].setValue(stateMap); + } + } + out.properties[*renderStatesName].setValue(renderStates); + } + } + qDebug() << "rayPointerPropertiesFromScriptValue" << out.properties; + return true; +} diff --git a/interface/src/raypick/PointerScriptingInterface.h b/interface/src/raypick/PointerScriptingInterface.h index 3313ce0bc2..033ef27488 100644 --- a/interface/src/raypick/PointerScriptingInterface.h +++ b/interface/src/raypick/PointerScriptingInterface.h @@ -48,6 +48,8 @@ class StylusPointerProperties : public PointerProperties { }; Q_DECLARE_METATYPE(RayPointerProperties); +Q_DECLARE_METATYPE(StylusPointerProperties); +Q_DECLARE_METATYPE(ParabolaPointerProperties); Q_DECLARE_METATYPE(PointerProperties); class PointerScriptingInterface : public QObject, public Dependency { @@ -159,6 +161,8 @@ public: // V8TODO: add documentation Q_INVOKABLE unsigned int createRayPointer(RayPointerProperties properties); + Q_INVOKABLE unsigned int createStylusPointer(StylusPointerProperties properties); + Q_INVOKABLE unsigned int createParabolaPointer(ParabolaPointerProperties properties); /*@jsdoc * Enables and shows a pointer. Enabled pointers update their pick results and generate events. @@ -512,7 +516,11 @@ private: }; ScriptValue rayPointerPropertiesToScriptValue(ScriptEngine* engine, const RayPointerProperties& in); +ScriptValue stylusPointerPropertiesToScriptValue(ScriptEngine* engine, const StylusPointerProperties& in); +ScriptValue parabolaPointerPropertiesToScriptValue(ScriptEngine* engine, const ParabolaPointerProperties& in); bool rayPointerPropertiesFromScriptValue(const ScriptValue& value, RayPointerProperties& out); +bool stylusPointerPropertiesFromScriptValue(const ScriptValue& value, StylusPointerProperties& out); +bool parabolaPointerPropertiesFromScriptValue(const ScriptValue& value, ParabolaPointerProperties& out); #endif // hifi_PointerScriptingInterface_h diff --git a/scripts/developer/debugging/debugWorkloadWithMouseHover.js b/scripts/developer/debugging/debugWorkloadWithMouseHover.js index eaff607359..7150182a54 100644 --- a/scripts/developer/debugging/debugWorkloadWithMouseHover.js +++ b/scripts/developer/debugging/debugWorkloadWithMouseHover.js @@ -30,7 +30,7 @@ color: COLOR2, ignorePickIntersection: true } - var laser = Pointers.createPointer(PickType.Ray, { + var laser = Pointers.createRayPointer({ joint: "Mouse", filter: Picks.PICK_ENTITIES | Picks.PICK_BYPASS_IGNORE | Picks.PICK_INCLUDE_COLLIDABLE | Picks.PICK_INCLUDE_NONCOLLIDABLE, renderStates: [{name: "one", end: end1}], @@ -40,7 +40,7 @@ Pointers.setRenderState(laser, "one"); var hoveredObject = undefined; - var SelectionListName = "DebugWorkloadSelection"; // sekret undocumented selection list (hard coded in C++) + var SelectionListName = "DebugWorkloadSelection"; // secret undocumented selection list (hard coded in C++) var selectionStyle = { isOutlineSmooth: true, outlineWidth: 5, diff --git a/scripts/developer/utilities/render/debugHighlight.js b/scripts/developer/utilities/render/debugHighlight.js index e8a83f0fc5..7ce9bad459 100644 --- a/scripts/developer/utilities/render/debugHighlight.js +++ b/scripts/developer/utilities/render/debugHighlight.js @@ -94,7 +94,8 @@ color: COLOR2, ignorePickIntersection: true } - var laser = Pointers.createPointer(PickType.Ray, { + //V8TODO + var laser = Pointers.createRayPointer({ joint: "Mouse", filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS | Picks.PICK_AVATARS, renderStates: [{name: "one", end: end1}], @@ -124,7 +125,7 @@ Pointers.disablePointer(laser) function fromQml(message) { - tokens = message.split(' ') + var tokens = message.split(' ') print("Received message from QML") if (tokens[0]=="highlight") { currentSelectionName = tokens[1]; diff --git a/scripts/developer/utilities/render/debugTransition.js b/scripts/developer/utilities/render/debugTransition.js index 491905a2ef..e87c2330c3 100644 --- a/scripts/developer/utilities/render/debugTransition.js +++ b/scripts/developer/utilities/render/debugTransition.js @@ -78,18 +78,18 @@ type: "sphere", dimensions: END_DIMENSIONS, color: COLOR1, - ignoreRayIntersection: true + ignorePickIntersection: true } var end2 = { - type: "sphere", + type: "Sphere", dimensions: END_DIMENSIONS, color: COLOR2, - ignoreRayIntersection: true + ignorePickIntersection: true } var laser function enablePointer() { - laser = Pointers.createPointer(PickType.Ray, { + laser = Pointers.createRayPointer({ joint: "Mouse", filter: Picks.PICK_ENTITIES, renderStates: [{name: "one", end: end1}], diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 687047c531..64ee5b5a36 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -618,7 +618,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); hand: RIGHT_HAND }); - this.mouseRayPointer = Pointers.createPointer(PickType.Ray, { + this.mouseRayPointer = Pointers.createRayPointer({ joint: "Mouse", filter: Picks.PICK_OVERLAYS | Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_NONCOLLIDABLE, enabled: true diff --git a/scripts/system/controllers/controllerModules/stylusInput.js b/scripts/system/controllers/controllerModules/stylusInput.js index 38ee6a765b..15048bca00 100644 --- a/scripts/system/controllers/controllerModules/stylusInput.js +++ b/scripts/system/controllers/controllerModules/stylusInput.js @@ -47,7 +47,8 @@ Script.include("/~/system/libraries/controllers.js"); [], 100); - this.pointer = Pointers.createPointer(PickType.Stylus, { + //V8TODO + this.pointer = Pointers.createStylusPointer({ hand: this.hand, filter: Picks.PICK_OVERLAYS, hover: true, diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index abe3bbea5b..5ed8346462 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -295,7 +295,8 @@ Script.include("/~/system/libraries/controllers.js"); _this.cleanup(); } - _this.teleportParabolaHandVisuals = Pointers.createPointer(PickType.Parabola, { + //V8TODO + _this.teleportParabolaHandVisuals = Pointers.createParabolaPointer({ joint: (_this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", dirOffset: { x: 0, y: 1, z: 0.1 }, posOffset: { x: (_this.hand === RIGHT_HAND) ? 0.03 : -0.03, y: 0.2, z: 0.02 }, @@ -311,7 +312,8 @@ Script.include("/~/system/libraries/controllers.js"); maxDistance: 8.0 }); - _this.teleportParabolaHandCollisions = Pointers.createPointer(PickType.Parabola, { + //V8TODO + _this.teleportParabolaHandCollisions = Pointers.createParabolaPointer({ joint: (_this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", dirOffset: { x: 0, y: 1, z: 0.1 }, posOffset: { x: (_this.hand === RIGHT_HAND) ? 0.03 : -0.03, y: 0.2, z: 0.02 }, @@ -326,7 +328,8 @@ Script.include("/~/system/libraries/controllers.js"); maxDistance: 8.0 }); - _this.teleportParabolaHeadVisuals = Pointers.createPointer(PickType.Parabola, { + //V8TODO + _this.teleportParabolaHeadVisuals = Pointers.createParabolaPointer({ joint: "Avatar", filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, faceAvatar: true, @@ -340,7 +343,8 @@ Script.include("/~/system/libraries/controllers.js"); maxDistance: 8.0 }); - _this.teleportParabolaHeadCollisions = Pointers.createPointer(PickType.Parabola, { + //V8TODO + _this.teleportParabolaHeadCollisions = Pointers.createParabolaPointer({ joint: "Avatar", filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, faceAvatar: true, diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index cf73404c9d..459fad3425 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -148,7 +148,7 @@ Mouse.prototype.restoreRotateCursor = function() { var mouse = new Mouse(); var beacon = { - type: "cube", + type: "Box", dimensions: { x: 0.01, y: 0, @@ -160,8 +160,7 @@ var beacon = { blue: 200 }, alpha: 1, - solid: true, - ignoreRayIntersection: true, + ignorePickIntersection: true, visible: true }; @@ -213,7 +212,7 @@ function Grabber() { Picks.setIncludeItems(this.mouseRayOverlays, tabletItems); } var renderStates = [{name: "grabbed", end: beacon}]; - this.mouseRayEntities = Pointers.createPointer(PickType.Ray, { + this.mouseRayEntities = Pointers.createRayPointer({ joint: "Mouse", filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_NONCOLLIDABLE, faceAvatar: true, diff --git a/scripts/system/libraries/pointersUtils.js b/scripts/system/libraries/pointersUtils.js index f807bb6db6..5920911414 100644 --- a/scripts/system/libraries/pointersUtils.js +++ b/scripts/system/libraries/pointersUtils.js @@ -104,10 +104,14 @@ var Pointer = function(hudLayer, pickType, pointerData) { function createPointer(pickType, pointerData) { //V8TODO - var pointerID = Pointers.createPointer(pickType, pointerData); - Pointers.setRenderState(pointerID, ""); - Pointers.enablePointer(pointerID); - return pointerID; + if (pickType == PickType.Ray) { + var pointerID = Pointers.createRayPointer(pointerData); + Pointers.setRenderState(pointerID, ""); + Pointers.enablePointer(pointerID); + return pointerID; + } else { + print("pointerUtils.js createPointer: ray type not supported yet on V8 branch"); + } } this.enable = function() {