From d47c040768f0faaaf7590515eb8a18e0e31d7771 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 29 Mar 2017 18:15:29 -0700 Subject: [PATCH 01/23] Vive: Expose all 16 tracked poses to the controller system. This is in preparation for the Vive hockey puck trackers... --- .../src/controllers/StandardControls.h | 16 ++ plugins/openvr/src/ViveControllerManager.cpp | 164 +++++------------- plugins/openvr/src/ViveControllerManager.h | 3 +- 3 files changed, 64 insertions(+), 119 deletions(-) diff --git a/libraries/controllers/src/controllers/StandardControls.h b/libraries/controllers/src/controllers/StandardControls.h index c21d8a2f6e..f521ab81cf 100644 --- a/libraries/controllers/src/controllers/StandardControls.h +++ b/libraries/controllers/src/controllers/StandardControls.h @@ -158,6 +158,22 @@ namespace controller { LEFT_HAND_PINKY2, LEFT_HAND_PINKY3, LEFT_HAND_PINKY4, + TRACKED_OBJECT_00, + TRACKED_OBJECT_01, + TRACKED_OBJECT_02, + TRACKED_OBJECT_03, + TRACKED_OBJECT_04, + TRACKED_OBJECT_05, + TRACKED_OBJECT_06, + TRACKED_OBJECT_07, + TRACKED_OBJECT_08, + TRACKED_OBJECT_09, + TRACKED_OBJECT_10, + TRACKED_OBJECT_11, + TRACKED_OBJECT_12, + TRACKED_OBJECT_13, + TRACKED_OBJECT_14, + TRACKED_OBJECT_15, NUM_STANDARD_POSES }; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 2e930c0fdc..8cedee2d8f 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -63,59 +63,6 @@ bool ViveControllerManager::activate() { enableOpenVrKeyboard(_container); - // OpenVR provides 3d mesh representations of the controllers - // Disabled controller rendering code - /* - auto renderModels = vr::VRRenderModels(); - - vr::RenderModel_t model; - if (!_system->LoadRenderModel(CONTROLLER_MODEL_STRING, &model)) { - qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING); - } else { - model::Mesh* mesh = new model::Mesh(); - model::MeshPointer meshPtr(mesh); - _modelGeometry.setMesh(meshPtr); - - auto indexBuffer = new gpu::Buffer(3 * model.unTriangleCount * sizeof(uint16_t), (gpu::Byte*)model.rIndexData); - auto indexBufferPtr = gpu::BufferPointer(indexBuffer); - auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT16, gpu::RAW)); - mesh->setIndexBuffer(*indexBufferView); - - auto vertexBuffer = new gpu::Buffer(model.unVertexCount * sizeof(vr::RenderModel_Vertex_t), - (gpu::Byte*)model.rVertexData); - auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer); - auto vertexBufferView = new gpu::BufferView(vertexBufferPtr, - 0, - vertexBufferPtr->getSize() - sizeof(float) * 3, - sizeof(vr::RenderModel_Vertex_t), - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)); - mesh->setVertexBuffer(*vertexBufferView); - mesh->addAttribute(gpu::Stream::NORMAL, - gpu::BufferView(vertexBufferPtr, - sizeof(float) * 3, - vertexBufferPtr->getSize() - sizeof(float) * 3, - sizeof(vr::RenderModel_Vertex_t), - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW))); - //mesh->addAttribute(gpu::Stream::TEXCOORD, - // gpu::BufferView(vertexBufferPtr, - // 2 * sizeof(float) * 3, - // vertexBufferPtr->getSize() - sizeof(float) * 2, - // sizeof(vr::RenderModel_Vertex_t), - // gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW))); - - gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); - gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); - _texture = gpu::TexturePointer( - gpu::Texture::create2D(formatGPU, model.diffuseTexture.unWidth, model.diffuseTexture.unHeight, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); - _texture->assignStoredMip(0, formatMip, model.diffuseTexture.unWidth * model.diffuseTexture.unHeight * 4 * sizeof(uint8_t), model.diffuseTexture.rubTextureMapData); - _texture->autoGenerateMips(-1); - - _modelLoaded = true; - _renderControllers = true; - } - */ - // register with UserInputMapper auto userInputMapper = DependencyManager::get(); userInputMapper->registerDevice(_inputDevice); @@ -145,70 +92,6 @@ void ViveControllerManager::deactivate() { _registeredWithInputMapper = false; } -void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges) { - PerformanceTimer perfTimer("ViveControllerManager::updateRendering"); - - /* - if (_modelLoaded) { - //auto controllerPayload = new render::Payload(this); - //auto controllerPayloadPointer = ViveControllerManager::PayloadPointer(controllerPayload); - //if (_leftHandRenderID == 0) { - // _leftHandRenderID = scene->allocateID(); - // pendingChanges.resetItem(_leftHandRenderID, controllerPayloadPointer); - //} - //pendingChanges.updateItem(_leftHandRenderID, ); - - - controller::Pose leftHand = _inputDevice->_poseStateMap[controller::StandardPoseChannel::LEFT_HAND]; - controller::Pose rightHand = _inputDevice->_poseStateMap[controller::StandardPoseChannel::RIGHT_HAND]; - - gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { - auto geometryCache = DependencyManager::get(); - geometryCache->useSimpleDrawPipeline(batch); - DependencyManager::get()->bindSimpleProgram(batch, true); - - auto mesh = _modelGeometry.getMesh(); - batch.setInputFormat(mesh->getVertexFormat()); - //batch._glBindTexture(GL_TEXTURE_2D, _uexture); - - if (leftHand.isValid()) { - renderHand(leftHand, batch, 1); - } - if (rightHand.isValid()) { - renderHand(rightHand, batch, -1); - } - }); - } - */ -} - -void ViveControllerManager::renderHand(const controller::Pose& pose, gpu::Batch& batch, int sign) { - /* - auto userInputMapper = DependencyManager::get(); - Transform transform(userInputMapper->getSensorToWorldMat()); - transform.postTranslate(pose.getTranslation() + pose.getRotation() * glm::vec3(0, 0, CONTROLLER_LENGTH_OFFSET)); - - glm::quat rotation = pose.getRotation() * glm::angleAxis(PI, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::angleAxis(sign * PI_OVER_TWO, glm::vec3(0.0f, 0.0f, 1.0f)); - transform.postRotate(rotation); - - batch.setModelTransform(transform); - - auto mesh = _modelGeometry.getMesh(); - batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer()); - batch.setInputBuffer(gpu::Stream::NORMAL, - mesh->getVertexBuffer()._buffer, - sizeof(float) * 3, - mesh->getVertexBuffer()._stride); - //batch.setInputBuffer(gpu::Stream::TEXCOORD, - // mesh->getVertexBuffer()._buffer, - // 2 * 3 * sizeof(float), - // mesh->getVertexBuffer()._stride); - batch.setIndexBuffer(gpu::UINT16, mesh->getIndexBuffer()._buffer, 0); - batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); - */ -} - - void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { if (!_system) { @@ -257,6 +140,11 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true); handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false); + // collect raw poses + for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { + handleTrackedObject(i, inputCalibrationData); + } + // handle haptics { Locker locker(_lock); @@ -278,6 +166,30 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle _trackedControllers = numTrackedControllers; } +void ViveControllerManager::InputDevice::handleTrackedObject(uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData) { + + uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex; + + if (_system->IsTrackedDeviceConnected(deviceIndex) && + _nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid && + poseIndex <= controller::TRACKED_OBJECT_15) { + + // process pose + const mat4& mat = _nextSimPoseData.poses[deviceIndex]; + const vec3 linearVelocity = _nextSimPoseData.linearVelocities[deviceIndex]; + const vec3 angularVelocity = _nextSimPoseData.angularVelocities[deviceIndex]; + + controller::Pose pose(extractTranslation(mat), glmExtractRotation(mat), linearVelocity, angularVelocity); + + // transform into avatar frame + glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat; + _poseStateMap[poseIndex] = pose.transform(controllerToAvatar); + } else { + controller::Pose invalidPose; + _poseStateMap[poseIndex] = invalidPose; + } +} + void ViveControllerManager::InputDevice::handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand) { if (_system->IsTrackedDeviceConnected(deviceIndex) && @@ -492,6 +404,24 @@ controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableI makePair(LEFT_HAND, "LeftHand"), makePair(RIGHT_HAND, "RightHand"), + // 16 tracked poses + makePair(TRACKED_OBJECT_00, "TrackedObject00"), + makePair(TRACKED_OBJECT_01, "TrackedObject01"), + makePair(TRACKED_OBJECT_02, "TrackedObject02"), + makePair(TRACKED_OBJECT_03, "TrackedObject03"), + makePair(TRACKED_OBJECT_04, "TrackedObject04"), + makePair(TRACKED_OBJECT_05, "TrackedObject05"), + makePair(TRACKED_OBJECT_06, "TrackedObject06"), + makePair(TRACKED_OBJECT_07, "TrackedObject07"), + makePair(TRACKED_OBJECT_08, "TrackedObject08"), + makePair(TRACKED_OBJECT_09, "TrackedObject09"), + makePair(TRACKED_OBJECT_10, "TrackedObject10"), + makePair(TRACKED_OBJECT_11, "TrackedObject11"), + makePair(TRACKED_OBJECT_12, "TrackedObject12"), + makePair(TRACKED_OBJECT_13, "TrackedObject13"), + makePair(TRACKED_OBJECT_14, "TrackedObject14"), + makePair(TRACKED_OBJECT_15, "TrackedObject15"), + // app button above trackpad. Input::NamedPair(Input(_deviceID, LEFT_APP_MENU, ChannelType::BUTTON), "LeftApplicationMenu"), Input::NamedPair(Input(_deviceID, RIGHT_APP_MENU, ChannelType::BUTTON), "RightApplicationMenu"), diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 3fb166c842..dc1883d5e4 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -43,8 +43,6 @@ public: void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; - void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges); - void setRenderControllers(bool renderControllers) { _renderControllers = renderControllers; } private: @@ -62,6 +60,7 @@ private: void hapticsHelper(float deltaTime, bool leftHand); void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand); + void handleTrackedObject(uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData); void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand); void handleAxisEvent(float deltaTime, uint32_t axis, float x, float y, bool isLeftHand); void handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const mat4& mat, From 0e63f97f7747f7d0eab4d6c551ff14feefd00f3b Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 29 Mar 2017 18:17:32 -0700 Subject: [PATCH 02/23] Test script that displays tracking data from Vive.TrackedObjects --- scripts/developer/tests/viveTrackedObjects.js | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 scripts/developer/tests/viveTrackedObjects.js diff --git a/scripts/developer/tests/viveTrackedObjects.js b/scripts/developer/tests/viveTrackedObjects.js new file mode 100644 index 0000000000..78911538e4 --- /dev/null +++ b/scripts/developer/tests/viveTrackedObjects.js @@ -0,0 +1,36 @@ + +var TRACKED_OBJECT_POSES = [ + "TrackedObject00", "TrackedObject01", "TrackedObject02", "TrackedObject03", + "TrackedObject04", "TrackedObject05", "TrackedObject06", "TrackedObject07", + "TrackedObject08", "TrackedObject09", "TrackedObject10", "TrackedObject11", + "TrackedObject12", "TrackedObject13", "TrackedObject14", "TrackedObject15" +]; + +function init() { + Script.update.connect(update); +} + +function shutdown() { + Script.update.disconnect(update); + + TRACKED_OBJECT_POSES.forEach(function (key) { + DebugDraw.removeMyAvatarMarker(key); + }); +} + +var WHITE = {x: 1, y: 1, z: 1, w: 1}; + +function update(dt) { + if (Controller.Hardware.Vive) { + TRACKED_OBJECT_POSES.forEach(function (key) { + var pose = Controller.getPoseValue(Controller.Hardware.Vive[key]); + if (pose.valid) { + DebugDraw.addMyAvatarMarker(key, pose.rotation, pose.translation, WHITE); + } else { + DebugDraw.removeMyAvatarMarker(key); + } + }); + } +} + +init(); From 849d65f95f2e1fbd4bde1e3fdfda29988ae5f35e Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Fri, 31 Mar 2017 15:01:19 +0200 Subject: [PATCH 03/23] Fixed warning: Tablet.qml:205: TypeError: Cannot read property of null (cherry picked from commit b1dc14b355bc6053a0e264a057a799a4d446e347) --- interface/resources/qml/hifi/tablet/Tablet.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/tablet/Tablet.qml b/interface/resources/qml/hifi/tablet/Tablet.qml index 3fb70f9cca..8ad6339d88 100644 --- a/interface/resources/qml/hifi/tablet/Tablet.qml +++ b/interface/resources/qml/hifi/tablet/Tablet.qml @@ -202,7 +202,7 @@ Item { RalewaySemiBold { id: usernameText - text: tablet.parent.parent.username + text: tabletRoot.username anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 20 From 6b7f3f7125994ed6a8f2c77a5ca6e4ce3f793c71 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Fri, 31 Mar 2017 15:09:39 +0200 Subject: [PATCH 04/23] Fixed warning: TabletAddressDialog.qml:282:13: QML ListView: Cannot specify top, bottom, and verticalCenter anchors at the same time. (cherry picked from commit b11e245cb1b19149ff00f16b718ff4088b856f3e) --- interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index a58177640d..e99332368e 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -291,8 +291,6 @@ StackView { left: parent.left right: parent.right leftMargin: 10 - verticalCenter: parent.verticalCenter; - horizontalCenter: parent.horizontalCenter; } model: suggestions orientation: ListView.Vertical From 9e96888534b703a67026bf16ed95b71c9bf0c600 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Fri, 31 Mar 2017 15:18:02 +0200 Subject: [PATCH 05/23] Fixed warning: TabletAddressDialog.qml:546: Error: Cannot assign to non-existent property 'shown' (cherry picked from commit e70c2cdcc74f9fd43273dca268433cdefd9ecf40) --- interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 6 +++--- interface/resources/qml/hifi/tablet/TabletRoot.qml | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index e99332368e..b3d56f02f2 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -107,7 +107,7 @@ StackView { imageURL: "../../../images/home.svg" onClicked: { addressBarDialog.loadHome(); - root.shown = false; + tabletRoot.shown = false; } anchors { left: parent.left @@ -541,14 +541,14 @@ StackView { if (addressLine.text !== "") { addressBarDialog.loadAddress(addressLine.text, fromSuggestions) } - root.shown = false; + tabletRoot.shown = false; } Keys.onPressed: { switch (event.key) { case Qt.Key_Escape: case Qt.Key_Back: - root.shown = false + tabletRoot.shown = false clearAddressLineTimer.start(); event.accepted = true break diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 8037c1280e..f5144e698f 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -13,6 +13,7 @@ Item { property var openMessage: null; property string subMenu: "" signal showDesktop(); + property bool shown: true function setOption(value) { option = value; From 156166ce4a0b8dac8a40fb08b76835eca676eaa7 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Fri, 31 Mar 2017 15:25:53 +0200 Subject: [PATCH 06/23] Fixed another warning in TabletAddressDialog.qml (cherry picked from commit 73c923bb522ad711380a2fcdaa9babe9f01a639a) --- interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index b3d56f02f2..4699bfd66b 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -25,8 +25,8 @@ StackView { HifiConstants { id: hifi } HifiStyles.HifiConstants { id: hifiStyleConstants } initialItem: addressBarDialog - width: parent.width - height: parent.height + width: parent !== null ? parent.width : undefined + height: parent !== null ? parent.height : undefined property var eventBridge; property var allStories: []; property int cardWidth: 460; @@ -142,7 +142,9 @@ StackView { anchors { top: navBar.bottom right: parent.right + rightMargin: 16 left: parent.left + leftMargin: 16 } property int inputAreaHeight: 70 From 7318ec468b7d1e5880a3f24910ad5afea239d0c6 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Fri, 31 Mar 2017 16:01:43 +0200 Subject: [PATCH 07/23] Fixed warning QObject::connect: No such signal Desktop_QMLTYPE_217::sendToScript(QVariant) (cherry picked from commit ef4bea2cd4811364e65baec2c48ce2205a0e2cb3) --- libraries/gl/src/gl/OffscreenGLCanvas.cpp | 3 ++- libraries/gl/src/gl/OffscreenQmlSurface.cpp | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/gl/src/gl/OffscreenGLCanvas.cpp b/libraries/gl/src/gl/OffscreenGLCanvas.cpp index e54846196b..fcb3195741 100644 --- a/libraries/gl/src/gl/OffscreenGLCanvas.cpp +++ b/libraries/gl/src/gl/OffscreenGLCanvas.cpp @@ -59,7 +59,8 @@ bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) { bool OffscreenGLCanvas::makeCurrent() { bool result = _context->makeCurrent(_offscreenSurface); - Q_ASSERT(result); + //Q_ASSERT(result); + std::call_once(_reportOnce, [this]{ qCDebug(glLogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); qCDebug(glLogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index de0caf56a9..4842faa3ef 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -607,7 +607,11 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::functionmetaObject()->indexOfSignal("sendToScript"); + if (sendToScriptIndex != -1) { + connect(newItem, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(QVariant))); + } // The root item is ready. Associate it with the window. _rootItem = newItem; From 990e1379e3cc66e04e36c2f372b57713c65fb2a4 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Sat, 1 Apr 2017 20:33:46 +0200 Subject: [PATCH 08/23] Fix warning in Audio page. Revert commented out assert in OffscreenGLCanvas: move to separate task (cherry picked from commit d966979c2368b159cf5b96c5fd535411cda019b8) --- interface/resources/qml/hifi/Audio.qml | 4 ++-- libraries/gl/src/gl/OffscreenGLCanvas.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/Audio.qml b/interface/resources/qml/hifi/Audio.qml index deb44b9bd5..d0c3122100 100644 --- a/interface/resources/qml/hifi/Audio.qml +++ b/interface/resources/qml/hifi/Audio.qml @@ -127,7 +127,7 @@ Rectangle { text: hifi.glyphs.mic color: hifi.colors.primaryHighlight anchors.verticalCenter: parent.verticalCenter - font.pointSize: 27 + size: 32 } RalewayRegular { anchors.verticalCenter: parent.verticalCenter @@ -182,7 +182,7 @@ Rectangle { text: hifi.glyphs.unmuted color: hifi.colors.primaryHighlight anchors.verticalCenter: parent.verticalCenter - font.pointSize: 27 + size: 32 } RalewayRegular { anchors.verticalCenter: parent.verticalCenter diff --git a/libraries/gl/src/gl/OffscreenGLCanvas.cpp b/libraries/gl/src/gl/OffscreenGLCanvas.cpp index fcb3195741..e5c630d97e 100644 --- a/libraries/gl/src/gl/OffscreenGLCanvas.cpp +++ b/libraries/gl/src/gl/OffscreenGLCanvas.cpp @@ -59,7 +59,7 @@ bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) { bool OffscreenGLCanvas::makeCurrent() { bool result = _context->makeCurrent(_offscreenSurface); - //Q_ASSERT(result); + Q_ASSERT(result); std::call_once(_reportOnce, [this]{ qCDebug(glLogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); From a882beb2fd501b40aeb2ab04e8755bce040ca0f0 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 3 Apr 2017 17:35:28 -0700 Subject: [PATCH 09/23] Trying to fix the overlay Image3D shading pipeline used --- .../display-plugins/OpenGLDisplayPlugin.cpp | 2 +- libraries/gl/src/gl/OffscreenQmlSurface.cpp | 1 + .../render-utils/src/RenderPipelines.cpp | 15 +++++--- .../src/simple_textured_unlit.slf | 16 +++++++-- .../src/simple_transparent_textured.slf | 36 +++++++++++++++++++ 5 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 libraries/render-utils/src/simple_transparent_textured.slf diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index a3cf91fcd5..e05d7c5bc9 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -573,7 +573,7 @@ void OpenGLDisplayPlugin::compositeLayers() { { PROFILE_RANGE_EX(render_detail, "compositeOverlay", 0xff0077ff, (uint64_t)presentCount()) - compositeOverlay(); + // compositeOverlay(); } auto compositorHelper = DependencyManager::get(); if (compositorHelper->getReticleVisible()) { diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index de0caf56a9..27f4f4f5dc 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -278,6 +278,7 @@ void OffscreenQmlSurface::cleanup() { } void OffscreenQmlSurface::render() { + return; if (_paused) { return; } diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 414bcf0d63..efbe09863b 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -28,6 +28,10 @@ #include "skin_model_shadow_vert.h" #include "skin_model_normal_map_vert.h" +#include "simple_vert.h" +#include "simple_textured_frag.h" +#include "simple_textured_unlit_frag.h" + #include "model_frag.h" #include "model_unlit_frag.h" #include "model_shadow_frag.h" @@ -135,6 +139,7 @@ void initOverlay3DPipelines(ShapePlumber& plumber) { void initDeferredPipelines(render::ShapePlumber& plumber) { // Vertex shaders + auto simpleVertex = gpu::Shader::createVertex(std::string(simple_vert)); auto modelVertex = gpu::Shader::createVertex(std::string(model_vert)); auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert)); auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert)); @@ -145,6 +150,8 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { auto skinModelShadowVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert)); // Pixel shaders + auto simplePixel = gpu::Shader::createPixel(std::string(simple_textured_frag)); + auto simpleUnlitPixel = gpu::Shader::createPixel(std::string(simple_textured_unlit_frag)); auto modelPixel = gpu::Shader::createPixel(std::string(model_frag)); auto modelUnlitPixel = gpu::Shader::createPixel(std::string(model_unlit_frag)); auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag)); @@ -167,13 +174,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { modelVertex, modelPixel); addPipeline( Key::Builder(), - modelVertex, modelPixel); + modelVertex, simplePixel); addPipeline( Key::Builder().withMaterial().withUnlit(), modelVertex, modelUnlitPixel); addPipeline( Key::Builder().withUnlit(), - modelVertex, modelUnlitPixel); + modelVertex, simpleUnlitPixel); addPipeline( Key::Builder().withMaterial().withTangents(), modelNormalMapVertex, modelNormalMapPixel); @@ -189,13 +196,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { modelVertex, modelTranslucentPixel); addPipeline( Key::Builder().withTranslucent(), - modelVertex, modelTranslucentPixel); + simpleVertex, simplePixel); addPipeline( Key::Builder().withMaterial().withTranslucent().withUnlit(), modelVertex, modelTranslucentUnlitPixel); addPipeline( Key::Builder().withTranslucent().withUnlit(), - modelVertex, modelTranslucentUnlitPixel); + simpleVertex, simpleUnlitPixel); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents(), modelNormalMapVertex, modelTranslucentPixel); diff --git a/libraries/render-utils/src/simple_textured_unlit.slf b/libraries/render-utils/src/simple_textured_unlit.slf index 4f02140825..1ee2011972 100644 --- a/libraries/render-utils/src/simple_textured_unlit.slf +++ b/libraries/render-utils/src/simple_textured_unlit.slf @@ -2,7 +2,7 @@ <$VERSION_HEADER$> // Generated on <$_SCRIBE_DATE$> // -// simple.frag +// simple_textured_unlit.frag // fragment shader // // Created by Clément Brisset on 5/29/15. @@ -31,12 +31,22 @@ void main(void) { const float ALPHA_THRESHOLD = 0.999; if (_color.a * texel.a < ALPHA_THRESHOLD) { - packDeferredFragmentTranslucent( + + _fragColor0 = vec4(_color.rgb * texel.rgb, _color.a * texel.a); + + if (_color.a * texel.a <= 0.0) { + _fragColor0 = vec4(_color.rgb * texel.rgb, _color.a * texel.a); + //discard; + } else { + _fragColor0 = vec4(_color.rgb * texel.rgb, _color.a * texel.a); + } + // _fragColor0 = vec4(albedo.rgb, alpha); + /* packDeferredFragmentTranslucent( normalize(_normal), _color.a * texel.a, _color.rgb * texel.rgb, DEFAULT_FRESNEL, - DEFAULT_ROUGHNESS); + DEFAULT_ROUGHNESS);*/ } else { packDeferredFragmentUnlit( normalize(_normal), diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf new file mode 100644 index 0000000000..0fda804129 --- /dev/null +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -0,0 +1,36 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple_transparent_textured.slf +// fragment shader +// +// Created by Sam Gateau on 4/3/17. +// 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 gpu/Color.slh@> +<@include DeferredBufferWrite.slh@> +<@include model/Material.slh@> + +// the albedo texture +uniform sampler2D originalTexture; + +// the interpolated normal +in vec3 _normal; +in vec4 _color; +in vec2 _texCoord0; + +void main(void) { + vec4 texel = texture(originalTexture, _texCoord0.st); + texel = colorToLinearRGBA(texel); + packDeferredFragmentTranslucent( + normalize(_normal), + _color.a, + _color.rgb * texel.rgb, + DEFAULT_FRESNEL, + DEFAULT_ROUGHNESS); +} \ No newline at end of file From 072e024d9ad29723f384dcb811b56bd59e9f55f1 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Tue, 4 Apr 2017 16:10:37 +0200 Subject: [PATCH 10/23] Fixed warning in JSConsole --- interface/src/ui/JSConsole.cpp | 14 ++++++++------ interface/src/ui/JSConsole.h | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/JSConsole.cpp b/interface/src/ui/JSConsole.cpp index 5d197f5ddc..7700874d9a 100644 --- a/interface/src/ui/JSConsole.cpp +++ b/interface/src/ui/JSConsole.cpp @@ -76,8 +76,8 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) { return; } if (_scriptEngine != NULL) { - disconnect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&))); - disconnect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&))); + disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &JSConsole::handlePrint); + disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &JSConsole::handleError); if (_ownScriptEngine) { _scriptEngine->deleteLater(); } @@ -87,8 +87,8 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) { _ownScriptEngine = scriptEngine == NULL; _scriptEngine = _ownScriptEngine ? DependencyManager::get()->loadScript(QString(), false) : scriptEngine; - connect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&))); - connect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&))); + connect(_scriptEngine, &ScriptEngine::printedMessage, this, &JSConsole::handlePrint); + connect(_scriptEngine, &ScriptEngine::errorMessage, this, &JSConsole::handleError); } void JSConsole::executeCommand(const QString& command) { @@ -134,11 +134,13 @@ void JSConsole::commandFinished() { resetCurrentCommandHistory(); } -void JSConsole::handleError(const QString& message) { +void JSConsole::handleError(const QString& scriptName, const QString& message) { + Q_UNUSED(scriptName); appendMessage(GUTTER_ERROR, "" + message.toHtmlEscaped() + ""); } -void JSConsole::handlePrint(const QString& message) { +void JSConsole::handlePrint(const QString& scriptName, const QString& message) { + Q_UNUSED(scriptName); appendMessage("", message); } diff --git a/interface/src/ui/JSConsole.h b/interface/src/ui/JSConsole.h index 47878fea99..d5f5aff301 100644 --- a/interface/src/ui/JSConsole.h +++ b/interface/src/ui/JSConsole.h @@ -47,8 +47,8 @@ protected: protected slots: void scrollToBottom(); void resizeTextInput(); - void handlePrint(const QString& message); - void handleError(const QString& message); + void handlePrint(const QString& scriptName, const QString& message); + void handleError(const QString& scriptName, const QString& message); void commandFinished(); private: From 332f9bb28354f6f6bf509939c72813769f5d3bc2 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Tue, 4 Apr 2017 16:22:40 +0200 Subject: [PATCH 11/23] Fixed TabletMenuStack.qml:56: Error: Cannot assign [undefined] to QString. Fixed keyboardRaised undefined error --- interface/resources/qml/hifi/dialogs/TabletAssetServer.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml b/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml index 2460fc39d5..85f8a2f59e 100644 --- a/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml +++ b/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml @@ -21,6 +21,9 @@ Rectangle { id: root objectName: "AssetServer" + property string title: "Asset Browser" + property bool keyboardRaised: false + property var eventBridge; signal sendToScript(var message); property bool isHMD: false @@ -415,7 +418,6 @@ Rectangle { Column { width: parent.width - y: hifi.dimensions.tabletMenuHeader //-bgNavBar spacing: 10 HifiControls.TabletContentSection { From 367555acdbdbe184ebd6945cef1876057fe55508 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Tue, 4 Apr 2017 16:35:21 +0200 Subject: [PATCH 12/23] Fixed BasicTableView.qml:610:17: QML Item: Binding loop detected for property width. width must be explicitly set --- .../resources/qml/hifi/dialogs/TabletRunningScripts.qml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml index dee0d0e21f..d826b40ad1 100644 --- a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml @@ -20,7 +20,7 @@ import "../../windows" Rectangle { id: root objectName: "RunningScripts" - property var title: "Running Scripts" + property string title: "Running Scripts" HifiConstants { id: hifi } signal sendToScript(var message); property var eventBridge; @@ -81,9 +81,9 @@ Rectangle { Flickable { id: flickable - width: parent.width + width: tabletRoot.width height: parent.height - (keyboard.raised ? keyboard.raisedHeight : 0) - contentWidth: parent.width + contentWidth: column.width contentHeight: column.childrenRect.height clip: true @@ -121,9 +121,8 @@ Rectangle { model: runningScriptsModel id: table height: 185 + width: parent.width colorScheme: hifi.colorSchemes.dark - anchors.left: parent.left - anchors.right: parent.right expandSelectedRow: true itemDelegate: Item { From aa487faad17d10b222e84b83011ffe43390f0088 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Tue, 4 Apr 2017 16:59:09 +0200 Subject: [PATCH 13/23] Fixed No such signal QmlWindow_QMLTYPE_490::resized(QSizeF) and No such signal QmlWindow_QMLTYPE_490::moved(QVector2D) warnings --- libraries/ui/src/QmlWindowClass.cpp | 7 +++++-- scripts/developer/debugging/debugWindow.qml | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/ui/src/QmlWindowClass.cpp b/libraries/ui/src/QmlWindowClass.cpp index c60e4fa698..c0e94058ae 100644 --- a/libraries/ui/src/QmlWindowClass.cpp +++ b/libraries/ui/src/QmlWindowClass.cpp @@ -122,12 +122,15 @@ void QmlWindowClass::initQml(QVariantMap properties) { object->setProperty(OFFSCREEN_VISIBILITY_PROPERTY, visible); object->setProperty(SOURCE_PROPERTY, _source); + const QMetaObject *metaObject = _qmlWindow->metaObject(); // Forward messages received from QML on to the script connect(_qmlWindow, SIGNAL(sendToScript(QVariant)), this, SLOT(qmlToScript(const QVariant&)), Qt::QueuedConnection); connect(_qmlWindow, SIGNAL(visibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection); - connect(_qmlWindow, SIGNAL(resized(QSizeF)), this, SIGNAL(resized(QSizeF)), Qt::QueuedConnection); - connect(_qmlWindow, SIGNAL(moved(QVector2D)), this, SLOT(hasMoved(QVector2D)), Qt::QueuedConnection); + if (metaObject->indexOfSignal("resized") >= 0) + connect(_qmlWindow, SIGNAL(resized(QSizeF)), this, SIGNAL(resized(QSizeF)), Qt::QueuedConnection); + if (metaObject->indexOfSignal("moved") >= 0) + connect(_qmlWindow, SIGNAL(moved(QVector2D)), this, SLOT(hasMoved(QVector2D)), Qt::QueuedConnection); connect(_qmlWindow, SIGNAL(windowClosed()), this, SLOT(hasClosed()), Qt::QueuedConnection); }); } diff --git a/scripts/developer/debugging/debugWindow.qml b/scripts/developer/debugging/debugWindow.qml index f046a949ef..20fa24358d 100644 --- a/scripts/developer/debugging/debugWindow.qml +++ b/scripts/developer/debugging/debugWindow.qml @@ -18,6 +18,9 @@ Rectangle { width: parent ? parent.width : 100 height: parent ? parent.height : 100 + signal moved(vector2d position); + signal resized(size size); + property var channel; TextArea { From b18d82bd1918d33a0cc1efe3842bf47706974cb0 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 4 Apr 2017 11:50:38 -0700 Subject: [PATCH 14/23] adding different shaders for transparent for simpel --- .../render-utils/src/RenderPipelines.cpp | 8 +++-- .../render-utils/src/simple_textured.slf | 6 ++-- .../src/simple_textured_unlit.slf | 20 ++++------- .../src/simple_transparent_textured.slf | 9 +++-- .../src/simple_transparent_textured_unlit.slf | 33 +++++++++++++++++++ 5 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 libraries/render-utils/src/simple_transparent_textured_unlit.slf diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index efbe09863b..c6a05e0d65 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -31,6 +31,8 @@ #include "simple_vert.h" #include "simple_textured_frag.h" #include "simple_textured_unlit_frag.h" +#include "simple_transparent_textured_frag.h" +#include "simple_transparent_textured_unlit_frag.h" #include "model_frag.h" #include "model_unlit_frag.h" @@ -152,6 +154,8 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { // Pixel shaders auto simplePixel = gpu::Shader::createPixel(std::string(simple_textured_frag)); auto simpleUnlitPixel = gpu::Shader::createPixel(std::string(simple_textured_unlit_frag)); + auto simpleTranslucentPixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_frag)); + auto simpleTranslucentUnlitPixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_unlit_frag)); auto modelPixel = gpu::Shader::createPixel(std::string(model_frag)); auto modelUnlitPixel = gpu::Shader::createPixel(std::string(model_unlit_frag)); auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag)); @@ -196,13 +200,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { modelVertex, modelTranslucentPixel); addPipeline( Key::Builder().withTranslucent(), - simpleVertex, simplePixel); + simpleVertex, simpleTranslucentPixel); addPipeline( Key::Builder().withMaterial().withTranslucent().withUnlit(), modelVertex, modelTranslucentUnlitPixel); addPipeline( Key::Builder().withTranslucent().withUnlit(), - simpleVertex, simpleUnlitPixel); + simpleVertex, simpleTranslucentUnlitPixel); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents(), modelNormalMapVertex, modelTranslucentPixel); diff --git a/libraries/render-utils/src/simple_textured.slf b/libraries/render-utils/src/simple_textured.slf index 6067c81a1b..550f6546fd 100644 --- a/libraries/render-utils/src/simple_textured.slf +++ b/libraries/render-utils/src/simple_textured.slf @@ -26,15 +26,17 @@ in vec2 _texCoord0; void main(void) { vec4 texel = texture(originalTexture, _texCoord0); + float colorAlpha = _color.a; if (_color.a <= 0.0) { texel = colorToLinearRGBA(texel); + colorAlpha = -_color.a; } const float ALPHA_THRESHOLD = 0.999; - if (_color.a * texel.a < ALPHA_THRESHOLD) { + if (colorAlpha * texel.a < ALPHA_THRESHOLD) { packDeferredFragmentTranslucent( normalize(_normal), - _color.a * texel.a, + colorAlpha * texel.a, _color.rgb * texel.rgb, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); diff --git a/libraries/render-utils/src/simple_textured_unlit.slf b/libraries/render-utils/src/simple_textured_unlit.slf index 1ee2011972..d261fb343a 100644 --- a/libraries/render-utils/src/simple_textured_unlit.slf +++ b/libraries/render-utils/src/simple_textured_unlit.slf @@ -25,28 +25,20 @@ in vec2 _texCoord0; void main(void) { vec4 texel = texture(originalTexture, _texCoord0.st); + float colorAlpha = _color.a; if (_color.a <= 0.0) { texel = colorToLinearRGBA(texel); + colorAlpha = -_color.a; } const float ALPHA_THRESHOLD = 0.999; - if (_color.a * texel.a < ALPHA_THRESHOLD) { - - _fragColor0 = vec4(_color.rgb * texel.rgb, _color.a * texel.a); - - if (_color.a * texel.a <= 0.0) { - _fragColor0 = vec4(_color.rgb * texel.rgb, _color.a * texel.a); - //discard; - } else { - _fragColor0 = vec4(_color.rgb * texel.rgb, _color.a * texel.a); - } - // _fragColor0 = vec4(albedo.rgb, alpha); - /* packDeferredFragmentTranslucent( + if (colorAlpha * texel.a < ALPHA_THRESHOLD) { + packDeferredFragmentTranslucent( normalize(_normal), - _color.a * texel.a, + colorAlpha * texel.a, _color.rgb * texel.rgb, DEFAULT_FRESNEL, - DEFAULT_ROUGHNESS);*/ + DEFAULT_ROUGHNESS); } else { packDeferredFragmentUnlit( normalize(_normal), diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf index 0fda804129..f61a2c3608 100644 --- a/libraries/render-utils/src/simple_transparent_textured.slf +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -26,10 +26,15 @@ in vec2 _texCoord0; void main(void) { vec4 texel = texture(originalTexture, _texCoord0.st); - texel = colorToLinearRGBA(texel); + float colorAlpha = _color.a; + if (_color.a <= 0.0) { + texel = colorToLinearRGBA(texel); + colorAlpha = -_color.a; + } + packDeferredFragmentTranslucent( normalize(_normal), - _color.a, + colorAlpha, _color.rgb * texel.rgb, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); diff --git a/libraries/render-utils/src/simple_transparent_textured_unlit.slf b/libraries/render-utils/src/simple_transparent_textured_unlit.slf new file mode 100644 index 0000000000..9ef3e6b82a --- /dev/null +++ b/libraries/render-utils/src/simple_transparent_textured_unlit.slf @@ -0,0 +1,33 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple_transparent_textured_unlit.slf +// fragment shader +// +// Created by Sam Gateau on 4/3/17. +// 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 gpu/Color.slh@> + +// the albedo texture +uniform sampler2D originalTexture; + +// the interpolated normal +in vec3 _normal; +in vec4 _color; +in vec2 _texCoord0; + +void main(void) { + vec4 texel = texture(originalTexture, _texCoord0.st); + float colorAlpha = _color.a; + if (_color.a <= 0.0) { + texel = colorToLinearRGBA(texel); + colorAlpha = -_color.a; + } + _fragColor0 = vec4(_color.rgb * texel.rgb, colorAlpha * texel.a); +} \ No newline at end of file From 6385a702cdefe23dfd9523636c12065fabe3fdec Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 4 Apr 2017 12:56:43 -0700 Subject: [PATCH 15/23] FIxing the bug for image3D overlay drawn in scene --- .../render-utils/src/RenderPipelines.cpp | 4 +- .../src/simple_transparent_textured.slf | 37 +++++++++++++++---- .../src/simple_transparent_textured_unlit.slf | 3 ++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index c6a05e0d65..da264cbf7d 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -178,13 +178,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { modelVertex, modelPixel); addPipeline( Key::Builder(), - modelVertex, simplePixel); + simpleVertex, simplePixel); addPipeline( Key::Builder().withMaterial().withUnlit(), modelVertex, modelUnlitPixel); addPipeline( Key::Builder().withUnlit(), - modelVertex, simpleUnlitPixel); + simpleVertex, simpleUnlitPixel); addPipeline( Key::Builder().withMaterial().withTangents(), modelNormalMapVertex, modelNormalMapPixel); diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf index f61a2c3608..b9eb921e9d 100644 --- a/libraries/render-utils/src/simple_transparent_textured.slf +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -13,29 +13,50 @@ // <@include gpu/Color.slh@> + <@include DeferredBufferWrite.slh@> -<@include model/Material.slh@> +<@include DeferredGlobalLight.slh@> +<$declareEvalGlobalLightingAlphaBlended()$> + +<@include gpu/Transform.slh@> +<$declareStandardCameraTransform()$> // the albedo texture uniform sampler2D originalTexture; // the interpolated normal +in vec4 _position; in vec3 _normal; in vec4 _color; in vec2 _texCoord0; void main(void) { vec4 texel = texture(originalTexture, _texCoord0.st); - float colorAlpha = _color.a; + float opacity = _color.a; if (_color.a <= 0.0) { texel = colorToLinearRGBA(texel); - colorAlpha = -_color.a; + opacity = -_color.a; } + opacity *= texel.a; + vec3 albedo = _color.rgb * texel.rgb; - packDeferredFragmentTranslucent( - normalize(_normal), - colorAlpha, - _color.rgb * texel.rgb, + vec3 fragPosition = _position.xyz; + vec3 fragNormal = normalize(_normal); + + TransformCamera cam = getTransformCamera(); + + _fragColor0 = vec4(evalGlobalLightingAlphaBlended( + cam._viewInverse, + 1.0, + 1.0, + fragPosition, + fragNormal, + albedo, DEFAULT_FRESNEL, - DEFAULT_ROUGHNESS); + 0.0, + vec3(0.0f), + DEFAULT_ROUGHNESS, + opacity), + opacity); + } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent_textured_unlit.slf b/libraries/render-utils/src/simple_transparent_textured_unlit.slf index 9ef3e6b82a..693d7be2db 100644 --- a/libraries/render-utils/src/simple_transparent_textured_unlit.slf +++ b/libraries/render-utils/src/simple_transparent_textured_unlit.slf @@ -22,6 +22,9 @@ in vec3 _normal; in vec4 _color; in vec2 _texCoord0; + +layout(location = 0) out vec4 _fragColor0; + void main(void) { vec4 texel = texture(originalTexture, _texCoord0.st); float colorAlpha = _color.a; From c33f10ca1be5f79f1657fa5754379ecb80c3e82b Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 4 Apr 2017 18:05:46 -0700 Subject: [PATCH 16/23] Recenter body on teleport, also it works more consistently. If your avatar happens to be squatting, your body will stand up straight after you teleport. Also, setting MyAvatar.position can sometimes fail due to the multi-threaded nature of scripting. Instead, teleport.js uses goToPosition to move the avatar, as a result teleport feels much more responsive now. --- scripts/system/controllers/teleport.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/system/controllers/teleport.js b/scripts/system/controllers/teleport.js index 90f8ccb368..33c0b3116e 100644 --- a/scripts/system/controllers/teleport.js +++ b/scripts/system/controllers/teleport.js @@ -297,8 +297,9 @@ function Teleporter() { } else if (teleportLocationType === TARGET.SURFACE) { var offset = getAvatarFootOffset(); intersection.intersection.y += offset; - MyAvatar.position = intersection.intersection; + MyAvatar.goToLocation(intersection.intersection, false, {x: 0, y: 0, z: 0, w: 1}, false); HMD.centerUI(); + MyAvatar.centerBody(); } } }; From 1b6bf90843efaa7171e1bff64bae5471678d12f4 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Wed, 5 Apr 2017 11:10:06 -0700 Subject: [PATCH 17/23] initial analytics for connections --- .../src/UserActivityLoggerScriptingInterface.cpp | 10 ++++++++++ .../src/UserActivityLoggerScriptingInterface.h | 1 + scripts/system/makeUserConnection.js | 3 +++ 3 files changed, 14 insertions(+) diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp index c8a7b61aa7..9c29e87f16 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.cpp @@ -61,6 +61,16 @@ void UserActivityLoggerScriptingInterface::palOpened(float secondsOpened) { }); } +void UserActivityLoggerScriptingInterface::makeUserConnection(QString otherID, bool success, QString detailsString) { + QJsonObject payload; + payload["otherUser"] = otherID; + payload["success"] = success; + if (detailsString.length() > 0) { + payload["details"] = detailsString; + } + logAction("makeUserConnection", payload); +} + void UserActivityLoggerScriptingInterface::logAction(QString action, QJsonObject details) { QMetaObject::invokeMethod(&UserActivityLogger::getInstance(), "logAction", Q_ARG(QString, action), diff --git a/libraries/networking/src/UserActivityLoggerScriptingInterface.h b/libraries/networking/src/UserActivityLoggerScriptingInterface.h index cf38450891..b68c7beb95 100644 --- a/libraries/networking/src/UserActivityLoggerScriptingInterface.h +++ b/libraries/networking/src/UserActivityLoggerScriptingInterface.h @@ -29,6 +29,7 @@ public: float tutorialElapsedTime, QString tutorialRunID = "", int tutorialVersion = 0, QString controllerType = ""); Q_INVOKABLE void palAction(QString action, QString target); Q_INVOKABLE void palOpened(float secondsOpen); + Q_INVOKABLE void makeUserConnection(QString otherUser, bool success, QString details=""); private: void logAction(QString action, QJsonObject details = {}); }; diff --git a/scripts/system/makeUserConnection.js b/scripts/system/makeUserConnection.js index e70e0a2ea2..0a781a5bb8 100644 --- a/scripts/system/makeUserConnection.js +++ b/scripts/system/makeUserConnection.js @@ -543,12 +543,14 @@ function connectionRequestCompleted() { // Final result is in. Do effects. // don't change state (so animation continues while gripped) // but do send a notification, by calling the slot that emits the signal for it Window.makeConnection(true, result.connection.new_connection ? "You and " + result.connection.username + " are now connected!" : result.connection.username); + UserActivityLogger.makeUserConnection(connectingId, true, result.connection.new_connection ? "new connection" : "already connected"); return; } // failed endHandshake(); debug("failing with result data", result); // IWBNI we also did some fail sound/visual effect. Window.makeConnection(false, result.connection); + UserActivityLogger.makeUserConnection(connectingId, false, result.connection); } var POLL_INTERVAL_MS = 200, POLL_LIMIT = 5; function handleConnectionResponseAndMaybeRepeat(error, response) { @@ -573,6 +575,7 @@ function handleConnectionResponseAndMaybeRepeat(error, response) { } else if (error || (response.status !== 'success')) { debug('server fail', error, response.status); result = error ? {status: 'error', connection: error} : response; + UserActivityLogger.makeUserConnection(connectingId, false, error || response); connectionRequestCompleted(); } else { debug('server success', result); From 61ece265f4b43c4d2cd994acc124e17db878c23c Mon Sep 17 00:00:00 2001 From: David Kelly Date: Wed, 5 Apr 2017 18:16:16 -0700 Subject: [PATCH 18/23] now you can forget connections --- interface/resources/qml/hifi/NameCard.qml | 96 ++++++++++++++++++++++- interface/resources/qml/hifi/Pal.qml | 7 +- scripts/system/pal.js | 15 ++++ 3 files changed, 112 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index 86cc0218a4..a298540d39 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -14,6 +14,7 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtGraphicalEffects 1.0 import "../styles-uit" +import "../controls-uit" as HifiControls import "toolbars" // references Users, UserActivityLogger, MyAvatar, Vec3, Quat, AddressManager from root context @@ -42,6 +43,7 @@ Item { property bool selected: false property bool isAdmin: false property bool isPresent: true + property string placeName: "" property string profilePicBorderColor: (connectionStatus == "connection" ? hifi.colors.indigoAccent : (connectionStatus == "friend" ? hifi.colors.greenHighlight : "transparent")) Item { @@ -316,9 +318,10 @@ Item { visible: thisNameCard.userName !== ""; // Size width: parent.width - height: pal.activeTab == "nearbyTab" || isMyCard ? usernameTextPixelSize + 4 : parent.height; + height: usernameTextPixelSize + 4 // Anchors - anchors.top: isMyCard ? myDisplayName.bottom : (pal.activeTab == "nearbyTab" ? displayNameContainer.bottom : parent.top); + anchors.top: isMyCard ? myDisplayName.bottom : pal.activeTab == "nearbyTab" ? displayNameContainer.bottom : undefined //(parent.height - displayNameTextPixelSize/2)); + anchors.verticalCenter: pal.activeTab == "connectionsTab" ? avatarImage.verticalCenter : undefined anchors.left: avatarImage.right; anchors.leftMargin: avatarImage.visible ? 5 : 0; anchors.rightMargin: 5; @@ -346,6 +349,93 @@ Item { } } } + StateImage { + id: nameCardConnectionInfoImage + visible: selected && !isMyCard && pal.activeTab == "connectionsTab" + imageURL: "../../images/info-icon-2-state.svg" // PLACEHOLDER!!! + size: 32; + buttonState: 0; + anchors.left: avatarImage.right + anchors.bottom: parent.bottom + } + MouseArea { + anchors.fill:nameCardConnectionInfoImage + enabled: selected + hoverEnabled: true + onClicked: { + userInfoViewer.url = defaultBaseUrl + "/users/" + userName; + userInfoViewer.visible = true; + } + onEntered: { + nameCardConnectionInfoImage.buttonState = 1; + } + onExited: { + nameCardConnectionInfoImage.buttonState = 0; + } + } + FiraSansRegular { + id: nameCardConnectionInfoText + visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard + width: parent.width + height: displayNameTextPixelSize + size: displayNameTextPixelSize - 4 + anchors.left: nameCardConnectionInfoImage.right + anchors.verticalCenter: nameCardConnectionInfoImage.verticalCenter + anchors.leftMargin: 5 + verticalAlignment: Text.AlignVCenter + text: "Info" + color: hifi.colors.baseGray + } + StateImage { + id: nameCardRemoveConnectionImage + visible: selected && !isMyCard && pal.activeTab == "connectionsTab" + imageURL: "../../images/info-icon-2-state.svg" // PLACEHOLDER!!! + size: 32; + buttonState: 0; + x: 120 + anchors.bottom: parent.bottom + } + MouseArea { + anchors.fill:nameCardRemoveConnectionImage + enabled: selected + hoverEnabled: true + onClicked: { + // send message to pal.js to forgetConnection + pal.sendToScript({method: 'removeConnection', params: thisNameCard.userName}); + } + onEntered: { + nameCardRemoveConnectionImage.buttonState = 1; + } + onExited: { + nameCardRemoveConnectionImage.buttonState = 0; + } + } + FiraSansRegular { + id: nameCardRemoveConnectionText + visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard + width: parent.width + height: displayNameTextPixelSize + size: displayNameTextPixelSize - 4 + anchors.left: nameCardRemoveConnectionImage.right + anchors.verticalCenter: nameCardRemoveConnectionImage.verticalCenter + anchors.leftMargin: 5 + verticalAlignment: Text.AlignVCenter + text: "Forget" + color: hifi.colors.baseGray + } + HifiControls.Button { + id: visitConnectionButton + visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard + text: "Visit" + enabled: thisNameCard.placeName !== "" + anchors.verticalCenter: nameCardRemoveConnectionImage.verticalCenter + x: 240 + onClicked: { + AddressManager.goToUser(thisNameCard.userName); + UserActivityLogger.palAction("go_to_user", thisNameCard.userName); + } + } + // VU Meter Rectangle { id: nameCardVUMeter @@ -484,7 +574,7 @@ Item { } } } - + function updateGainFromQML(avatarUuid, sliderValue, isReleased) { Users.setAvatarGain(avatarUuid, sliderValue); if (isReleased) { diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 66803621ec..b7e11e97e6 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -763,7 +763,7 @@ Rectangle { // This Rectangle refers to each Row in the connectionsTable. rowDelegate: Rectangle { // Size - height: rowHeight; + height: rowHeight + (styleData.selected ? 15 : 0); color: rowColor(styleData.selected, styleData.alternate); } @@ -779,6 +779,7 @@ Rectangle { profileUrl: (model && model.profileUrl) || ""; displayName: ""; userName: model ? model.userName : ""; + placeName: model ? model.placeName : "" connectionStatus : model ? model.connection : ""; selected: styleData.selected; // Size @@ -792,7 +793,7 @@ Rectangle { FiraSansRegular { id: connectionsLocationData // Properties - visible: styleData.role === "placeName"; + visible: !connectionsNameCard.selected && styleData.role === "placeName"; text: (model && model.placeName) || ""; elide: Text.ElideRight; // Size @@ -822,7 +823,7 @@ Rectangle { // "Friends" checkbox HifiControlsUit.CheckBox { id: friendsCheckBox; - visible: styleData.role === "friends" && model.userName !== myData.userName; + visible: styleData.role === "friends" && model && model.userName !== myData.userName; anchors.centerIn: parent; checked: model ? (model["connection"] === "friend" ? true : false) : false; boxSize: 24; diff --git a/scripts/system/pal.js b/scripts/system/pal.js index b39c993894..263ee444cc 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -269,6 +269,21 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See getConnectionData(); UserActivityLogger.palAction("refresh_connections", ""); break; + case 'removeConnection': + connectionUserName = message.params; + request({ + uri: METAVERSE_BASE + '/api/v1/user/connections/' + connectionUserName, + method: 'DELETE' + }, function (error, response) { + print(JSON.stringify(response)); + if (error || (response.status !== 'success')) { + print("Error: unable to remove connection", connectionUserName, error || response.status); + return; + } + getConnectionData(); + }); + break + case 'removeFriend': friendUserName = message.params; request({ From 06bd9c97bf160e45d29414b54016e47f6f172414 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Wed, 5 Apr 2017 18:21:54 -0700 Subject: [PATCH 19/23] remove info button from avatar image --- interface/resources/qml/hifi/NameCard.qml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index a298540d39..679920dc1c 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -81,25 +81,6 @@ Item { anchors.fill: parent; visible: userImage.status != Image.Ready; } - StateImage { - id: infoHoverImage; - visible: false; - imageURL: "../../images/info-icon-2-state.svg"; - size: 32; - buttonState: 1; - anchors.centerIn: parent; - } - MouseArea { - anchors.fill: parent - enabled: selected || isMyCard; - hoverEnabled: enabled - onClicked: { - userInfoViewer.url = defaultBaseUrl + "/users/" + userName; - userInfoViewer.visible = true; - } - onEntered: infoHoverImage.visible = true; - onExited: infoHoverImage.visible = false; - } } // Colored border around avatarImage From a92162dea9f8ba90af6ad755840f8be699ca95ff Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 6 Apr 2017 08:50:22 -0700 Subject: [PATCH 20/23] no mo useless debug statements --- scripts/system/pal.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 263ee444cc..5fbea90025 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -275,7 +275,6 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See uri: METAVERSE_BASE + '/api/v1/user/connections/' + connectionUserName, method: 'DELETE' }, function (error, response) { - print(JSON.stringify(response)); if (error || (response.status !== 'success')) { print("Error: unable to remove connection", connectionUserName, error || response.status); return; @@ -290,7 +289,6 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See uri: METAVERSE_BASE + '/api/v1/user/friends/' + friendUserName, method: 'DELETE' }, function (error, response) { - print(JSON.stringify(response)); if (error || (response.status !== 'success')) { print("Error: unable to unfriend", friendUserName, error || response.status); return; From 16fa7988f6d7adcccaceef913419edf1031780b7 Mon Sep 17 00:00:00 2001 From: Vladyslav Stelmakhovskyi Date: Thu, 6 Apr 2017 17:53:46 +0200 Subject: [PATCH 21/23] TabletWebView redesigned to single WebView instance --- interface/resources/qml/TabletBrowser.qml | 193 ++++++--------- .../resources/qml/controls/TabletWebView.qml | 226 ++++++------------ 2 files changed, 154 insertions(+), 265 deletions(-) diff --git a/interface/resources/qml/TabletBrowser.qml b/interface/resources/qml/TabletBrowser.qml index 85fff59207..2650102b27 100644 --- a/interface/resources/qml/TabletBrowser.qml +++ b/interface/resources/qml/TabletBrowser.qml @@ -1,5 +1,5 @@ import QtQuick 2.5 -import QtQuick.Controls 1.2 +import QtQuick.Controls 1.4 import QtWebChannel 1.0 import QtWebEngine 1.2 @@ -7,7 +7,7 @@ import "controls" import "styles" as HifiStyles import "styles-uit" import "windows" -import HFWebEngineProfile 1.0 +import HFTabletWebEngineProfile 1.0 Item { id: root @@ -27,138 +27,103 @@ Item { x: 0 y: 0 - - function goBack() { - webview.goBack(); - } - - function goForward() { - webview.goForward(); - } - - function gotoPage(url) { - webview.url = url; - } function setProfile(profile) { webview.profile = profile; } - function reloadPage() { - webview.reloadAndBypassCache(); - webview.setActiveFocusOnPress(true); - webview.setEnabled(true); + QtObject { + id: eventBridgeWrapper + WebChannel.id: "eventBridgeWrapper" + property var eventBridge; } - Item { - id:item + WebEngineView { + id: webview + objectName: "webEngineView" + x: 0 + y: 0 width: parent.width - implicitHeight: parent.height + height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - - QtObject { - id: eventBridgeWrapper - WebChannel.id: "eventBridgeWrapper" - property var eventBridge; + profile: HFTabletWebEngineProfile { + id: webviewTabletProfile + storageName: "qmlTabletWebEngine" } - WebEngineView { - id: webview - objectName: "webEngineView" - x: 0 - y: 0 - width: parent.width - height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - - profile: HFWebEngineProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } + property string userScriptUrl: "" - property string userScriptUrl: "" - - // creates a global EventBridge object. - WebEngineScript { - id: createGlobalEventBridge - sourceCode: eventBridgeJavaScriptToInject - injectionPoint: WebEngineScript.DocumentCreation - worldId: WebEngineScript.MainWorld - } - - // detects when to raise and lower virtual keyboard - WebEngineScript { - id: raiseAndLowerKeyboard - injectionPoint: WebEngineScript.Deferred - sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js" - worldId: WebEngineScript.MainWorld - } - - // User script. - WebEngineScript { - id: userScript - sourceUrl: webview.userScriptUrl - injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. - worldId: WebEngineScript.MainWorld - } + // creates a global EventBridge object. + WebEngineScript { + id: createGlobalEventBridge + sourceCode: eventBridgeJavaScriptToInject + injectionPoint: WebEngineScript.DocumentCreation + worldId: WebEngineScript.MainWorld + } - userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] - - property string newUrl: "" - - webChannel.registeredObjects: [eventBridgeWrapper] + // detects when to raise and lower virtual keyboard + WebEngineScript { + id: raiseAndLowerKeyboard + injectionPoint: WebEngineScript.Deferred + sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js" + worldId: WebEngineScript.MainWorld + } - Component.onCompleted: { - // Ensure the JS from the web-engine makes it to our logging - webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { - console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); - }); - - webview.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface"; - web.address = url; - } - - onFeaturePermissionRequested: { - grantFeaturePermission(securityOrigin, feature, true); - } + // User script. + WebEngineScript { + id: userScript + sourceUrl: webview.userScriptUrl + injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. + worldId: WebEngineScript.MainWorld + } - onLoadingChanged: { - keyboardRaised = false; - punctuationMode = false; - keyboard.resetShiftMode(false); - - // Required to support clicking on "hifi://" links - if (WebEngineView.LoadStartedStatus == loadRequest.status) { - var url = loadRequest.url.toString(); - if (urlHandler.canHandleUrl(url)) { - if (urlHandler.handleUrl(url)) { - root.stop(); - } + userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] + + property string newUrl: "" + + webChannel.registeredObjects: [eventBridgeWrapper] + + Component.onCompleted: { + // Ensure the JS from the web-engine makes it to our logging + webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { + console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); + }); + + webview.profile.httpUserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"; + web.address = url; + } + + onFeaturePermissionRequested: { + grantFeaturePermission(securityOrigin, feature, true); + } + + onLoadingChanged: { + keyboardRaised = false; + punctuationMode = false; + keyboard.resetShiftMode(false); + + // Required to support clicking on "hifi://" links + if (WebEngineView.LoadStartedStatus == loadRequest.status) { + var url = loadRequest.url.toString(); + if (urlHandler.canHandleUrl(url)) { + if (urlHandler.handleUrl(url)) { + root.stop(); } } } + } - onNewViewRequested: { - var component = Qt.createComponent("./TabletBrowser.qml"); - - if (component.status != Component.Ready) { - if (component.status == Component.Error) { - console.log("Error: " + component.errorString()); - } - return; - } - var newWindow = component.createObject(); - newWindow.setProfile(webview.profile); - request.openIn(newWindow.webView); - newWindow.eventBridge = web.eventBridge; - stackRoot.push(newWindow); - newWindow.webView.forceActiveFocus(); - + onNavigationRequested: { + if (request.navigationType == WebEngineNavigationRequest.LinkClickedNavigation) { + pagesModel.append({webUrl: request.url.toString()}) } } - - } // item - - + + onNewViewRequested: { + request.openIn(webView); + } + } + Keys.onPressed: { switch(event.key) { case Qt.Key_L: @@ -171,4 +136,4 @@ Item { } } - } // dialog +} diff --git a/interface/resources/qml/controls/TabletWebView.qml b/interface/resources/qml/controls/TabletWebView.qml index 742ab2d333..50d6e1c504 100644 --- a/interface/resources/qml/controls/TabletWebView.qml +++ b/interface/resources/qml/controls/TabletWebView.qml @@ -1,6 +1,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 -import QtWebEngine 1.1 +import QtWebEngine 1.2 import QtWebChannel 1.0 import "../controls-uit" as HiFiControls import "../styles" as HifiStyles @@ -14,17 +14,20 @@ Item { height: parent.height property var parentStackItem: null property int headerHeight: 38 - property alias url: root.url - property string address: url - property alias scriptURL: root.userScriptUrl + property string url + property string address: url //for compatibility + property string scriptURL property alias eventBridge: eventBridgeWrapper.eventBridge property bool keyboardEnabled: HMD.active property bool keyboardRaised: false property bool punctuationMode: false property bool isDesktop: false - property WebEngineView view: root + property WebEngineView view: loader.currentView + property int currentPage: -1 // used as a model for repeater + property alias pagesModel: pagesModel + Row { id: buttons HifiConstants { id: hifi } @@ -37,29 +40,29 @@ Item { anchors.leftMargin: 8 HiFiGlyphs { id: back; - enabled: true; + enabled: currentPage > 0 text: hifi.glyphs.backward color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText size: 48 - MouseArea { anchors.fill: parent; onClicked: stackRoot.goBack() } + MouseArea { anchors.fill: parent; onClicked: goBack() } } HiFiGlyphs { id: forward; - enabled: stackRoot.currentItem.canGoForward; + enabled: currentPage < pagesModel.count - 1 text: hifi.glyphs.forward color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText size: 48 - MouseArea { anchors.fill: parent; onClicked: stackRoot.currentItem.goForward() } + MouseArea { anchors.fill: parent; onClicked: goForward() } } HiFiGlyphs { id: reload; - enabled: true; - text: webview.loading ? hifi.glyphs.close : hifi.glyphs.reload + enabled: view != null; + text: (view !== null && view.loading) ? hifi.glyphs.close : hifi.glyphs.reload color: enabled ? hifistyles.colors.text : hifistyles.colors.disabledText size: 48 - MouseArea { anchors.fill: parent; onClicked: stackRoot.currentItem.reloadPage(); } + MouseArea { anchors.fill: parent; onClicked: reloadPage(); } } } @@ -86,7 +89,7 @@ Item { } //root.hidePermissionsBar(); web.keyboardRaised = false; - stackRoot.currentItem.gotoPage(text); + gotoPage(text); break; @@ -94,157 +97,78 @@ Item { } } + ListModel { + id: pagesModel + onCountChanged: { + currentPage = count - 1 + } + } + function goBack() { + if (currentPage > 0) { + currentPage--; + } + } + + function goForward() { + if (currentPage < pagesModel.count - 1) { + currentPage++; + } + } + + function gotoPage(url) { + pagesModel.append({webUrl: url}) + } + + function reloadPage() { + view.reloadAndBypassCache() + view.setActiveFocusOnPress(true); + view.setEnabled(true); + } + + onCurrentPageChanged: { + if (currentPage >= 0 && currentPage < pagesModel.count && loader.item !== null) { + loader.item.url = pagesModel.get(currentPage).webUrl + } + } + + onUrlChanged: { + gotoPage(url) + } + + QtObject { + id: eventBridgeWrapper + WebChannel.id: "eventBridgeWrapper" + property var eventBridge; + } + + Loader { + id: loader + + property WebEngineView currentView: null - StackView { - id: stackRoot width: parent.width height: parent.height - web.headerHeight + asynchronous: true anchors.top: buttons.bottom - //property var goBack: currentItem.goBack(); - property WebEngineView view: root - - initialItem: root; - - function goBack() { - if (depth > 1 ) { - if (currentItem.canGoBack) { - currentItem.goBack(); - } else { - stackRoot.pop(); - currentItem.webView.focus = true; - currentItem.webView.forceActiveFocus(); - web.address = currentItem.webView.url; - } - } else { - if (currentItem.canGoBack) { - currentItem.goBack(); - } else if (parentStackItem) { - web.parentStackItem.pop(); + active: false + source: "../TabletBrowser.qml" + onStatusChanged: { + if (loader.status === Loader.Ready) { + currentView = item.webView + item.webView.userScriptUrl = web.scriptURL + if (currentPage >= 0) { + //we got something to load already + item.url = pagesModel.get(currentPage).webUrl } } } - - QtObject { - id: eventBridgeWrapper - WebChannel.id: "eventBridgeWrapper" - property var eventBridge; - } - - WebEngineView { - id: root - objectName: "webEngineView" - x: 0 - y: 0 - width: parent.width - height: keyboardEnabled && keyboardRaised ? (parent.height - keyboard.height) : parent.height - profile: HFTabletWebEngineProfile { - id: webviewTabletProfile - storageName: "qmlTabletWebEngine" - } - - property WebEngineView webView: root - function reloadPage() { - root.reload(); - } - - function gotoPage(url) { - root.url = url; - } - - property string userScriptUrl: "" - - // creates a global EventBridge object. - WebEngineScript { - id: createGlobalEventBridge - sourceCode: eventBridgeJavaScriptToInject - injectionPoint: WebEngineScript.DocumentCreation - worldId: WebEngineScript.MainWorld - } - - // detects when to raise and lower virtual keyboard - WebEngineScript { - id: raiseAndLowerKeyboard - injectionPoint: WebEngineScript.Deferred - sourceUrl: resourceDirectoryUrl + "/html/raiseAndLowerKeyboard.js" - worldId: WebEngineScript.MainWorld - } - - // User script. - WebEngineScript { - id: userScript - sourceUrl: root.userScriptUrl - injectionPoint: WebEngineScript.DocumentReady // DOM ready but page load may not be finished. - worldId: WebEngineScript.MainWorld - } - - userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] - - property string newUrl: "" - - webChannel.registeredObjects: [eventBridgeWrapper] - - Component.onCompleted: { - // Ensure the JS from the web-engine makes it to our logging - root.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { - console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); - }); - - root.profile.httpUserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36" - - } - - onFeaturePermissionRequested: { - grantFeaturePermission(securityOrigin, feature, true); - } - - onLoadingChanged: { - keyboardRaised = false; - punctuationMode = false; - keyboard.resetShiftMode(false); - // Required to support clicking on "hifi://" links - if (WebEngineView.LoadStartedStatus == loadRequest.status) { - var url = loadRequest.url.toString(); - if (urlHandler.canHandleUrl(url)) { - if (urlHandler.handleUrl(url)) { - root.stop(); - } - } - } - } - - onNewViewRequested:{ - var component = Qt.createComponent("../TabletBrowser.qml"); - if (component.status != Component.Ready) { - if (component.status == Component.Error) { - console.log("Error: " + component.errorString()); - } - return; - } - var newWindow = component.createObject(); - newWindow.setProfile(root.profile); - request.openIn(newWindow.webView); - newWindow.eventBridge = web.eventBridge; - stackRoot.push(newWindow); - } - } - - HiFiControls.Keyboard { - id: keyboard - raised: web.keyboardEnabled && web.keyboardRaised - numeric: web.punctuationMode - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - } - } - } Component.onCompleted: { web.isDesktop = (typeof desktop !== "undefined"); address = url; + loader.active = true } Keys.onPressed: { From 85c78da83959fb3381776158f3b0ac8502f036a7 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 6 Apr 2017 11:16:51 -0700 Subject: [PATCH 22/23] updated, plus fixed some annoying errors in logs from Pal.qml --- interface/resources/qml/hifi/NameCard.qml | 15 +++++++-------- interface/resources/qml/hifi/Pal.qml | 19 +++++++++++++------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index 679920dc1c..3343cec26f 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -45,7 +45,7 @@ Item { property bool isPresent: true property string placeName: "" property string profilePicBorderColor: (connectionStatus == "connection" ? hifi.colors.indigoAccent : (connectionStatus == "friend" ? hifi.colors.greenHighlight : "transparent")) - + property alias avImage: avatarImage Item { id: avatarImage visible: profileUrl !== "" && userName !== ""; @@ -367,14 +367,13 @@ Item { text: "Info" color: hifi.colors.baseGray } - StateImage { + HiFiGlyphs { id: nameCardRemoveConnectionImage visible: selected && !isMyCard && pal.activeTab == "connectionsTab" - imageURL: "../../images/info-icon-2-state.svg" // PLACEHOLDER!!! - size: 32; - buttonState: 0; + text: hifi.glyphs.close + size: 28; x: 120 - anchors.bottom: parent.bottom + anchors.verticalCenter: nameCardConnectionInfoImage.verticalCenter } MouseArea { anchors.fill:nameCardRemoveConnectionImage @@ -385,10 +384,10 @@ Item { pal.sendToScript({method: 'removeConnection', params: thisNameCard.userName}); } onEntered: { - nameCardRemoveConnectionImage.buttonState = 1; + nameCardRemoveConnectionImage.text = hifi.glyphs.closeInverted; } onExited: { - nameCardRemoveConnectionImage.buttonState = 0; + nameCardRemoveConnectionImage.text = hifi.glyphs.close; } } FiraSansRegular { diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index b7e11e97e6..a3d555f817 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -793,17 +793,21 @@ Rectangle { FiraSansRegular { id: connectionsLocationData // Properties - visible: !connectionsNameCard.selected && styleData.role === "placeName"; + visible: styleData.role === "placeName"; text: (model && model.placeName) || ""; elide: Text.ElideRight; // Size width: parent.width; - // Anchors - anchors.fill: parent; + // you would think that this would work: + // anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter + // but no! you cannot anchor to a non-sibling or parent. So I will + // align with the friends checkbox, where I did the manual alignment + anchors.verticalCenter: friendsCheckBox.verticalCenter // Text Size size: 16; // Text Positioning verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter // Style color: hifi.colors.blueAccent; font.underline: true; @@ -824,7 +828,11 @@ Rectangle { HifiControlsUit.CheckBox { id: friendsCheckBox; visible: styleData.role === "friends" && model && model.userName !== myData.userName; - anchors.centerIn: parent; + // you would think that this would work: + // anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter + // but no! you cannot anchor to a non-sibling or parent. So: + x: parent.width/2 - boxSize/2 + y: connectionsNameCard.avImage.y + connectionsNameCard.avImage.height/2 - boxSize/2 checked: model ? (model["connection"] === "friend" ? true : false) : false; boxSize: 24; onClicked: { @@ -902,7 +910,7 @@ Rectangle { wrapMode: Text.WordWrap textFormat: Text.StyledText; // Text - text: HMD.active ? + text: HMD.isMounted ? "When you meet someone you want to remember later, you can connect with a handshake:

" + "1. Put your hand out onto their hand and squeeze your controller's grip button on its side.
" + "2. Once the other person puts their hand onto yours, you'll see your connection form.
" + @@ -961,7 +969,6 @@ Rectangle { // Text size size: hifi.fontSizes.tabularData; // Anchors - anchors.top: myCard.top; anchors.left: parent.left; // Style color: hifi.colors.baseGrayHighlight; From 1d60a55d5f0b7d8262db0316333f18bf27b99b98 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 6 Apr 2017 11:20:08 -0700 Subject: [PATCH 23/23] notice login/logout change in pal --- interface/resources/qml/hifi/Pal.qml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index 66803621ec..50fba660d8 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -52,6 +52,13 @@ Rectangle { id: letterboxMessage; z: 999; // Force the popup on top of everything else } + Connections { + target: GlobalServices + onMyUsernameChanged: { + myData.userName = Account.username; + myDataChanged(); // Setting a property within an object isn't enough to update dependencies. This will do it. + } + } // The ComboDialog used for setting availability ComboDialog { id: comboDialog;