mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-11 12:02:12 +02:00
604 lines
22 KiB
QML
604 lines
22 KiB
QML
//
|
|
// NameCard.qml
|
|
// qml/hifi
|
|
//
|
|
// Created by Howard Stearns on 12/9/2016
|
|
// Copyright 2016 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
|
|
//
|
|
|
|
import QtQuick 2.5
|
|
import QtQuick.Controls 1.4
|
|
import QtQuick.Controls.Styles 1.4
|
|
import QtGraphicalEffects 1.0
|
|
import stylesUit 1.0
|
|
import controlsUit 1.0 as HifiControls
|
|
import "toolbars"
|
|
|
|
// references Users, UserActivityLogger, MyAvatar, Vec3, Quat, AddressManager, Account from root context
|
|
|
|
Item {
|
|
id: thisNameCard
|
|
// Size
|
|
width: isMyCard ? pal.myCardWidth - anchors.leftMargin : pal.nearbyNameCardWidth;
|
|
height: isMyCard ? pal.myCardHeight : pal.rowHeight;
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: 5
|
|
anchors.top: parent.top;
|
|
|
|
// Properties
|
|
property string profileUrl: "";
|
|
property string connectionStatus : ""
|
|
property string uuid: ""
|
|
property string displayName: ""
|
|
property string userName: ""
|
|
property real displayNameTextPixelSize: 18
|
|
property int usernameTextPixelSize: 14
|
|
property real audioLevel: 0.0
|
|
property real avgAudioLevel: 0.0
|
|
property bool isMyCard: false
|
|
property bool selected: false
|
|
property bool isAdmin: false
|
|
property bool isPresent: true
|
|
property bool isReplicated: false
|
|
property string placeName: ""
|
|
property string profilePicBorderColor: (connectionStatus == "connection" ? hifi.colors.indigoAccent : (connectionStatus == "friend" ? hifi.colors.greenHighlight : "transparent"))
|
|
property alias avImage: avatarImage
|
|
property bool has3DHTML: PlatformInfo.has3DHTML();
|
|
|
|
Item {
|
|
id: avatarImage
|
|
visible: profileUrl !== "" && userName !== "";
|
|
// Size
|
|
height: isMyCard ? 84 : 42;
|
|
width: visible ? height : 0;
|
|
anchors.top: parent.top;
|
|
anchors.topMargin: isMyCard ? 0 : 8;
|
|
anchors.left: parent.left
|
|
clip: true
|
|
Image {
|
|
id: userImage
|
|
source: profileUrl !== "" ? ((0 === profileUrl.indexOf("http")) ? profileUrl : (Account.metaverseServerURL + profileUrl)) : "";
|
|
mipmap: true;
|
|
// Anchors
|
|
anchors.fill: parent
|
|
layer.enabled: true
|
|
layer.effect: OpacityMask {
|
|
maskSource: Item {
|
|
width: userImage.width;
|
|
height: userImage.height;
|
|
Rectangle {
|
|
anchors.centerIn: parent;
|
|
width: userImage.width; // This works because userImage is square
|
|
height: width;
|
|
radius: width;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
AnimatedImage {
|
|
source: "../../icons/profilePicLoading.gif"
|
|
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 && activeTab == "nearbyTab") || isMyCard;
|
|
hoverEnabled: enabled
|
|
onClicked: {
|
|
if (has3DHTML) {
|
|
userInfoViewer.url = Account.metaverseServerURL + "/users/" + userName;
|
|
userInfoViewer.visible = true;
|
|
}
|
|
}
|
|
onEntered: infoHoverImage.visible = has3DHTML;
|
|
onExited: infoHoverImage.visible = false;
|
|
}
|
|
}
|
|
|
|
// Colored border around avatarImage
|
|
Rectangle {
|
|
id: avatarImageBorder;
|
|
visible: avatarImage.visible;
|
|
anchors.verticalCenter: avatarImage.verticalCenter;
|
|
anchors.horizontalCenter: avatarImage.horizontalCenter;
|
|
width: avatarImage.width + border.width;
|
|
height: avatarImage.height + border.width;
|
|
color: "transparent"
|
|
radius: avatarImage.height;
|
|
border.color: profilePicBorderColor;
|
|
border.width: 4;
|
|
}
|
|
|
|
// DisplayName field for my card
|
|
Rectangle {
|
|
id: myDisplayName
|
|
visible: isMyCard
|
|
// Size
|
|
width: parent.width - avatarImage.width - anchors.leftMargin - anchors.rightMargin*2;
|
|
height: 40
|
|
// Anchors
|
|
anchors.top: avatarImage.top
|
|
anchors.topMargin: avatarImage.visible ? 18 : 0;
|
|
anchors.left: avatarImage.right
|
|
anchors.leftMargin: avatarImage.visible ? 5 : 0;
|
|
anchors.rightMargin: 5;
|
|
// Style
|
|
color: hifi.colors.textFieldLightBackground
|
|
border.color: hifi.colors.blueHighlight
|
|
border.width: 0
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
onClicked: {
|
|
myDisplayNameText.focus = true;
|
|
myDisplayNameText.cursorPosition = myDisplayNameText.positionAt(mouseX - myDisplayNameText.anchors.leftMargin, mouseY, TextInput.CursorOnCharacter);
|
|
}
|
|
onDoubleClicked: {
|
|
myDisplayNameText.selectAll();
|
|
myDisplayNameText.focus = true;
|
|
}
|
|
onEntered: myDisplayName.color = hifi.colors.lightGrayText;
|
|
onExited: myDisplayName.color = hifi.colors.textFieldLightBackground;
|
|
}
|
|
// Edit pencil glyph
|
|
HiFiGlyphs {
|
|
id: editGlyph
|
|
text: hifi.glyphs.editPencil
|
|
// Text Size
|
|
size: displayNameTextPixelSize*1.5
|
|
// Anchors
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: 5
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
// Style
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
color: hifi.colors.baseGray
|
|
}
|
|
TextInput {
|
|
id: myDisplayNameText
|
|
// Properties
|
|
text: thisNameCard.displayName
|
|
maximumLength: 256
|
|
clip: true
|
|
// Size
|
|
width: parent.width
|
|
height: parent.height
|
|
// Anchors
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: 10
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: editGlyph.width + editGlyph.anchors.rightMargin
|
|
// Style
|
|
font.family: "Fira Sans SemiBold"
|
|
font.pixelSize: displayNameTextPixelSize
|
|
selectionColor: hifi.colors.blueAccent
|
|
selectedTextColor: "black"
|
|
// Text Positioning
|
|
verticalAlignment: TextInput.AlignVCenter
|
|
horizontalAlignment: TextInput.AlignLeft
|
|
autoScroll: false;
|
|
// Signals
|
|
onEditingFinished: {
|
|
if (MyAvatar.displayName !== text) {
|
|
MyAvatar.displayName = text;
|
|
UserActivityLogger.palAction("display_name_change", text);
|
|
}
|
|
focus = false;
|
|
}
|
|
onFocusChanged: {
|
|
if (focus === true) {
|
|
myDisplayName.border.width = 1
|
|
color = "black"
|
|
autoScroll = true;
|
|
pal.currentlyEditingDisplayName = true
|
|
} else {
|
|
myDisplayName.border.width = 0
|
|
color: hifi.colors.darkGray
|
|
cursorPosition = 0;
|
|
autoScroll = false;
|
|
pal.currentlyEditingDisplayName = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// DisplayName container for others' cards
|
|
Item {
|
|
id: displayNameContainer
|
|
visible: !isMyCard && pal.activeTab !== "connectionsTab"
|
|
// Size
|
|
width: parent.width - anchors.leftMargin - avatarImage.width - anchors.leftMargin;
|
|
height: displayNameTextPixelSize + 4
|
|
// Anchors
|
|
anchors.top: avatarImage.top;
|
|
anchors.left: avatarImage.right
|
|
anchors.leftMargin: avatarImage.visible ? 5 : 0;
|
|
// DisplayName Text for others' cards
|
|
FiraSansSemiBold {
|
|
id: displayNameText
|
|
// Properties
|
|
text: thisNameCard.displayName
|
|
elide: Text.ElideRight
|
|
// Size
|
|
width: isAdmin ? Math.min(displayNameTextMetrics.tightBoundingRect.width + 8, parent.width - adminLabelText.width - adminLabelQuestionMark.width + 8) : parent.width
|
|
// Anchors
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
// Text Size
|
|
size: displayNameTextPixelSize
|
|
// Text Positioning
|
|
verticalAlignment: Text.AlignTop
|
|
// Style
|
|
color: hifi.colors.darkGray;
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
enabled: selected && pal.activeTab == "nearbyTab" && isPresent;
|
|
hoverEnabled: enabled
|
|
onClicked: {
|
|
goToUserInDomain(thisNameCard.uuid);
|
|
UserActivityLogger.palAction("go_to_user_in_domain", thisNameCard.uuid);
|
|
}
|
|
onEntered: {
|
|
displayNameText.color = hifi.colors.blueHighlight;
|
|
userNameText.color = hifi.colors.blueHighlight;
|
|
}
|
|
onExited: {
|
|
displayNameText.color = hifi.colors.darkGray
|
|
userNameText.color = hifi.colors.blueAccent;
|
|
}
|
|
}
|
|
}
|
|
TextMetrics {
|
|
id: displayNameTextMetrics
|
|
font: displayNameText.font
|
|
text: displayNameText.text
|
|
}
|
|
// "ADMIN" label for other users' cards
|
|
RalewaySemiBold {
|
|
id: adminLabelText
|
|
visible: isAdmin
|
|
text: "ADMIN"
|
|
// Text size
|
|
size: displayNameText.size - 4
|
|
// Anchors
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: displayNameText.right
|
|
// Style
|
|
font.capitalization: Font.AllUppercase
|
|
color: hifi.colors.redHighlight
|
|
// Alignment
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignTop
|
|
}
|
|
// This Rectangle refers to the [?] popup button next to "ADMIN"
|
|
Item {
|
|
id: adminLabelQuestionMark
|
|
visible: isAdmin
|
|
// Size
|
|
width: 20
|
|
height: displayNameText.height
|
|
// Anchors
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: adminLabelText.right
|
|
RalewayRegular {
|
|
id: adminLabelQuestionMarkText
|
|
text: "[?]"
|
|
size: adminLabelText.size
|
|
font.capitalization: Font.AllUppercase
|
|
color: hifi.colors.redHighlight
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
anchors.fill: parent
|
|
}
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
enabled: isPresent
|
|
hoverEnabled: enabled
|
|
onClicked: letterbox(hifi.glyphs.question,
|
|
"Domain Admin",
|
|
"This user is an admin on this domain. Admins can <b>Silence</b> and <b>Ban</b> other users at their discretion - so be extra nice!")
|
|
onEntered: adminLabelQuestionMarkText.color = "#94132e"
|
|
onExited: adminLabelQuestionMarkText.color = hifi.colors.redHighlight
|
|
}
|
|
}
|
|
}
|
|
|
|
// UserName Text
|
|
FiraSansRegular {
|
|
id: userNameText
|
|
// Properties
|
|
text: thisNameCard.userName === "Unknown user" ? "not logged in" : thisNameCard.userName;
|
|
elide: Text.ElideRight
|
|
visible: thisNameCard.userName !== "";
|
|
// Size
|
|
width: parent.width
|
|
height: paintedHeight
|
|
// Anchors
|
|
anchors.top: isMyCard ? myDisplayName.bottom : pal.activeTab == "nearbyTab" ? displayNameContainer.bottom : avatarImage.top //(parent.height - displayNameTextPixelSize/2));
|
|
anchors.bottom: pal.activeTab === "connectionsTab" && !isMyCard ? avatarImage.bottom : undefined
|
|
anchors.left: avatarImage.right;
|
|
anchors.leftMargin: avatarImage.visible ? 5 : 0;
|
|
anchors.rightMargin: 5;
|
|
// Text Size
|
|
size: pal.activeTab == "nearbyTab" || isMyCard ? usernameTextPixelSize : displayNameTextPixelSize;
|
|
// Text Positioning
|
|
verticalAlignment: Text.AlignVCenter;
|
|
// Style
|
|
color: hifi.colors.blueAccent;
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
enabled: selected && pal.activeTab == "nearbyTab" && thisNameCard.userName !== "" && isPresent;
|
|
hoverEnabled: enabled
|
|
onClicked: {
|
|
goToUserInDomain(thisNameCard.uuid);
|
|
UserActivityLogger.palAction("go_to_user_in_domain", thisNameCard.uuid);
|
|
}
|
|
onEntered: {
|
|
displayNameText.color = hifi.colors.blueHighlight;
|
|
userNameText.color = hifi.colors.blueHighlight;
|
|
}
|
|
onExited: {
|
|
displayNameText.color = hifi.colors.darkGray;
|
|
userNameText.color = hifi.colors.blueAccent;
|
|
}
|
|
}
|
|
}
|
|
StateImage {
|
|
id: nameCardConnectionInfoImage
|
|
visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && has3DHTML
|
|
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: {
|
|
if (has3DHTML) {
|
|
userInfoViewer.url = Account.metaverseServerURL + "/users/" + userName;
|
|
userInfoViewer.visible = true;
|
|
}
|
|
}
|
|
onEntered: {
|
|
nameCardConnectionInfoImage.buttonState = 1;
|
|
}
|
|
onExited: {
|
|
nameCardConnectionInfoImage.buttonState = 0;
|
|
}
|
|
}
|
|
FiraSansRegular {
|
|
id: nameCardConnectionInfoText
|
|
visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && PlatformInfo.has3DHTML()
|
|
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: 24;
|
|
x: 120
|
|
anchors.verticalCenter: nameCardConnectionInfoImage.verticalCenter
|
|
anchors.left: has3DHTML ? nameCardConnectionInfoText.right : avatarImage.right
|
|
anchors.leftMargin: has3DHTML ? 10 : 0
|
|
}
|
|
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"
|
|
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"
|
|
text: "Visit"
|
|
enabled: thisNameCard.placeName !== ""
|
|
anchors.verticalCenter: nameCardRemoveConnectionImage.verticalCenter
|
|
x: 240
|
|
onClicked: {
|
|
console.log("Vist user button clicked."); // Remove after debugging.
|
|
AddressManager.goToUser(thisNameCard.userName, false);
|
|
UserActivityLogger.palAction("go_to_user", thisNameCard.userName);
|
|
}
|
|
}
|
|
|
|
// VU Meter
|
|
Rectangle {
|
|
id: nameCardVUMeter
|
|
// Size
|
|
width: ((gainSlider.value - gainSlider.minimumValue)/(gainSlider.maximumValue - gainSlider.minimumValue)) * (gainSlider.width);
|
|
height: 8
|
|
// Anchors
|
|
anchors.bottom: isMyCard ? avatarImage.bottom : parent.bottom;
|
|
anchors.bottomMargin: isMyCard ? 0 : height;
|
|
anchors.left: isMyCard ? userNameText.left : parent.left;
|
|
// Style
|
|
radius: 4
|
|
color: "#c5c5c5"
|
|
visible: (!isMyCard && (selected && pal.activeTab == "nearbyTab")) && isPresent
|
|
// Rectangle for the zero-gain point on the VU meter
|
|
Rectangle {
|
|
id: vuMeterZeroGain
|
|
visible: gainSlider.visible
|
|
// Size
|
|
width: 4
|
|
height: 18
|
|
// Style
|
|
color: hifi.colors.darkGray
|
|
// Anchors
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: (-gainSlider.minimumValue)/(gainSlider.maximumValue - gainSlider.minimumValue) * gainSlider.width - 4
|
|
}
|
|
// Rectangle for the VU meter line
|
|
Rectangle {
|
|
id: vuMeterLine
|
|
width: gainSlider.width
|
|
visible: gainSlider.visible
|
|
// Style
|
|
color: vuMeterBase.color
|
|
radius: nameCardVUMeter.radius
|
|
height: nameCardVUMeter.height / 2
|
|
anchors.verticalCenter: nameCardVUMeter.verticalCenter
|
|
}
|
|
// Rectangle for the VU meter base
|
|
Rectangle {
|
|
id: vuMeterBase
|
|
// Anchors
|
|
anchors.fill: parent
|
|
visible: !isMyCard && selected
|
|
// Style
|
|
color: parent.color
|
|
radius: parent.radius
|
|
}
|
|
// Rectangle for the VU meter audio level
|
|
Rectangle {
|
|
id: vuMeterLevel
|
|
visible: !isMyCard && selected
|
|
// Size
|
|
width: (thisNameCard.audioLevel) * parent.width
|
|
// Style
|
|
color: parent.color
|
|
radius: parent.radius
|
|
// Anchors
|
|
anchors.bottom: parent.bottom
|
|
anchors.top: parent.top
|
|
anchors.left: parent.left
|
|
}
|
|
// Gradient for the VU meter audio level
|
|
LinearGradient {
|
|
anchors.fill: vuMeterLevel
|
|
source: vuMeterLevel
|
|
start: Qt.point(0, 0)
|
|
end: Qt.point(parent.width, 0)
|
|
gradient: Gradient {
|
|
GradientStop { position: 0.0; color: "#2c8e72" }
|
|
GradientStop { position: 0.9; color: "#1fc6a6" }
|
|
GradientStop { position: 0.91; color: "#ea4c5f" }
|
|
GradientStop { position: 1.0; color: "#ea4c5f" }
|
|
}
|
|
}
|
|
}
|
|
|
|
// Per-Avatar Gain Slider
|
|
Slider {
|
|
id: gainSlider
|
|
// Size
|
|
width: isMyCard ? thisNameCard.width - 20 : thisNameCard.width;
|
|
height: 14
|
|
// Anchors
|
|
anchors.verticalCenter: nameCardVUMeter.verticalCenter;
|
|
anchors.left: nameCardVUMeter.left;
|
|
// Properties
|
|
visible: (!isMyCard && (selected && pal.activeTab == "nearbyTab")) && isPresent;
|
|
minimumValue: -60.0
|
|
maximumValue: 20.0
|
|
stepSize: 5
|
|
updateValueWhileDragging: true
|
|
value: Users.getAvatarGain(uuid)
|
|
onValueChanged: {
|
|
updateGainFromQML(uuid, value, false);
|
|
}
|
|
onPressedChanged: {
|
|
if (!pressed) {
|
|
updateGainFromQML(uuid, value, true)
|
|
}
|
|
}
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onWheel: {
|
|
// Do nothing.
|
|
}
|
|
onDoubleClicked: {
|
|
gainSlider.value = 0.0
|
|
}
|
|
onPressed: {
|
|
// Pass through to Slider
|
|
mouse.accepted = false
|
|
}
|
|
onReleased: {
|
|
// the above mouse.accepted seems to make this
|
|
// never get called, nonetheless...
|
|
mouse.accepted = false
|
|
}
|
|
}
|
|
style: SliderStyle {
|
|
groove: Rectangle {
|
|
color: "#c5c5c5"
|
|
implicitWidth: gainSlider.width
|
|
implicitHeight: 4
|
|
radius: 2
|
|
opacity: 0
|
|
}
|
|
handle: Rectangle {
|
|
anchors.centerIn: parent
|
|
color: (control.pressed || control.hovered) ? "#00b4ef" : "#8F8F8F"
|
|
implicitWidth: 10
|
|
implicitHeight: 16
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateGainFromQML(avatarUuid, sliderValue, isReleased) {
|
|
if (Users.getAvatarGain(avatarUuid) != sliderValue) {
|
|
Users.setAvatarGain(avatarUuid, sliderValue);
|
|
if (isReleased) {
|
|
UserActivityLogger.palAction("avatar_gain_changed", avatarUuid);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Function body by Howard Stearns 2017-01-08
|
|
function goToUserInDomain(avatarUuid) {
|
|
var avatar = AvatarList.getAvatar(avatarUuid);
|
|
if (!avatar || !avatar.position || !avatar.orientation) {
|
|
console.log("This avatar is no longer present. goToUserInDomain() failed.");
|
|
return;
|
|
}
|
|
// This is the last step of what AddressManager.goToUser does, but we don't need to resolve the username.
|
|
MyAvatar.goToLocation(avatar.position, true, Quat.cancelOutRollAndPitch(avatar.orientation), true);
|
|
}
|
|
}
|