diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml
index 86cc0218a4..3343cec26f 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,8 +43,9 @@ 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"))
-
+ property alias avImage: avatarImage
Item {
id: avatarImage
visible: profileUrl !== "" && userName !== "";
@@ -79,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
@@ -316,9 +299,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 +330,92 @@ 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
+ }
+ HiFiGlyphs {
+ id: nameCardRemoveConnectionImage
+ visible: selected && !isMyCard && pal.activeTab == "connectionsTab"
+ text: hifi.glyphs.close
+ size: 28;
+ x: 120
+ anchors.verticalCenter: nameCardConnectionInfoImage.verticalCenter
+ }
+ 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.text = hifi.glyphs.closeInverted;
+ }
+ onExited: {
+ nameCardRemoveConnectionImage.text = hifi.glyphs.close;
+ }
+ }
+ 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 +554,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 2f10f0fdf5..d8566bb28e 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;
@@ -763,7 +770,7 @@ Rectangle {
// This Rectangle refers to each Row in the connectionsTable.
rowDelegate: Rectangle {
// Size
- height: rowHeight;
+ height: rowHeight + (styleData.selected ? 15 : 0);
color: connectionsRowColor(styleData.selected, styleData.alternate);
}
@@ -779,6 +786,7 @@ Rectangle {
profileUrl: (model && model.profileUrl) || "";
displayName: "";
userName: model ? model.userName : "";
+ placeName: model ? model.placeName : ""
connectionStatus : model ? model.connection : "";
selected: styleData.selected;
// Size
@@ -797,12 +805,16 @@ Rectangle {
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;
@@ -822,8 +834,12 @@ Rectangle {
// "Friends" checkbox
HifiControlsUit.CheckBox {
id: friendsCheckBox;
- visible: styleData.role === "friends" && model.userName !== myData.userName;
- anchors.centerIn: parent;
+ visible: styleData.role === "friends" && model && model.userName !== myData.userName;
+ // 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: {
@@ -901,7 +917,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.
" +
@@ -960,7 +976,6 @@ Rectangle {
// Text size
size: hifi.fontSizes.tabularData;
// Anchors
- anchors.top: myCard.top;
anchors.left: parent.left;
// Style
color: hifi.colors.baseGrayHighlight;
diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp
index 9e6c18bb96..3bbd26e010 100644
--- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp
+++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp
@@ -278,11 +278,9 @@ void OffscreenQmlSurface::cleanup() {
}
void OffscreenQmlSurface::render() {
-
#ifdef HIFI_ENABLE_NSIGHT_DEBUG
return;
#endif
-
if (_paused) {
return;
}
diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp
index 414bcf0d63..da264cbf7d 100644
--- a/libraries/render-utils/src/RenderPipelines.cpp
+++ b/libraries/render-utils/src/RenderPipelines.cpp
@@ -28,6 +28,12 @@
#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 "simple_transparent_textured_frag.h"
+#include "simple_transparent_textured_unlit_frag.h"
+
#include "model_frag.h"
#include "model_unlit_frag.h"
#include "model_shadow_frag.h"
@@ -135,6 +141,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 +152,10 @@ 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 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));
@@ -167,13 +178,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
modelVertex, modelPixel);
addPipeline(
Key::Builder(),
- modelVertex, modelPixel);
+ simpleVertex, simplePixel);
addPipeline(
Key::Builder().withMaterial().withUnlit(),
modelVertex, modelUnlitPixel);
addPipeline(
Key::Builder().withUnlit(),
- modelVertex, modelUnlitPixel);
+ simpleVertex, simpleUnlitPixel);
addPipeline(
Key::Builder().withMaterial().withTangents(),
modelNormalMapVertex, modelNormalMapPixel);
@@ -189,13 +200,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
modelVertex, modelTranslucentPixel);
addPipeline(
Key::Builder().withTranslucent(),
- modelVertex, modelTranslucentPixel);
+ simpleVertex, simpleTranslucentPixel);
addPipeline(
Key::Builder().withMaterial().withTranslucent().withUnlit(),
modelVertex, modelTranslucentUnlitPixel);
addPipeline(
Key::Builder().withTranslucent().withUnlit(),
- modelVertex, modelTranslucentUnlitPixel);
+ 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 4f02140825..d261fb343a 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.
@@ -25,15 +25,17 @@ 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) {
- 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);
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..b9eb921e9d
--- /dev/null
+++ b/libraries/render-utils/src/simple_transparent_textured.slf
@@ -0,0 +1,62 @@
+<@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 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 opacity = _color.a;
+ if (_color.a <= 0.0) {
+ texel = colorToLinearRGBA(texel);
+ opacity = -_color.a;
+ }
+ opacity *= texel.a;
+ vec3 albedo = _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,
+ 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
new file mode 100644
index 0000000000..693d7be2db
--- /dev/null
+++ b/libraries/render-utils/src/simple_transparent_textured_unlit.slf
@@ -0,0 +1,36 @@
+<@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;
+
+
+layout(location = 0) out vec4 _fragColor0;
+
+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
diff --git a/scripts/system/pal.js b/scripts/system/pal.js
index b39c993894..5fbea90025 100644
--- a/scripts/system/pal.js
+++ b/scripts/system/pal.js
@@ -269,13 +269,26 @@ 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) {
+ if (error || (response.status !== 'success')) {
+ print("Error: unable to remove connection", connectionUserName, error || response.status);
+ return;
+ }
+ getConnectionData();
+ });
+ break
+
case 'removeFriend':
friendUserName = message.params;
request({
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;