From 935d152617983d13869646a2a2c941111e98ad13 Mon Sep 17 00:00:00 2001 From: milad Date: Fri, 17 May 2019 12:42:10 -0700 Subject: [PATCH 1/5] forgot to copy a folder in to the local repo --- .../modules/defaultLocalEntityProps.js | 26 + .../resources/modules/entityMaker.js | 154 ++++ .../resources/modules/nameTagListManager.js | 668 ++++++++++++++++++ .../resources/modules/objectAssign.js | 32 + .../resources/modules/pickRayController.js | 305 ++++++++ .../resources/modules/textHelper.js | 224 ++++++ .../simplifiedNametag/simplifiedNametag.js | 95 +++ scripts/system/simplifiedUI/simplifiedUI.js | 3 +- 8 files changed, 1505 insertions(+), 2 deletions(-) create mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js create mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js create mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js create mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js create mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js create mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js create mode 100644 scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js new file mode 100644 index 0000000000..1947a47220 --- /dev/null +++ b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js @@ -0,0 +1,26 @@ +// +// Simplified Nametag +// defaultLocalEntityProps.js +// Created by Milad Nazeri on 2019-03-09 +// Copyright 2019 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 +// +// Base properties for the Local Entities +// + +var localEntityProps = { + dimensions: [1, 0.1, 0], + type: "Text", + lineHeight: 0.1, + textColor: "#ffffff", + textAlpha: 1.0, + backgroundColor: "#2d2d2d", + backgroundAlpha: 0.6, + billboardMode: "full", + lifetime: 3, + canCastShadow: true +}; + +module.exports = localEntityProps; \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js new file mode 100644 index 0000000000..5b254f9ba5 --- /dev/null +++ b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js @@ -0,0 +1,154 @@ +// +// Simplified Nametag +// entityMaker.js +// Created by Milad Nazeri on 2019-02-19 +// Copyright 2019 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 +// +// A helper library to make entities +// + + +Script.require('./objectAssign.js'); + +function EntityMaker(type) { + this.properties = {}; + this.cache = {}; + this.id = null; + this.created = null; + this.type = type; +} + + +// ************************************* +// START API +// ************************************* +// #region API + + +// Add properties to the cache / temporary storage +function add(props){ + // You can either add an object of props or 2 arguments as key and value + if (arguments.length === 2) { + var property = arguments[0]; + var value = arguments[1]; + props = {}; + props[property] = value; + } + + this.properties = Object.assign({}, this.properties, props); + this.cache = Object.assign({}, this.cache, this.properties); + + return this; +} + + +// Sends the current temporary stroage to edit the entity +function sync(){ + Entities.editEntity(this.id, this.properties); + this.properties = {}; + + return this; +} + + +// Immediately edit the entity with the properties given +function edit(props){ + if (arguments.length === 2) { + var property = arguments[0]; + var value = arguments[1]; + props = {}; + props[property] = value; + } + this.properties = Object.assign({}, this.properties, props); + this.cache = Object.assign({}, this.cache, this.properties); + this.sync(); + + return this; +} + + +// Get a property either from the cache or by querying the entity directly +function get(propertyKeys, queryEntity){ + if (queryEntity && typeof propertyKeys === 'string') { + var propertyValue = Entities.getEntityProperties(this.id, propertyKeys)[propertyKeys]; + this.properties[propertyKeys] = propertyValue; + this.cache = Object.assign({}, this.cache, this.properties); + return propertyValue; + } + + if (queryEntity && Array.isArray(propertyKeys)) { + var entityProps = Entities.getEntityProperties(this.id, propertyKeys); + for (var prop in entityProps) { + if (propertyKeys.indexOf(prop) === -1) { + delete entityProps[prop]; + } else { + this.properties[prop] = entityProps[prop]; + } + } + return entityProps; + } + + if (Array.isArray(propertyKeys)) { + var recombinedProps = {}; + propertyKeys.forEach(function (prop) { + recombinedProps[prop] = this.cache[prop]; + }, this); + return recombinedProps; + } + + return this.cache[propertyKeys]; +} + + +// Show the entity +function show(){ + this.edit({ visible: true }); + + return this; +} + + +// Hide the enity +function hide(){ + this.edit({ visible: false }); +} + + +// Add an entity if it isn't created +function create(clearPropertiesAfter){ + this.id = Entities.addEntity(this.properties, this.type); + if (clearPropertiesAfter) { + this.properties = {}; + } + return this; +} + + +// Delete the entity +function destroy(){ + Entities.deleteEntity(this.id); + + return this; +} + + +// #endregion +// ************************************* +// END API +// ************************************* + +EntityMaker.prototype = { + add: add, + sync: sync, + edit: edit, + get: get, + show: show, + hide: hide, + create: create, + destroy: destroy +}; + +module.exports = EntityMaker; \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js new file mode 100644 index 0000000000..d77bbcf1b5 --- /dev/null +++ b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js @@ -0,0 +1,668 @@ +// +// Simplified Nametag +// nameTagListManager.js +// Created by Milad Nazeri on 2019-03-09 +// Copyright 2019 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 +// +// Helps manage the list of avatars added to the nametag list +// + +var ON = 'ON'; +var OFF = 'OFF'; +var DEBUG_ON = true; +var DEBUG_OFF = false; +var log = Script.require( + 'https://hifi-content.s3.amazonaws.com/milad/ROLC/d/ROLC_High-Fidelity/02_Organize/O_Projects/Repos/hifi-content/developerTools/sharedLibraries/easyLog/easyLog.js?' + + Date.now())(DEBUG_OFF, 'nameTagListManager.js'); + + +var EntityMaker = Script.require('./entityMaker.js?' + Date.now()); +var entityProps = Script.require('./defaultLocalEntityProps.js?' + Date.now()); +var textHelper = new (Script.require('./textHelper.js?' + Date.now())); +var X = 0; +var Y = 1; +var Z = 2; +var HALF = 0.5; +var CLEAR_ENTITY_EDIT_PROPS = true; +var MILISECONDS_IN_SECOND = 1000; + +// ************************************* +// START UTILTY +// ************************************* +// #region UTILTY + + +// Properties to give new avatars added to the list +function NewAvatarProps() { + return { + avatarInfo: null, + previousDistance: null, + currentDistance: null, + initialDistance: null, + initialDimensions: null, + previousName: null, + timeoutStarted: false + }; +} + + +// Makes sure clear interval exists before changing +function maybeClearInterval() { + if (_this.redrawTimeout) { + Script.clearInterval(_this.redrawTimeout); + _this.redrawTimeout = null; + } +} + + +// Calculate our initial properties for the nametag +var Z_SIZE = 0.01; +var LINE_HEIGHT_SCALER = 0.99; +var DISTANCE_SCALER_ON = 0.35; +var DISTANCE_SCALER_ALWAYS_ON = 0.50; +var distanceScaler = DISTANCE_SCALER_ON; +var userScaler = 1.0; +var DEFAULT_LINE_HEIGHT = entityProps.lineHeight; +function calculateInitialProperties(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + + var adjustedScaler = null; + var distance = null; + var dimensions = null; + var lineHeight = null; + var scaledDimensions = null; + var name = null; + + // Handle if we are asking for the main or sub properties + name = avatarInfo.displayName; + + // Use the text helper to calculate what our dimensions for the text box should be + textHelper + .setText(name) + .setLineHeight(DEFAULT_LINE_HEIGHT); + + // Calculate the distance from the camera to the target avatar + distance = getDistance(uuid); + + // Adjust the distance by the distance scaler + distanceScaler = avatarNametagMode === "on" ? DISTANCE_SCALER_ON : DISTANCE_SCALER_ALWAYS_ON; + adjustedScaler = distance * distanceScaler; + // Get the new dimensions from the text helper + dimensions = [textHelper.getTotalTextLength(), DEFAULT_LINE_HEIGHT, Z_SIZE]; + // Adjust the dimensions by the modified distance scaler + scaledDimensions = Vec3.multiply(dimensions, adjustedScaler); + + // Adjust the lineheight to be the new scaled dimensions Y + lineHeight = scaledDimensions[Y] * LINE_HEIGHT_SCALER; + + return { + distance: distance, + scaledDimensions: scaledDimensions, + lineHeight: lineHeight + }; +} + + +// Used in alwaysOn mode to show or hide if they reached the max radius +function showHide(uuid, type) { + var avatar = _this.avatars[uuid]; + var nametag = avatar.nametag; + + if (type === "show") { + nametag.show(); + } else { + nametag.hide(); + } +} + + +// Go through the selected avatar list and see if any of the avatars need a redraw +function checkAllSelectedForRedraw() { + for (var avatar in _this.selectedAvatars) { + maybeRedraw(avatar); + } +} + + +// Remake the nametags if the display name changes +function updateName(uuid) { + var avatar = _this.avatars[uuid]; + avatar.nametag.destroy(); + + avatar.nametag = new EntityMaker('local').add(entityProps); + + makeNameTag(uuid); +} + + +// Get the current data for an avatar. +function getAvatarData(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + + var newAvatarInfo = AvatarManager.getAvatar(uuid); + // Save the username so it doesn't get overwritten when grabbing new avatarData + var combinedAvatarInfo = Object.assign({}, newAvatarInfo, { + username: avatarInfo === null ? null : avatarInfo.username + }); + + // Now combine that avatar data with the main avatar object + _this.avatars[uuid] = Object.assign({}, avatar, { avatarInfo: combinedAvatarInfo }); + + return _this; +} + + +// Calculate the distance between the camera and the target avatar +function getDistance(uuid, checkAvatar, shouldSave) { + checkAvatar = checkAvatar || false; + shouldSave = shouldSave || true; + var eye = checkAvatar ? MyAvatar.position : Camera.position; + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + + var target = avatarInfo.position; + + var currentDistance = Vec3.distance(target, eye); + + if (!checkAvatar && shouldSave) { + avatar.previousDistance = avatar.currentDistance; + avatar.currentDistance = currentDistance; + } + + return currentDistance; +} + + +// Check to see if we need to toggle our interval check because we went to 0 avatars +// or if we got our first avatar in the select list +function shouldToggleInterval() { + var currentNumberOfAvatarsSelected = Object.keys(_this.selectedAvatars).length; + + if (currentNumberOfAvatarsSelected === 0 && _this.redrawTimeout) { + toggleInterval(); + return; + } + + if (currentNumberOfAvatarsSelected > 0 && !_this.redrawTimeout) { + toggleInterval(); + return; + } +} + + +// Turn off and on the redraw check +var INTERVAL_CHECK_MS = 30; +function toggleInterval() { + if (_this.redrawTimeout) { + maybeClearInterval(); + } else { + _this.redrawTimeout = + Script.setInterval(checkAllSelectedForRedraw, INTERVAL_CHECK_MS); + } +} + + +// handle turning the peristenet mode on +function handleAlwaysOnMode(shouldTurnOnAlwaysOnMode) { + _this.reset(); + if (shouldTurnOnAlwaysOnMode) { + AvatarManager + .getAvatarIdentifiers() + .forEach(function (avatar) { + if (avatar) { + add(avatar); + } + }); + } +} + + +// #endregion +// ************************************* +// END UTILTY +// ************************************* + +// ************************************* +// START Nametag +// ************************************* +// #region Nametag + + +var _this = null; +function nameTagListManager() { + _this = this; + + _this.avatars = {}; + _this.selectedAvatars = {}; + _this.redrawTimeout = null; +} + + +// Create or make visible either the sub or the main tag. +var REDRAW_TIMEOUT_AMOUNT_MS = 500; +var LEFT_MARGIN_SCALER = 0.15; +var RIGHT_MARGIN_SCALER = 0.10; +var TOP_MARGIN_SCALER = 0.07; +var BOTTOM_MARGIN_SCALER = 0.03; +var ABOVE_HEAD_OFFSET = 0.30; +var DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON = 5; +var DISTANCE_SCALER_INTERPOLATION_OFFSET_ON = 10; +var maxDistance = MAX_RADIUS_IGNORE_METERS; +var onModeScalar = 0.55; +var alwaysOnModeScalar = -0.55; +function makeNameTag(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + var nametag = avatar.nametag; + + // Make sure an anonymous name is covered before sending to calculate + + avatarInfo.displayName = avatarInfo.displayName === "" ? "anonymous" : avatarInfo.displayName.trim(); + avatar.previousName = avatarInfo.displayName; + + // Returns back the properties we need based on what we are looking for and the distance from the avatar + var calculatedProps = calculateInitialProperties(uuid); + var distance = calculatedProps.distance; + var scaledDimensions = calculatedProps.scaledDimensions; + var lineHeight = calculatedProps.lineHeight; + + // Capture the inital dimensions, distance, and displayName in case we need to redraw + avatar.previousDisplayName = avatarInfo.displayName; + avatar.initialDimensions = scaledDimensions; + avatar.initialDistance = distance; + var name = avatarInfo.displayName; + var parentID = uuid; + + nametag.add("text", name); + + // Multiply the new dimensions and line height with the user selected scaler + scaledDimensions = Vec3.multiply(scaledDimensions, userScaler); + + maxDistance = avatarNametagMode === "on" + ? MAX_ON_MODE_DISTANCE + DISTANCE_SCALER_INTERPOLATION_OFFSET_ON + : MAX_RADIUS_IGNORE_METERS + DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON; + var finalScaler = (distance - maxDistance) / (MIN_DISTANCE - maxDistance); + + var remainder = 1 - finalScaler; + var multipliedRemainderOn = remainder * onModeScalar; + var multipliedRemainderAlwaysOn = remainder * alwaysOnModeScalar; + finalScaler = avatarNametagMode === "on" ? finalScaler + multipliedRemainderOn : finalScaler + multipliedRemainderAlwaysOn; + + scaledDimensions = Vec3.multiply(scaledDimensions, finalScaler); + + lineHeight = scaledDimensions[Y] * LINE_HEIGHT_SCALER; + // Add some room for the margin by using lineHeight as a reference + scaledDimensions[X] += (lineHeight * LEFT_MARGIN_SCALER) + (lineHeight * RIGHT_MARGIN_SCALER); + scaledDimensions[Y] += (lineHeight * TOP_MARGIN_SCALER) + (lineHeight * BOTTOM_MARGIN_SCALER); + + var scaledDimenionsYHalf = scaledDimensions[Y] * HALF; + var AvatarData = AvatarManager.getAvatar(uuid); + var headJointIndex = AvatarData.getJointIndex("Head"); + var jointInObjectFrame = AvatarData.getAbsoluteJointTranslationInObjectFrame(headJointIndex); + var nameTagPosition = jointInObjectFrame.y + scaledDimenionsYHalf + ABOVE_HEAD_OFFSET; + var localPosition = [0, nameTagPosition, 0]; + + var visible = true; + if (avatarNametagMode === "alwaysOn") { + var currentDistance = getDistance(uuid, CHECK_AVATAR, false); + visible = currentDistance > MAX_RADIUS_IGNORE_METERS ? false : true; + } + + nametag + .add("leftMargin", lineHeight * LEFT_MARGIN_SCALER) + .add("rightMargin", lineHeight * RIGHT_MARGIN_SCALER) + .add("topMargin", lineHeight * TOP_MARGIN_SCALER) + .add("bottomMargin", lineHeight * BOTTOM_MARGIN_SCALER) + .add("lineHeight", lineHeight) + .add("dimensions", scaledDimensions) + .add("parentID", parentID) + .add("localPosition", localPosition) + .add("visible", visible) + .create(CLEAR_ENTITY_EDIT_PROPS); + + Script.setTimeout(function () { + nametag.edit("visible", true); + }, REDRAW_TIMEOUT_AMOUNT_MS); +} + + +// Check to see if the display named changed or if the distance is big enough to need a redraw. +var MAX_RADIUS_IGNORE_METERS = 22; +var MAX_ON_MODE_DISTANCE = 30; +var CHECK_AVATAR = true; +var MIN_DISTANCE = 0.2; +function maybeRedraw(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + getAvatarData(uuid); + + getDistance(uuid); + var avatarDistance = getDistance(uuid, CHECK_AVATAR, false); + if (avatarNametagMode === "alwaysOn" && avatarDistance > MAX_RADIUS_IGNORE_METERS) { + showHide(uuid, "hide"); + } + + if (avatarNametagMode === "alwaysOn" && avatarDistance < MAX_RADIUS_IGNORE_METERS) { + showHide(uuid, "show"); + } + + avatarInfo.displayName = avatarInfo.displayName === "" ? "anonymous" : avatarInfo.displayName.trim(); + + if (avatar.previousName !== avatarInfo.displayName) { + updateName(uuid, avatarInfo.displayName); + } else { + redraw(uuid); + } + +} + + +// Handle redrawing if needed +function redraw(uuid) { + var avatar = _this.avatars[uuid]; + + var nametag = avatar.nametag; + var initialDimensions = null; + var initialDistance = null; + var currentDistance = null; + var newDimensions = null; + var lineHeight = null; + + initialDistance = avatar.initialDistance; + currentDistance = avatar.currentDistance; + + initialDimensions = avatar.initialDimensions; + + // Find our new dimensions from the new distance + newDimensions = [ + (initialDimensions[X] / initialDistance) * currentDistance, + (initialDimensions[Y] / initialDistance) * currentDistance, + (initialDimensions[Z] / initialDistance) * currentDistance + ]; + + // Multiply the new dimensions and line height with the user selected scaler + newDimensions = Vec3.multiply(newDimensions, userScaler); + + var distance = getDistance(uuid, false, false); + + maxDistance = avatarNametagMode === "on" + ? MAX_ON_MODE_DISTANCE + DISTANCE_SCALER_INTERPOLATION_OFFSET_ON + : MAX_RADIUS_IGNORE_METERS + DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON; + var finalScaler = (distance - maxDistance) / (MIN_DISTANCE - maxDistance); + var remainder = 1 - finalScaler; + var multipliedRemainderOn = remainder * onModeScalar; + var multipliedRemainderAlwaysOn = remainder * alwaysOnModeScalar; + finalScaler = avatarNametagMode === "on" ? finalScaler + multipliedRemainderOn : finalScaler + multipliedRemainderAlwaysOn; + + newDimensions = Vec3.multiply(newDimensions, finalScaler); + + lineHeight = newDimensions[Y] * LINE_HEIGHT_SCALER; + + // Add some room for the margin by using lineHeight as a reference + newDimensions[X] += (lineHeight * LEFT_MARGIN_SCALER) + (lineHeight * RIGHT_MARGIN_SCALER); + newDimensions[Y] += (lineHeight * TOP_MARGIN_SCALER) + (lineHeight * BOTTOM_MARGIN_SCALER); + + // We can generalize some of the processes that are similar in makeNameTag() and redraw() if we wanted to reduce some code + var newDimenionsYHalf = newDimensions[Y] * HALF; + var AvatarData = AvatarManager.getAvatar(uuid); + var headJointIndex = AvatarData.getJointIndex("Head"); + var jointInObjectFrame = AvatarData.getAbsoluteJointTranslationInObjectFrame(headJointIndex); + var nameTagPosition = jointInObjectFrame.y + newDimenionsYHalf + ABOVE_HEAD_OFFSET; + var localPosition = [0, nameTagPosition, 0]; + + nametag + .add("leftMargin", lineHeight * LEFT_MARGIN_SCALER) + .add("rightMargin", lineHeight * RIGHT_MARGIN_SCALER) + .add("topMargin", lineHeight * TOP_MARGIN_SCALER) + .add("bottomMargin", lineHeight * BOTTOM_MARGIN_SCALER) + .add("lineHeight", lineHeight) + .add("dimensions", newDimensions) + .add("localPosition", localPosition) + .sync(); +} + +// Add a user to the list. +var DEFAULT_LIFETIME = entityProps.lifetime; + + +// add a user to our current selections +function add(uuid) { + // User Doesn't exist so give them new props and save in the cache, and get their current avatar info. + if (!_this.avatars[uuid]) { + _this.avatars[uuid] = new NewAvatarProps(); + getAvatarData(uuid); + } + + var avatar = _this.avatars[uuid]; + + _this.selectedAvatars[uuid] = true; + if (avatarNametagMode === "alwaysOn") { + entityProps.lifetime = -1; + } else { + entityProps.lifetime = DEFAULT_LIFETIME; + } + + avatar.nametag = new EntityMaker('local').add(entityProps); + + // When the user clicks someone, we create their nametag + makeNameTag(uuid); + var deleteEnttyInMiliseconds = entityProps.lifetime * MILISECONDS_IN_SECOND; + + // Remove from list after lifetime is over + if (avatarNametagMode === "on") { + avatar.timeoutStarted = Script.setTimeout(function () { + removeNametag(uuid); + }, deleteEnttyInMiliseconds); + } + + // Check to see if anyone is in the selected list now to see if we need to start the interval checking + shouldToggleInterval(); + + return _this; +} + + +// Remove the avatar from the list. +function remove(uuid) { + if (_this.selectedAvatars[uuid]) { + delete _this.selectedAvatars[uuid]; + } + + removeNametag(uuid); + + shouldToggleInterval(); + delete _this.avatars[uuid]; + + return _this; +} + + +// Remove all the current nametags. +function removeAllNametags() { + for (var uuid in _this.selectedAvatars) { + removeNametag(uuid); + } + + return _this; +} + + +// Remove a single Nametag. +function removeNametag(uuid) { + var avatar = _this.avatars[uuid]; + + if (avatar) { + avatar.nametag.destroy(); + delete _this.selectedAvatars[uuid]; + return _this; + } + +} + + +// #endregion +// ************************************* +// END Nametag +// ************************************* + +// ************************************* +// START API +// ************************************* +// #region API + + +// Create the manager and hook up username signal +function create() { + + return _this; +} + + +// Destory the manager and disconnect from username signal +function destroy() { + _this.reset(); + return _this; +} + + +// Check to see if we need to delete any close by nametags +var MAX_DELETE_RANGE = 4; +function checkIfAnyAreClose(target) { + var targetPosition = AvatarManager.getAvatar(target).position; + for (var uuid in _this.selectedAvatars) { + var position = AvatarManager.getAvatar(uuid).position; + var distance = Vec3.distance(position, targetPosition); + if (distance <= MAX_DELETE_RANGE) { + var timeoutStarted = _this.avatars[uuid].timeoutStarted; + if (timeoutStarted) { + Script.clearTimeout(timeoutStarted); + timeoutStarted = null; + } + removeNametag(uuid); + } + } +} + +// Handles what happens when an avatar gets triggered on +function handleSelect(uuid) { + if (avatarNametagMode === "off" || avatarNametagMode === "alwaysOn") { + return; + } + + var inSelected = uuid in _this.selectedAvatars; + + if (inSelected) { + if (avatarNametagMode === "on") { + var timeoutStarted = _this.avatars[uuid].timeoutStarted; + if (timeoutStarted) { + Script.clearTimeout(timeoutStarted); + timeoutStarted = null; + } + } + + removeNametag(uuid); + + } else { + checkIfAnyAreClose(uuid); + add(uuid); + } +} + + +// Check to see if we need to clear timeouts for avatars +function maybeClearAllTimeouts() { + for (var uuid in _this.selectedAvatars) { + var timeoutStarted = _this.avatars[uuid].timeoutStarted; + if (timeoutStarted) { + Script.clearTimeout(timeoutStarted); + timeoutStarted = null; + } + } +} + + +// Check to see if the uuid is in the avatars list before removing +function maybeRemove(uuid) { + if (uuid in _this.avatars) { + remove(uuid); + } +} + + +// Check to see if we need to add this user to our list +function maybeAdd(uuid) { + if (uuid && avatarNametagMode === "alwaysOn" && !(uuid in _this.avatars)) { + add(uuid); + } +} + + +// Register the beggining scaler in case it was saved from a previous session +function registerInitialScaler(initalScaler) { + userScaler = initalScaler; +} + + +// Handle the user updating scale +function updateUserScaler(newUSerScaler) { + userScaler = newUSerScaler; + for (var avatar in _this.selectedAvatars) { + redraw(avatar); + } +} + + +// Reset the avatar list +function reset() { + maybeClearAllTimeouts(); + removeAllNametags(); + _this.avatars = {}; + shouldToggleInterval(); + + return _this; +} + + +// Update the nametag display mode +var avatarNametagMode = "on"; +function handleAvatarNametagMode(newAvatarNametagMode) { + if (avatarNametagMode === "alwaysOn") { + handleAlwaysOnMode(false); + } + + avatarNametagMode = newAvatarNametagMode; + if (avatarNametagMode === "alwaysOn") { + handleAlwaysOnMode(true); + } + + if (avatarNametagMode === "off" || avatarNametagMode === "on") { + reset(); + } +} + + +// #endregion +// ************************************* +// END API +// ************************************* + + +nameTagListManager.prototype = { + create: create, + destroy: destroy, + handleSelect: handleSelect, + maybeRemove: maybeRemove, + maybeAdd: maybeAdd, + registerInitialScaler: registerInitialScaler, + updateUserScaler: updateUserScaler, + handleAvatarNametagMode: handleAvatarNametagMode, + reset: reset +}; + + +module.exports = nameTagListManager; \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js new file mode 100644 index 0000000000..c408b0ebc8 --- /dev/null +++ b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js @@ -0,0 +1,32 @@ +// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + +if (typeof Object.assign != 'function') { + // Must be writable: true, enumerable: false, configurable: true + Object.defineProperty(Object, "assign", { + value: function assign(target, varArgs) { // .length of function is 2 + 'use strict'; + if (target == null) { // TypeError if undefined or null + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }, + writable: true, + configurable: true + }); +} + diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js new file mode 100644 index 0000000000..87d05fa838 --- /dev/null +++ b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js @@ -0,0 +1,305 @@ +// +// Simplified Nametag +// pickRayController.js +// Created by Milad Nazeri on 2019-03-08 +// Copyright 2019 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 +// +// Easy pickray controllers for Entities, Overlays, and Avatars +// + + +var _this; +function PickRayController(){ + _this = this; + + _this.rayType = null; + _this.eventHandler = null; + _this.intersection = null; + _this.lastPick = null; + _this.currentPick = null; + _this.mappingName = null; + _this.mapping = null; + _this._boundMousePressHandler = null; + _this.shouldDoublePress = null; + _this.controllEnabled = false; +} + + +// ************************************* +// START UTILITY +// ************************************* +// #region UTILITY + + +// Returns the right UUID based on hand triggered +function getUUIDFromLaser(hand) { + hand = hand === Controller.Standard.LeftHand + ? Controller.Standard.LeftHand + : Controller.Standard.RightHand; + + var pose = getControllerWorldLocation(hand); + var start = pose.position; + // Get the direction that the hand is facing in the world + var direction = Vec3.multiplyQbyV(pose.orientation, [0, 1, 0]); + + pickRayTypeHandler(start, direction); + + if (_this.currentPick) { + _this.eventHandler(_this.currentPick, _this.intersection); + } +} + + +// The following two functions are a modified version of what's found in scripts/system/libraries/controllers.js + +// Utility function for the ControllerWorldLocation offset +function getGrabPointSphereOffset(handController) { + // These values must match what's in scripts/system/libraries/controllers.js + // x = upward, y = forward, z = lateral + var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; + var offset = GRAB_POINT_SPHERE_OFFSET; + if (handController === Controller.Standard.LeftHand) { + offset = { + x: -GRAB_POINT_SPHERE_OFFSET.x, + y: GRAB_POINT_SPHERE_OFFSET.y, + z: GRAB_POINT_SPHERE_OFFSET.z + }; + } + + return Vec3.multiply(MyAvatar.sensorToWorldScale, offset); +} + + +// controllerWorldLocation is where the controller would be, in-world, with an added offset +function getControllerWorldLocation(handController, doOffset) { + var orientation; + var position; + var valid = false; + + if (handController >= 0) { + var pose = Controller.getPoseValue(handController); + valid = pose.valid; + var controllerJointIndex; + if (pose.valid) { + if (handController === Controller.Standard.RightHand) { + controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"); + } else { + controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"); + } + orientation = Quat.multiply(MyAvatar.orientation, MyAvatar.getAbsoluteJointRotationInObjectFrame(controllerJointIndex)); + position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, MyAvatar.getAbsoluteJointTranslationInObjectFrame(controllerJointIndex))); + + // add to the real position so the grab-point is out in front of the hand, a bit + if (doOffset) { + var offset = getGrabPointSphereOffset(handController); + position = Vec3.sum(position, Vec3.multiplyQbyV(orientation, offset)); + } + + } else if (!HMD.isHandControllerAvailable()) { + // NOTE: keep _this offset in sync with scripts/system/controllers/handControllerPointer.js:493 + var VERTICAL_HEAD_LASER_OFFSET = 0.1 * MyAvatar.sensorToWorldScale; + position = Vec3.sum(Camera.position, Vec3.multiplyQbyV(Camera.orientation, { x: 0, y: VERTICAL_HEAD_LASER_OFFSET, z: 0 })); + orientation = Quat.multiply(Camera.orientation, Quat.angleAxis(-90, { x: 1, y: 0, z: 0 })); + valid = true; + } + } + + return { + position: position, + translation: position, + orientation: orientation, + rotation: orientation, + valid: valid + }; +} + + +// Handle if the uuid picked on is new or different +function handleUUID(uuid){ + if (!_this.lastPick && !_this.currentPick) { + _this.currentPick = uuid; + _this.lastPick = uuid; + } else { + _this.lastPick = _this.currentPick; + _this.currentPick = uuid; + } +} + + +function pickRayTypeHandler(pickRay){ + // Handle if pickray is system generated or user generated + if (arguments.length === 2) { + pickRay = { origin: arguments[0], direction: arguments[1] }; + } + + // Each different ray pick type needs a different findRayIntersection function + switch (_this.rayType) { + case 'avatar': + var avatarIntersection = AvatarList.findRayIntersection(pickRay, [], [MyAvatar.sessionUUID], false); + _this.intersection = avatarIntersection; + handleUUID(avatarIntersection.avatarID); + break; + case 'local': + var overlayIntersection = Overlays.findRayIntersection(pickRay, [], []); + _this.intersection = overlayIntersection; + handleUUID(overlayIntersection.overlayID); + break; + case 'entity': + var entityIntersection = Entities.findRayIntersection(pickRay, [], []); + _this.intersection = entityIntersection; + handleUUID(entityIntersection.avatarID); + break; + default: + console.log("ray type not handled"); + } +} + + +// Handle the interaction when in desktop and a mouse is pressed +function mousePressHandler(event) { + if (HMD.active || !event.isLeftButton) { + return; + } + var pickRay = Camera.computePickRay(event.x, event.y); + pickRayTypeHandler(pickRay); + if (_this.currentPick) { + _this.eventHandler(_this.currentPick, _this.intersection); + } +} + + +// Function to call when double press is singled +function doublePressHandler(event) { + mousePressHandler(event); +} + + +// #endregion +// ************************************* +// END UTILITY +// ************************************* + +// ************************************* +// START API +// ************************************* +// #region API + + +// After setup is given, this gets the Controller ready to be enabled +function create(){ + _this.mapping = Controller.newMapping(_this.mappingName); + + _this.mapping.from(Controller.Standard.LTClick).to(function (value) { + if (value === 0) { + return; + } + + getUUIDFromLaser(Controller.Standard.LeftHand); + }); + + + _this.mapping.from(Controller.Standard.RTClick).to(function (value) { + if (value === 0) { + return; + } + + getUUIDFromLaser(Controller.Standard.RightHand); + }); + + return _this; +} + + +// Set type of raypick for what kind of uuids to return +function setType(type){ + _this.rayType = type; + + return _this; +} + + +// Set if double presses should register as well +function setShouldDoublePress(shouldDoublePress){ + _this.shouldDoublePress = shouldDoublePress; + + return _this; +} + + +// Set the mapping name for the controller +function setMapName(name) { + _this.mappingName = name; + + return _this; +} + + +// Enables mouse press and trigger events +function enable(){ + if (!_this.controllEnabled) { + Controller.mousePressEvent.connect(mousePressHandler); + if (_this.shouldDoublePress) { + Controller.mouseDoublePressEvent.connect(doublePressHandler); + } + Controller.enableMapping(_this.mappingName); + _this.controllEnabled = true; + + return _this; + } + + return -1; +} + + +// Disable the controller and mouse press +function disable(){ + if (_this.controllEnabled) { + Controller.mousePressEvent.disconnect(mousePressHandler); + if (_this.shouldDoublePress){ + Controller.mouseDoublePressEvent.disconnect(doublePressHandler); + } + Controller.disableMapping(_this.mappingName); + _this.controllEnabled = false; + + return _this; + } + + return -1; +} + + +// Synonym for disable +function destroy(){ + _this.disable(); +} + + +// Register the function to be called on a click +function registerEventHandler(fn){ + _this.eventHandler = fn; + + return _this; +} + + +// #endregion +// ************************************* +// END API +// ************************************* + +PickRayController.prototype = { + create: create, + setType: setType, + setShouldDoublePress: setShouldDoublePress, + setMapName: setMapName, + enable: enable, + disable: disable, + destroy: destroy, + registerEventHandler: registerEventHandler +}; + + +module.exports = PickRayController; diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js new file mode 100644 index 0000000000..72013a2ac5 --- /dev/null +++ b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js @@ -0,0 +1,224 @@ +// +// Simplified Nametag +// textHelper.js +// Created by Milad Nazeri on 2019-03-08 +// Copyright 2019 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 +// +// Module to help calculate text size +// + + +// ************************************* +// START MAPS +// ************************************* +// #region MAPS + + +var charMap = { + a: 0.05, + b: 0.051, + c: 0.05, + d: 0.051, + e: 0.05, + f: 0.035, + g: 0.051, + h: 0.051, + i: 0.025, + j: 0.025, + k: 0.05, + l: 0.025, + m: 0.0775, + n: 0.051, + o: 0.051, + p: 0.051, + q: 0.051, + r: 0.035, + s: 0.05, + t: 0.035, + u: 0.051, + v: 0.05, + w: 0.07, + x: 0.05, + y: 0.05, + z: 0.05, + A: 0.06, + B: 0.06, + C: 0.06, + D: 0.06, + E: 0.05, + F: 0.05, + G: 0.06, + H: 0.0625, + I: 0.0275, + J: 0.05, + K: 0.06, + L: 0.05, + M: 0.075, + N: 0.0625, + O: 0.0625, + P: 0.06, + Q: 0.0625, + R: 0.06, + S: 0.06, + T: 0.06, + U: 0.06, + V: 0.06, + W: 0.075, + X: 0.06, + Y: 0.06, + Z: 0.06 +}; + +var symbolMap = { + "!": 0.025, + "@": 0.08, + "#": 0.07, + "$": 0.058, + "%": 0.07, + "^": 0.04, + "&": 0.06, + "*": 0.04, + "(": 0.04, + ")": 0.04, + "_": 0.041, + "{": 0.034, + "}": 0.034, + "/": 0.04, + "|": 0.02, + "<": 0.049, + ">": 0.049, + "[": 0.0300, + "]": 0.0300, + ".": 0.0260, + ",": 0.0260, + "?": 0.048, + "~": 0.0610, + "`": 0.0310, + "+": 0.0510, + "=": 0.0510 +}; + + +// #endregion +// ************************************* +// END MAPS +// ************************************* + +var _this = null; +function TextHelper(){ + _this = this; + + this.text = ""; + this.textArray = ""; + this.lineHeight = 0; + this.totalTextLength = 0; + this.scaler = 1.0; +} + + +// ************************************* +// START UTILITY +// ************************************* +// #region UTILITY + + +// Split the string into a text array to be operated on +function createTextArray(){ + _this.textArray = _this.text.split(""); +} + + +// Account for the text length +function adjustForScale(defaultTextLength){ + _this.totalTextLength = defaultTextLength * _this.scaler; +} + + +// #endregion +// ************************************* +// END UTILITY +// ************************************* + +// #endregion +// ************************************* +// END name +// ************************************* + +// ************************************* +// START API +// ************************************* +// #region API + + +// Set the text that needs to be calculated on +function setText(newText){ + _this.text = newText; + createTextArray(); + + return _this; +} + + +// Set the line height which helps calculate the font size +var DEFAULT_LINE_HEIGHT = 0.1; +function setLineHeight(newLineHeight){ + _this.lineHeight = newLineHeight; + _this.scaler = _this.lineHeight / DEFAULT_LINE_HEIGHT; + + return _this; +} + + +// Calculate the sign dimensions +var DEFAULT_CHAR_SIZE = 0.025; +var NUMBER = 0.05; +var DIGIT_REGEX = /\d/g; +var WHITE_SPACE_REGEX = /[ ]/g; +var SPACE = 0.018; +function getTotalTextLength(){ + // Map the string array to it's sizes + var lengthArray = _this.textArray.map(function(letter){ + if (charMap[letter]){ + return charMap[letter]; + } else if (letter.match(DIGIT_REGEX)){ + return NUMBER; + } else if (symbolMap[letter]) { + return symbolMap[letter]; + } else if (letter.match(WHITE_SPACE_REGEX)) { + return SPACE; + } else { + return DEFAULT_CHAR_SIZE; + } + }); + + // add up all the values in the array + var defaultTextLength = lengthArray.reduce(function(prev, curr){ + return prev + curr; + }, 0); + + adjustForScale(defaultTextLength); + + return _this.totalTextLength; +} + + +// #endregion +// ************************************* +// END API +// ************************************* + +TextHelper.prototype = { + setText: setText, + setLineHeight: setLineHeight, + getTotalTextLength: getTotalTextLength +}; + +module.exports = TextHelper; + +// var text = new TextHelper(); +// text.setText("lowbar"); +// text.setLineHeight("0.1"); +// text.getTotalTextLength(); \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js b/scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js new file mode 100644 index 0000000000..9b4d9cfad3 --- /dev/null +++ b/scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js @@ -0,0 +1,95 @@ +// +// Simplified Nametag +// Created by Milad Nazeri on 2019-02-16 +// Copyright 2019 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 +// +// Click on someone to get a nametag for them +// +var PickRayController = Script.require('./resources/modules/pickRayController.js?' + Date.now()); +var NameTagListManager = Script.require('./resources/modules/nameTagListManager.js?' + Date.now()); +var pickRayController = new PickRayController(); +var nameTagListManager = new NameTagListManager(); + +// Handles avatar being solo'd +pickRayController + .registerEventHandler(selectAvatar) + .setType("avatar") + .setMapName("hifi_simplifiedNametag") + .setShouldDoublePress(true) + .create() + .enable(); + + +function selectAvatar(uuid, intersection) { + nameTagListManager.handleSelect(uuid, intersection); +} + + +// Handles reset of list if you change domains +function onDomainChange() { + nameTagListManager.reset(); +} + + +// Handles removing an avatar from the list if they leave the domain +function onAvatarRemoved(uuid) { + nameTagListManager.maybeRemove(uuid); +} + + +// Automatically add an avatar if they come into the domain. Mainly used for alwaysOn mode. +function onAvatarAdded(uuid) { + nameTagListManager.maybeAdd(uuid); +} + + +// Called on init +var avatarNametagMode; +function create() { + nameTagListManager.create(); + handleAvatarNametagMode(Settings.getValue("simplifiedNametag/avatarNametagMode", "on")); + + Window.domainChanged.connect(onDomainChange); + AvatarManager.avatarRemovedEvent.connect(onAvatarRemoved); + AvatarManager.avatarAddedEvent.connect(onAvatarAdded); +} + + +// Called when the script is closing +function destroy() { + nameTagListManager.destroy(); + pickRayController.destroy(); + Window.domainChanged.disconnect(onDomainChange); + AvatarManager.avatarRemovedEvent.disconnect(onAvatarRemoved); + AvatarManager.avatarAddedEvent.disconnect(onAvatarAdded); +} + + +// chose which mode you want the nametags in. On, off, or alwaysOn. +function handleAvatarNametagMode(newAvatarNameTagMode) { + avatarNametagMode = newAvatarNameTagMode; + nameTagListManager.handleAvatarNametagMode(avatarNametagMode); + Settings.setValue("simplifiedNametag/avatarNametagMode", avatarNametagMode); +} + + +// ************************************* +// START api +// ************************************* +// #region api + + +module.exports = { + create: create, + destroy: destroy, + handleAvatarNametagMode: handleAvatarNametagMode +}; + + +// #endregion +// ************************************* +// END api +// ************************************* \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedUI.js b/scripts/system/simplifiedUI/simplifiedUI.js index c6181d2ad9..3efee2ce4e 100644 --- a/scripts/system/simplifiedUI/simplifiedUI.js +++ b/scripts/system/simplifiedUI/simplifiedUI.js @@ -434,8 +434,7 @@ function ensureFirstPersonCameraInHMD(isHMDMode) { } } - -var simplifiedNametag = Script.require("../simplifiedNametag/simplifiedNametag.js"); +var simplifiedNametag = Script.require("./simplifiedNametag/simplifiedNametag.js?" + Date.now()); var oldShowAudioTools; var oldShowBubbleTools; var keepExistingUIAndScriptsSetting = Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false); From 27c48418878edba86f10a08393e4753c74175a3b Mon Sep 17 00:00:00 2001 From: milad Date: Fri, 24 May 2019 13:57:18 -0700 Subject: [PATCH 2/5] Updated Nametag to use the sessionDisplayName or the displayName as default --- .../resources/modules/nameTagListManager.js | 51 +- .../modules/defaultLocalEntityProps.js | 26 - .../resources/modules/entityMaker.js | 154 ---- .../resources/modules/nameTagListManager.js | 668 ------------------ .../resources/modules/objectAssign.js | 32 - .../resources/modules/pickRayController.js | 305 -------- .../resources/modules/textHelper.js | 224 ------ .../simplifiedNametag/simplifiedNametag.js | 95 --- 8 files changed, 27 insertions(+), 1528 deletions(-) delete mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js delete mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js delete mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js delete mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js delete mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js delete mode 100644 scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js delete mode 100644 scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js diff --git a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js index ded67745f8..1d5ead6975 100644 --- a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js +++ b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js @@ -10,15 +10,7 @@ // Helps manage the list of avatars added to the nametag list // -var ON = 'ON'; -var OFF = 'OFF'; -var DEBUG_ON = true; -var DEBUG_OFF = false; -var log = Script.require( - 'https://hifi-content.s3.amazonaws.com/milad/ROLC/d/ROLC_High-Fidelity/02_Organize/O_Projects/Repos/hifi-content/developerTools/sharedLibraries/easyLog/easyLog.js?' - + Date.now())(DEBUG_OFF, 'nameTagListManager.js'); - - +console.log("\nm\n\n\n\n\n\n\n\n\nTEST!!!\n\n\n\n\n\n") var EntityMaker = Script.require('./entityMaker.js?' + Date.now()); var entityProps = Script.require('./defaultLocalEntityProps.js?' + Date.now()); var textHelper = new (Script.require('./textHelper.js?' + Date.now())); @@ -68,7 +60,6 @@ var userScaler = 1.0; var DEFAULT_LINE_HEIGHT = entityProps.lineHeight; function calculateInitialProperties(uuid) { var avatar = _this.avatars[uuid]; - var avatarInfo = avatar.avatarInfo; var adjustedScaler = null; var distance = null; @@ -78,7 +69,7 @@ function calculateInitialProperties(uuid) { var name = null; // Handle if we are asking for the main or sub properties - name = avatarInfo.displayName; + name = getCorrectName(uuid); // Use the text helper to calculate what our dimensions for the text box should be textHelper @@ -242,6 +233,22 @@ function nameTagListManager() { _this.redrawTimeout = null; } +// Get the correct display name +function getCorrectName(uuid) { + var avatar = _this.avatars[uuid]; + var avatarInfo = avatar.avatarInfo; + + var displayNameToUse = avatarInfo.sessionDisplayName; + if (displayNameToUse === "") { + displayNameToUse = avatarInfo.displayName; + } + + + displayNameToUse= displayNameToUse === "" ? "anonymous" : displayNameToUse.trim(); + + return displayNameToUse; +} + // Create or make visible either the sub or the main tag. var REDRAW_TIMEOUT_AMOUNT_MS = 500; @@ -257,13 +264,12 @@ var onModeScalar = 0.55; var alwaysOnModeScalar = -0.75; function makeNameTag(uuid) { var avatar = _this.avatars[uuid]; - var avatarInfo = avatar.avatarInfo; var nametag = avatar.nametag; - // Make sure an anonymous name is covered before sending to calculate - - avatarInfo.displayName = avatarInfo.displayName === "" ? "anonymous" : avatarInfo.displayName.trim(); - avatar.previousName = avatarInfo.displayName; + // Get the correct name for the nametag + var name = getCorrectName(uuid); + avatar.previousName = name; + nametag.add("text", name); // Returns back the properties we need based on what we are looking for and the distance from the avatar var calculatedProps = calculateInitialProperties(uuid); @@ -271,14 +277,12 @@ function makeNameTag(uuid) { var scaledDimensions = calculatedProps.scaledDimensions; var lineHeight = calculatedProps.lineHeight; - // Capture the inital dimensions, distance, and displayName in case we need to redraw - avatar.previousDisplayName = avatarInfo.displayName; + // Capture the inital dimensions and distance in case we need to redraw avatar.initialDimensions = scaledDimensions; avatar.initialDistance = distance; - var name = avatarInfo.displayName; + var parentID = uuid; - nametag.add("text", name); // Multiply the new dimensions and line height with the user selected scaler scaledDimensions = Vec3.multiply(scaledDimensions, userScaler); @@ -338,7 +342,6 @@ var CHECK_AVATAR = true; var MIN_DISTANCE = 0.2; function maybeRedraw(uuid) { var avatar = _this.avatars[uuid]; - var avatarInfo = avatar.avatarInfo; getAvatarData(uuid); getDistance(uuid); @@ -351,10 +354,10 @@ function maybeRedraw(uuid) { showHide(uuid, "show"); } - avatarInfo.displayName = avatarInfo.displayName === "" ? "anonymous" : avatarInfo.displayName.trim(); + var name = getCorrectName(uuid); - if (avatar.previousName !== avatarInfo.displayName) { - updateName(uuid, avatarInfo.displayName); + if (avatar.previousName !== name) { + updateName(uuid, name); } else { redraw(uuid); } diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js deleted file mode 100644 index 1947a47220..0000000000 --- a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/defaultLocalEntityProps.js +++ /dev/null @@ -1,26 +0,0 @@ -// -// Simplified Nametag -// defaultLocalEntityProps.js -// Created by Milad Nazeri on 2019-03-09 -// Copyright 2019 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 -// -// Base properties for the Local Entities -// - -var localEntityProps = { - dimensions: [1, 0.1, 0], - type: "Text", - lineHeight: 0.1, - textColor: "#ffffff", - textAlpha: 1.0, - backgroundColor: "#2d2d2d", - backgroundAlpha: 0.6, - billboardMode: "full", - lifetime: 3, - canCastShadow: true -}; - -module.exports = localEntityProps; \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js deleted file mode 100644 index 5b254f9ba5..0000000000 --- a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/entityMaker.js +++ /dev/null @@ -1,154 +0,0 @@ -// -// Simplified Nametag -// entityMaker.js -// Created by Milad Nazeri on 2019-02-19 -// Copyright 2019 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 -// -// A helper library to make entities -// - - -Script.require('./objectAssign.js'); - -function EntityMaker(type) { - this.properties = {}; - this.cache = {}; - this.id = null; - this.created = null; - this.type = type; -} - - -// ************************************* -// START API -// ************************************* -// #region API - - -// Add properties to the cache / temporary storage -function add(props){ - // You can either add an object of props or 2 arguments as key and value - if (arguments.length === 2) { - var property = arguments[0]; - var value = arguments[1]; - props = {}; - props[property] = value; - } - - this.properties = Object.assign({}, this.properties, props); - this.cache = Object.assign({}, this.cache, this.properties); - - return this; -} - - -// Sends the current temporary stroage to edit the entity -function sync(){ - Entities.editEntity(this.id, this.properties); - this.properties = {}; - - return this; -} - - -// Immediately edit the entity with the properties given -function edit(props){ - if (arguments.length === 2) { - var property = arguments[0]; - var value = arguments[1]; - props = {}; - props[property] = value; - } - this.properties = Object.assign({}, this.properties, props); - this.cache = Object.assign({}, this.cache, this.properties); - this.sync(); - - return this; -} - - -// Get a property either from the cache or by querying the entity directly -function get(propertyKeys, queryEntity){ - if (queryEntity && typeof propertyKeys === 'string') { - var propertyValue = Entities.getEntityProperties(this.id, propertyKeys)[propertyKeys]; - this.properties[propertyKeys] = propertyValue; - this.cache = Object.assign({}, this.cache, this.properties); - return propertyValue; - } - - if (queryEntity && Array.isArray(propertyKeys)) { - var entityProps = Entities.getEntityProperties(this.id, propertyKeys); - for (var prop in entityProps) { - if (propertyKeys.indexOf(prop) === -1) { - delete entityProps[prop]; - } else { - this.properties[prop] = entityProps[prop]; - } - } - return entityProps; - } - - if (Array.isArray(propertyKeys)) { - var recombinedProps = {}; - propertyKeys.forEach(function (prop) { - recombinedProps[prop] = this.cache[prop]; - }, this); - return recombinedProps; - } - - return this.cache[propertyKeys]; -} - - -// Show the entity -function show(){ - this.edit({ visible: true }); - - return this; -} - - -// Hide the enity -function hide(){ - this.edit({ visible: false }); -} - - -// Add an entity if it isn't created -function create(clearPropertiesAfter){ - this.id = Entities.addEntity(this.properties, this.type); - if (clearPropertiesAfter) { - this.properties = {}; - } - return this; -} - - -// Delete the entity -function destroy(){ - Entities.deleteEntity(this.id); - - return this; -} - - -// #endregion -// ************************************* -// END API -// ************************************* - -EntityMaker.prototype = { - add: add, - sync: sync, - edit: edit, - get: get, - show: show, - hide: hide, - create: create, - destroy: destroy -}; - -module.exports = EntityMaker; \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js deleted file mode 100644 index d77bbcf1b5..0000000000 --- a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/nameTagListManager.js +++ /dev/null @@ -1,668 +0,0 @@ -// -// Simplified Nametag -// nameTagListManager.js -// Created by Milad Nazeri on 2019-03-09 -// Copyright 2019 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 -// -// Helps manage the list of avatars added to the nametag list -// - -var ON = 'ON'; -var OFF = 'OFF'; -var DEBUG_ON = true; -var DEBUG_OFF = false; -var log = Script.require( - 'https://hifi-content.s3.amazonaws.com/milad/ROLC/d/ROLC_High-Fidelity/02_Organize/O_Projects/Repos/hifi-content/developerTools/sharedLibraries/easyLog/easyLog.js?' - + Date.now())(DEBUG_OFF, 'nameTagListManager.js'); - - -var EntityMaker = Script.require('./entityMaker.js?' + Date.now()); -var entityProps = Script.require('./defaultLocalEntityProps.js?' + Date.now()); -var textHelper = new (Script.require('./textHelper.js?' + Date.now())); -var X = 0; -var Y = 1; -var Z = 2; -var HALF = 0.5; -var CLEAR_ENTITY_EDIT_PROPS = true; -var MILISECONDS_IN_SECOND = 1000; - -// ************************************* -// START UTILTY -// ************************************* -// #region UTILTY - - -// Properties to give new avatars added to the list -function NewAvatarProps() { - return { - avatarInfo: null, - previousDistance: null, - currentDistance: null, - initialDistance: null, - initialDimensions: null, - previousName: null, - timeoutStarted: false - }; -} - - -// Makes sure clear interval exists before changing -function maybeClearInterval() { - if (_this.redrawTimeout) { - Script.clearInterval(_this.redrawTimeout); - _this.redrawTimeout = null; - } -} - - -// Calculate our initial properties for the nametag -var Z_SIZE = 0.01; -var LINE_HEIGHT_SCALER = 0.99; -var DISTANCE_SCALER_ON = 0.35; -var DISTANCE_SCALER_ALWAYS_ON = 0.50; -var distanceScaler = DISTANCE_SCALER_ON; -var userScaler = 1.0; -var DEFAULT_LINE_HEIGHT = entityProps.lineHeight; -function calculateInitialProperties(uuid) { - var avatar = _this.avatars[uuid]; - var avatarInfo = avatar.avatarInfo; - - var adjustedScaler = null; - var distance = null; - var dimensions = null; - var lineHeight = null; - var scaledDimensions = null; - var name = null; - - // Handle if we are asking for the main or sub properties - name = avatarInfo.displayName; - - // Use the text helper to calculate what our dimensions for the text box should be - textHelper - .setText(name) - .setLineHeight(DEFAULT_LINE_HEIGHT); - - // Calculate the distance from the camera to the target avatar - distance = getDistance(uuid); - - // Adjust the distance by the distance scaler - distanceScaler = avatarNametagMode === "on" ? DISTANCE_SCALER_ON : DISTANCE_SCALER_ALWAYS_ON; - adjustedScaler = distance * distanceScaler; - // Get the new dimensions from the text helper - dimensions = [textHelper.getTotalTextLength(), DEFAULT_LINE_HEIGHT, Z_SIZE]; - // Adjust the dimensions by the modified distance scaler - scaledDimensions = Vec3.multiply(dimensions, adjustedScaler); - - // Adjust the lineheight to be the new scaled dimensions Y - lineHeight = scaledDimensions[Y] * LINE_HEIGHT_SCALER; - - return { - distance: distance, - scaledDimensions: scaledDimensions, - lineHeight: lineHeight - }; -} - - -// Used in alwaysOn mode to show or hide if they reached the max radius -function showHide(uuid, type) { - var avatar = _this.avatars[uuid]; - var nametag = avatar.nametag; - - if (type === "show") { - nametag.show(); - } else { - nametag.hide(); - } -} - - -// Go through the selected avatar list and see if any of the avatars need a redraw -function checkAllSelectedForRedraw() { - for (var avatar in _this.selectedAvatars) { - maybeRedraw(avatar); - } -} - - -// Remake the nametags if the display name changes -function updateName(uuid) { - var avatar = _this.avatars[uuid]; - avatar.nametag.destroy(); - - avatar.nametag = new EntityMaker('local').add(entityProps); - - makeNameTag(uuid); -} - - -// Get the current data for an avatar. -function getAvatarData(uuid) { - var avatar = _this.avatars[uuid]; - var avatarInfo = avatar.avatarInfo; - - var newAvatarInfo = AvatarManager.getAvatar(uuid); - // Save the username so it doesn't get overwritten when grabbing new avatarData - var combinedAvatarInfo = Object.assign({}, newAvatarInfo, { - username: avatarInfo === null ? null : avatarInfo.username - }); - - // Now combine that avatar data with the main avatar object - _this.avatars[uuid] = Object.assign({}, avatar, { avatarInfo: combinedAvatarInfo }); - - return _this; -} - - -// Calculate the distance between the camera and the target avatar -function getDistance(uuid, checkAvatar, shouldSave) { - checkAvatar = checkAvatar || false; - shouldSave = shouldSave || true; - var eye = checkAvatar ? MyAvatar.position : Camera.position; - var avatar = _this.avatars[uuid]; - var avatarInfo = avatar.avatarInfo; - - var target = avatarInfo.position; - - var currentDistance = Vec3.distance(target, eye); - - if (!checkAvatar && shouldSave) { - avatar.previousDistance = avatar.currentDistance; - avatar.currentDistance = currentDistance; - } - - return currentDistance; -} - - -// Check to see if we need to toggle our interval check because we went to 0 avatars -// or if we got our first avatar in the select list -function shouldToggleInterval() { - var currentNumberOfAvatarsSelected = Object.keys(_this.selectedAvatars).length; - - if (currentNumberOfAvatarsSelected === 0 && _this.redrawTimeout) { - toggleInterval(); - return; - } - - if (currentNumberOfAvatarsSelected > 0 && !_this.redrawTimeout) { - toggleInterval(); - return; - } -} - - -// Turn off and on the redraw check -var INTERVAL_CHECK_MS = 30; -function toggleInterval() { - if (_this.redrawTimeout) { - maybeClearInterval(); - } else { - _this.redrawTimeout = - Script.setInterval(checkAllSelectedForRedraw, INTERVAL_CHECK_MS); - } -} - - -// handle turning the peristenet mode on -function handleAlwaysOnMode(shouldTurnOnAlwaysOnMode) { - _this.reset(); - if (shouldTurnOnAlwaysOnMode) { - AvatarManager - .getAvatarIdentifiers() - .forEach(function (avatar) { - if (avatar) { - add(avatar); - } - }); - } -} - - -// #endregion -// ************************************* -// END UTILTY -// ************************************* - -// ************************************* -// START Nametag -// ************************************* -// #region Nametag - - -var _this = null; -function nameTagListManager() { - _this = this; - - _this.avatars = {}; - _this.selectedAvatars = {}; - _this.redrawTimeout = null; -} - - -// Create or make visible either the sub or the main tag. -var REDRAW_TIMEOUT_AMOUNT_MS = 500; -var LEFT_MARGIN_SCALER = 0.15; -var RIGHT_MARGIN_SCALER = 0.10; -var TOP_MARGIN_SCALER = 0.07; -var BOTTOM_MARGIN_SCALER = 0.03; -var ABOVE_HEAD_OFFSET = 0.30; -var DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON = 5; -var DISTANCE_SCALER_INTERPOLATION_OFFSET_ON = 10; -var maxDistance = MAX_RADIUS_IGNORE_METERS; -var onModeScalar = 0.55; -var alwaysOnModeScalar = -0.55; -function makeNameTag(uuid) { - var avatar = _this.avatars[uuid]; - var avatarInfo = avatar.avatarInfo; - var nametag = avatar.nametag; - - // Make sure an anonymous name is covered before sending to calculate - - avatarInfo.displayName = avatarInfo.displayName === "" ? "anonymous" : avatarInfo.displayName.trim(); - avatar.previousName = avatarInfo.displayName; - - // Returns back the properties we need based on what we are looking for and the distance from the avatar - var calculatedProps = calculateInitialProperties(uuid); - var distance = calculatedProps.distance; - var scaledDimensions = calculatedProps.scaledDimensions; - var lineHeight = calculatedProps.lineHeight; - - // Capture the inital dimensions, distance, and displayName in case we need to redraw - avatar.previousDisplayName = avatarInfo.displayName; - avatar.initialDimensions = scaledDimensions; - avatar.initialDistance = distance; - var name = avatarInfo.displayName; - var parentID = uuid; - - nametag.add("text", name); - - // Multiply the new dimensions and line height with the user selected scaler - scaledDimensions = Vec3.multiply(scaledDimensions, userScaler); - - maxDistance = avatarNametagMode === "on" - ? MAX_ON_MODE_DISTANCE + DISTANCE_SCALER_INTERPOLATION_OFFSET_ON - : MAX_RADIUS_IGNORE_METERS + DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON; - var finalScaler = (distance - maxDistance) / (MIN_DISTANCE - maxDistance); - - var remainder = 1 - finalScaler; - var multipliedRemainderOn = remainder * onModeScalar; - var multipliedRemainderAlwaysOn = remainder * alwaysOnModeScalar; - finalScaler = avatarNametagMode === "on" ? finalScaler + multipliedRemainderOn : finalScaler + multipliedRemainderAlwaysOn; - - scaledDimensions = Vec3.multiply(scaledDimensions, finalScaler); - - lineHeight = scaledDimensions[Y] * LINE_HEIGHT_SCALER; - // Add some room for the margin by using lineHeight as a reference - scaledDimensions[X] += (lineHeight * LEFT_MARGIN_SCALER) + (lineHeight * RIGHT_MARGIN_SCALER); - scaledDimensions[Y] += (lineHeight * TOP_MARGIN_SCALER) + (lineHeight * BOTTOM_MARGIN_SCALER); - - var scaledDimenionsYHalf = scaledDimensions[Y] * HALF; - var AvatarData = AvatarManager.getAvatar(uuid); - var headJointIndex = AvatarData.getJointIndex("Head"); - var jointInObjectFrame = AvatarData.getAbsoluteJointTranslationInObjectFrame(headJointIndex); - var nameTagPosition = jointInObjectFrame.y + scaledDimenionsYHalf + ABOVE_HEAD_OFFSET; - var localPosition = [0, nameTagPosition, 0]; - - var visible = true; - if (avatarNametagMode === "alwaysOn") { - var currentDistance = getDistance(uuid, CHECK_AVATAR, false); - visible = currentDistance > MAX_RADIUS_IGNORE_METERS ? false : true; - } - - nametag - .add("leftMargin", lineHeight * LEFT_MARGIN_SCALER) - .add("rightMargin", lineHeight * RIGHT_MARGIN_SCALER) - .add("topMargin", lineHeight * TOP_MARGIN_SCALER) - .add("bottomMargin", lineHeight * BOTTOM_MARGIN_SCALER) - .add("lineHeight", lineHeight) - .add("dimensions", scaledDimensions) - .add("parentID", parentID) - .add("localPosition", localPosition) - .add("visible", visible) - .create(CLEAR_ENTITY_EDIT_PROPS); - - Script.setTimeout(function () { - nametag.edit("visible", true); - }, REDRAW_TIMEOUT_AMOUNT_MS); -} - - -// Check to see if the display named changed or if the distance is big enough to need a redraw. -var MAX_RADIUS_IGNORE_METERS = 22; -var MAX_ON_MODE_DISTANCE = 30; -var CHECK_AVATAR = true; -var MIN_DISTANCE = 0.2; -function maybeRedraw(uuid) { - var avatar = _this.avatars[uuid]; - var avatarInfo = avatar.avatarInfo; - getAvatarData(uuid); - - getDistance(uuid); - var avatarDistance = getDistance(uuid, CHECK_AVATAR, false); - if (avatarNametagMode === "alwaysOn" && avatarDistance > MAX_RADIUS_IGNORE_METERS) { - showHide(uuid, "hide"); - } - - if (avatarNametagMode === "alwaysOn" && avatarDistance < MAX_RADIUS_IGNORE_METERS) { - showHide(uuid, "show"); - } - - avatarInfo.displayName = avatarInfo.displayName === "" ? "anonymous" : avatarInfo.displayName.trim(); - - if (avatar.previousName !== avatarInfo.displayName) { - updateName(uuid, avatarInfo.displayName); - } else { - redraw(uuid); - } - -} - - -// Handle redrawing if needed -function redraw(uuid) { - var avatar = _this.avatars[uuid]; - - var nametag = avatar.nametag; - var initialDimensions = null; - var initialDistance = null; - var currentDistance = null; - var newDimensions = null; - var lineHeight = null; - - initialDistance = avatar.initialDistance; - currentDistance = avatar.currentDistance; - - initialDimensions = avatar.initialDimensions; - - // Find our new dimensions from the new distance - newDimensions = [ - (initialDimensions[X] / initialDistance) * currentDistance, - (initialDimensions[Y] / initialDistance) * currentDistance, - (initialDimensions[Z] / initialDistance) * currentDistance - ]; - - // Multiply the new dimensions and line height with the user selected scaler - newDimensions = Vec3.multiply(newDimensions, userScaler); - - var distance = getDistance(uuid, false, false); - - maxDistance = avatarNametagMode === "on" - ? MAX_ON_MODE_DISTANCE + DISTANCE_SCALER_INTERPOLATION_OFFSET_ON - : MAX_RADIUS_IGNORE_METERS + DISTANCE_SCALER_INTERPOLATION_OFFSET_ALWAYSON; - var finalScaler = (distance - maxDistance) / (MIN_DISTANCE - maxDistance); - var remainder = 1 - finalScaler; - var multipliedRemainderOn = remainder * onModeScalar; - var multipliedRemainderAlwaysOn = remainder * alwaysOnModeScalar; - finalScaler = avatarNametagMode === "on" ? finalScaler + multipliedRemainderOn : finalScaler + multipliedRemainderAlwaysOn; - - newDimensions = Vec3.multiply(newDimensions, finalScaler); - - lineHeight = newDimensions[Y] * LINE_HEIGHT_SCALER; - - // Add some room for the margin by using lineHeight as a reference - newDimensions[X] += (lineHeight * LEFT_MARGIN_SCALER) + (lineHeight * RIGHT_MARGIN_SCALER); - newDimensions[Y] += (lineHeight * TOP_MARGIN_SCALER) + (lineHeight * BOTTOM_MARGIN_SCALER); - - // We can generalize some of the processes that are similar in makeNameTag() and redraw() if we wanted to reduce some code - var newDimenionsYHalf = newDimensions[Y] * HALF; - var AvatarData = AvatarManager.getAvatar(uuid); - var headJointIndex = AvatarData.getJointIndex("Head"); - var jointInObjectFrame = AvatarData.getAbsoluteJointTranslationInObjectFrame(headJointIndex); - var nameTagPosition = jointInObjectFrame.y + newDimenionsYHalf + ABOVE_HEAD_OFFSET; - var localPosition = [0, nameTagPosition, 0]; - - nametag - .add("leftMargin", lineHeight * LEFT_MARGIN_SCALER) - .add("rightMargin", lineHeight * RIGHT_MARGIN_SCALER) - .add("topMargin", lineHeight * TOP_MARGIN_SCALER) - .add("bottomMargin", lineHeight * BOTTOM_MARGIN_SCALER) - .add("lineHeight", lineHeight) - .add("dimensions", newDimensions) - .add("localPosition", localPosition) - .sync(); -} - -// Add a user to the list. -var DEFAULT_LIFETIME = entityProps.lifetime; - - -// add a user to our current selections -function add(uuid) { - // User Doesn't exist so give them new props and save in the cache, and get their current avatar info. - if (!_this.avatars[uuid]) { - _this.avatars[uuid] = new NewAvatarProps(); - getAvatarData(uuid); - } - - var avatar = _this.avatars[uuid]; - - _this.selectedAvatars[uuid] = true; - if (avatarNametagMode === "alwaysOn") { - entityProps.lifetime = -1; - } else { - entityProps.lifetime = DEFAULT_LIFETIME; - } - - avatar.nametag = new EntityMaker('local').add(entityProps); - - // When the user clicks someone, we create their nametag - makeNameTag(uuid); - var deleteEnttyInMiliseconds = entityProps.lifetime * MILISECONDS_IN_SECOND; - - // Remove from list after lifetime is over - if (avatarNametagMode === "on") { - avatar.timeoutStarted = Script.setTimeout(function () { - removeNametag(uuid); - }, deleteEnttyInMiliseconds); - } - - // Check to see if anyone is in the selected list now to see if we need to start the interval checking - shouldToggleInterval(); - - return _this; -} - - -// Remove the avatar from the list. -function remove(uuid) { - if (_this.selectedAvatars[uuid]) { - delete _this.selectedAvatars[uuid]; - } - - removeNametag(uuid); - - shouldToggleInterval(); - delete _this.avatars[uuid]; - - return _this; -} - - -// Remove all the current nametags. -function removeAllNametags() { - for (var uuid in _this.selectedAvatars) { - removeNametag(uuid); - } - - return _this; -} - - -// Remove a single Nametag. -function removeNametag(uuid) { - var avatar = _this.avatars[uuid]; - - if (avatar) { - avatar.nametag.destroy(); - delete _this.selectedAvatars[uuid]; - return _this; - } - -} - - -// #endregion -// ************************************* -// END Nametag -// ************************************* - -// ************************************* -// START API -// ************************************* -// #region API - - -// Create the manager and hook up username signal -function create() { - - return _this; -} - - -// Destory the manager and disconnect from username signal -function destroy() { - _this.reset(); - return _this; -} - - -// Check to see if we need to delete any close by nametags -var MAX_DELETE_RANGE = 4; -function checkIfAnyAreClose(target) { - var targetPosition = AvatarManager.getAvatar(target).position; - for (var uuid in _this.selectedAvatars) { - var position = AvatarManager.getAvatar(uuid).position; - var distance = Vec3.distance(position, targetPosition); - if (distance <= MAX_DELETE_RANGE) { - var timeoutStarted = _this.avatars[uuid].timeoutStarted; - if (timeoutStarted) { - Script.clearTimeout(timeoutStarted); - timeoutStarted = null; - } - removeNametag(uuid); - } - } -} - -// Handles what happens when an avatar gets triggered on -function handleSelect(uuid) { - if (avatarNametagMode === "off" || avatarNametagMode === "alwaysOn") { - return; - } - - var inSelected = uuid in _this.selectedAvatars; - - if (inSelected) { - if (avatarNametagMode === "on") { - var timeoutStarted = _this.avatars[uuid].timeoutStarted; - if (timeoutStarted) { - Script.clearTimeout(timeoutStarted); - timeoutStarted = null; - } - } - - removeNametag(uuid); - - } else { - checkIfAnyAreClose(uuid); - add(uuid); - } -} - - -// Check to see if we need to clear timeouts for avatars -function maybeClearAllTimeouts() { - for (var uuid in _this.selectedAvatars) { - var timeoutStarted = _this.avatars[uuid].timeoutStarted; - if (timeoutStarted) { - Script.clearTimeout(timeoutStarted); - timeoutStarted = null; - } - } -} - - -// Check to see if the uuid is in the avatars list before removing -function maybeRemove(uuid) { - if (uuid in _this.avatars) { - remove(uuid); - } -} - - -// Check to see if we need to add this user to our list -function maybeAdd(uuid) { - if (uuid && avatarNametagMode === "alwaysOn" && !(uuid in _this.avatars)) { - add(uuid); - } -} - - -// Register the beggining scaler in case it was saved from a previous session -function registerInitialScaler(initalScaler) { - userScaler = initalScaler; -} - - -// Handle the user updating scale -function updateUserScaler(newUSerScaler) { - userScaler = newUSerScaler; - for (var avatar in _this.selectedAvatars) { - redraw(avatar); - } -} - - -// Reset the avatar list -function reset() { - maybeClearAllTimeouts(); - removeAllNametags(); - _this.avatars = {}; - shouldToggleInterval(); - - return _this; -} - - -// Update the nametag display mode -var avatarNametagMode = "on"; -function handleAvatarNametagMode(newAvatarNametagMode) { - if (avatarNametagMode === "alwaysOn") { - handleAlwaysOnMode(false); - } - - avatarNametagMode = newAvatarNametagMode; - if (avatarNametagMode === "alwaysOn") { - handleAlwaysOnMode(true); - } - - if (avatarNametagMode === "off" || avatarNametagMode === "on") { - reset(); - } -} - - -// #endregion -// ************************************* -// END API -// ************************************* - - -nameTagListManager.prototype = { - create: create, - destroy: destroy, - handleSelect: handleSelect, - maybeRemove: maybeRemove, - maybeAdd: maybeAdd, - registerInitialScaler: registerInitialScaler, - updateUserScaler: updateUserScaler, - handleAvatarNametagMode: handleAvatarNametagMode, - reset: reset -}; - - -module.exports = nameTagListManager; \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js deleted file mode 100644 index c408b0ebc8..0000000000 --- a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/objectAssign.js +++ /dev/null @@ -1,32 +0,0 @@ -// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - -if (typeof Object.assign != 'function') { - // Must be writable: true, enumerable: false, configurable: true - Object.defineProperty(Object, "assign", { - value: function assign(target, varArgs) { // .length of function is 2 - 'use strict'; - if (target == null) { // TypeError if undefined or null - throw new TypeError('Cannot convert undefined or null to object'); - } - - var to = Object(target); - - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; - - if (nextSource != null) { // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }, - writable: true, - configurable: true - }); -} - diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js deleted file mode 100644 index 87d05fa838..0000000000 --- a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/pickRayController.js +++ /dev/null @@ -1,305 +0,0 @@ -// -// Simplified Nametag -// pickRayController.js -// Created by Milad Nazeri on 2019-03-08 -// Copyright 2019 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 -// -// Easy pickray controllers for Entities, Overlays, and Avatars -// - - -var _this; -function PickRayController(){ - _this = this; - - _this.rayType = null; - _this.eventHandler = null; - _this.intersection = null; - _this.lastPick = null; - _this.currentPick = null; - _this.mappingName = null; - _this.mapping = null; - _this._boundMousePressHandler = null; - _this.shouldDoublePress = null; - _this.controllEnabled = false; -} - - -// ************************************* -// START UTILITY -// ************************************* -// #region UTILITY - - -// Returns the right UUID based on hand triggered -function getUUIDFromLaser(hand) { - hand = hand === Controller.Standard.LeftHand - ? Controller.Standard.LeftHand - : Controller.Standard.RightHand; - - var pose = getControllerWorldLocation(hand); - var start = pose.position; - // Get the direction that the hand is facing in the world - var direction = Vec3.multiplyQbyV(pose.orientation, [0, 1, 0]); - - pickRayTypeHandler(start, direction); - - if (_this.currentPick) { - _this.eventHandler(_this.currentPick, _this.intersection); - } -} - - -// The following two functions are a modified version of what's found in scripts/system/libraries/controllers.js - -// Utility function for the ControllerWorldLocation offset -function getGrabPointSphereOffset(handController) { - // These values must match what's in scripts/system/libraries/controllers.js - // x = upward, y = forward, z = lateral - var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; - var offset = GRAB_POINT_SPHERE_OFFSET; - if (handController === Controller.Standard.LeftHand) { - offset = { - x: -GRAB_POINT_SPHERE_OFFSET.x, - y: GRAB_POINT_SPHERE_OFFSET.y, - z: GRAB_POINT_SPHERE_OFFSET.z - }; - } - - return Vec3.multiply(MyAvatar.sensorToWorldScale, offset); -} - - -// controllerWorldLocation is where the controller would be, in-world, with an added offset -function getControllerWorldLocation(handController, doOffset) { - var orientation; - var position; - var valid = false; - - if (handController >= 0) { - var pose = Controller.getPoseValue(handController); - valid = pose.valid; - var controllerJointIndex; - if (pose.valid) { - if (handController === Controller.Standard.RightHand) { - controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"); - } else { - controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"); - } - orientation = Quat.multiply(MyAvatar.orientation, MyAvatar.getAbsoluteJointRotationInObjectFrame(controllerJointIndex)); - position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, MyAvatar.getAbsoluteJointTranslationInObjectFrame(controllerJointIndex))); - - // add to the real position so the grab-point is out in front of the hand, a bit - if (doOffset) { - var offset = getGrabPointSphereOffset(handController); - position = Vec3.sum(position, Vec3.multiplyQbyV(orientation, offset)); - } - - } else if (!HMD.isHandControllerAvailable()) { - // NOTE: keep _this offset in sync with scripts/system/controllers/handControllerPointer.js:493 - var VERTICAL_HEAD_LASER_OFFSET = 0.1 * MyAvatar.sensorToWorldScale; - position = Vec3.sum(Camera.position, Vec3.multiplyQbyV(Camera.orientation, { x: 0, y: VERTICAL_HEAD_LASER_OFFSET, z: 0 })); - orientation = Quat.multiply(Camera.orientation, Quat.angleAxis(-90, { x: 1, y: 0, z: 0 })); - valid = true; - } - } - - return { - position: position, - translation: position, - orientation: orientation, - rotation: orientation, - valid: valid - }; -} - - -// Handle if the uuid picked on is new or different -function handleUUID(uuid){ - if (!_this.lastPick && !_this.currentPick) { - _this.currentPick = uuid; - _this.lastPick = uuid; - } else { - _this.lastPick = _this.currentPick; - _this.currentPick = uuid; - } -} - - -function pickRayTypeHandler(pickRay){ - // Handle if pickray is system generated or user generated - if (arguments.length === 2) { - pickRay = { origin: arguments[0], direction: arguments[1] }; - } - - // Each different ray pick type needs a different findRayIntersection function - switch (_this.rayType) { - case 'avatar': - var avatarIntersection = AvatarList.findRayIntersection(pickRay, [], [MyAvatar.sessionUUID], false); - _this.intersection = avatarIntersection; - handleUUID(avatarIntersection.avatarID); - break; - case 'local': - var overlayIntersection = Overlays.findRayIntersection(pickRay, [], []); - _this.intersection = overlayIntersection; - handleUUID(overlayIntersection.overlayID); - break; - case 'entity': - var entityIntersection = Entities.findRayIntersection(pickRay, [], []); - _this.intersection = entityIntersection; - handleUUID(entityIntersection.avatarID); - break; - default: - console.log("ray type not handled"); - } -} - - -// Handle the interaction when in desktop and a mouse is pressed -function mousePressHandler(event) { - if (HMD.active || !event.isLeftButton) { - return; - } - var pickRay = Camera.computePickRay(event.x, event.y); - pickRayTypeHandler(pickRay); - if (_this.currentPick) { - _this.eventHandler(_this.currentPick, _this.intersection); - } -} - - -// Function to call when double press is singled -function doublePressHandler(event) { - mousePressHandler(event); -} - - -// #endregion -// ************************************* -// END UTILITY -// ************************************* - -// ************************************* -// START API -// ************************************* -// #region API - - -// After setup is given, this gets the Controller ready to be enabled -function create(){ - _this.mapping = Controller.newMapping(_this.mappingName); - - _this.mapping.from(Controller.Standard.LTClick).to(function (value) { - if (value === 0) { - return; - } - - getUUIDFromLaser(Controller.Standard.LeftHand); - }); - - - _this.mapping.from(Controller.Standard.RTClick).to(function (value) { - if (value === 0) { - return; - } - - getUUIDFromLaser(Controller.Standard.RightHand); - }); - - return _this; -} - - -// Set type of raypick for what kind of uuids to return -function setType(type){ - _this.rayType = type; - - return _this; -} - - -// Set if double presses should register as well -function setShouldDoublePress(shouldDoublePress){ - _this.shouldDoublePress = shouldDoublePress; - - return _this; -} - - -// Set the mapping name for the controller -function setMapName(name) { - _this.mappingName = name; - - return _this; -} - - -// Enables mouse press and trigger events -function enable(){ - if (!_this.controllEnabled) { - Controller.mousePressEvent.connect(mousePressHandler); - if (_this.shouldDoublePress) { - Controller.mouseDoublePressEvent.connect(doublePressHandler); - } - Controller.enableMapping(_this.mappingName); - _this.controllEnabled = true; - - return _this; - } - - return -1; -} - - -// Disable the controller and mouse press -function disable(){ - if (_this.controllEnabled) { - Controller.mousePressEvent.disconnect(mousePressHandler); - if (_this.shouldDoublePress){ - Controller.mouseDoublePressEvent.disconnect(doublePressHandler); - } - Controller.disableMapping(_this.mappingName); - _this.controllEnabled = false; - - return _this; - } - - return -1; -} - - -// Synonym for disable -function destroy(){ - _this.disable(); -} - - -// Register the function to be called on a click -function registerEventHandler(fn){ - _this.eventHandler = fn; - - return _this; -} - - -// #endregion -// ************************************* -// END API -// ************************************* - -PickRayController.prototype = { - create: create, - setType: setType, - setShouldDoublePress: setShouldDoublePress, - setMapName: setMapName, - enable: enable, - disable: disable, - destroy: destroy, - registerEventHandler: registerEventHandler -}; - - -module.exports = PickRayController; diff --git a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js b/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js deleted file mode 100644 index 72013a2ac5..0000000000 --- a/scripts/system/simplifiedUI/simplifiedNametag/resources/modules/textHelper.js +++ /dev/null @@ -1,224 +0,0 @@ -// -// Simplified Nametag -// textHelper.js -// Created by Milad Nazeri on 2019-03-08 -// Copyright 2019 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 -// -// Module to help calculate text size -// - - -// ************************************* -// START MAPS -// ************************************* -// #region MAPS - - -var charMap = { - a: 0.05, - b: 0.051, - c: 0.05, - d: 0.051, - e: 0.05, - f: 0.035, - g: 0.051, - h: 0.051, - i: 0.025, - j: 0.025, - k: 0.05, - l: 0.025, - m: 0.0775, - n: 0.051, - o: 0.051, - p: 0.051, - q: 0.051, - r: 0.035, - s: 0.05, - t: 0.035, - u: 0.051, - v: 0.05, - w: 0.07, - x: 0.05, - y: 0.05, - z: 0.05, - A: 0.06, - B: 0.06, - C: 0.06, - D: 0.06, - E: 0.05, - F: 0.05, - G: 0.06, - H: 0.0625, - I: 0.0275, - J: 0.05, - K: 0.06, - L: 0.05, - M: 0.075, - N: 0.0625, - O: 0.0625, - P: 0.06, - Q: 0.0625, - R: 0.06, - S: 0.06, - T: 0.06, - U: 0.06, - V: 0.06, - W: 0.075, - X: 0.06, - Y: 0.06, - Z: 0.06 -}; - -var symbolMap = { - "!": 0.025, - "@": 0.08, - "#": 0.07, - "$": 0.058, - "%": 0.07, - "^": 0.04, - "&": 0.06, - "*": 0.04, - "(": 0.04, - ")": 0.04, - "_": 0.041, - "{": 0.034, - "}": 0.034, - "/": 0.04, - "|": 0.02, - "<": 0.049, - ">": 0.049, - "[": 0.0300, - "]": 0.0300, - ".": 0.0260, - ",": 0.0260, - "?": 0.048, - "~": 0.0610, - "`": 0.0310, - "+": 0.0510, - "=": 0.0510 -}; - - -// #endregion -// ************************************* -// END MAPS -// ************************************* - -var _this = null; -function TextHelper(){ - _this = this; - - this.text = ""; - this.textArray = ""; - this.lineHeight = 0; - this.totalTextLength = 0; - this.scaler = 1.0; -} - - -// ************************************* -// START UTILITY -// ************************************* -// #region UTILITY - - -// Split the string into a text array to be operated on -function createTextArray(){ - _this.textArray = _this.text.split(""); -} - - -// Account for the text length -function adjustForScale(defaultTextLength){ - _this.totalTextLength = defaultTextLength * _this.scaler; -} - - -// #endregion -// ************************************* -// END UTILITY -// ************************************* - -// #endregion -// ************************************* -// END name -// ************************************* - -// ************************************* -// START API -// ************************************* -// #region API - - -// Set the text that needs to be calculated on -function setText(newText){ - _this.text = newText; - createTextArray(); - - return _this; -} - - -// Set the line height which helps calculate the font size -var DEFAULT_LINE_HEIGHT = 0.1; -function setLineHeight(newLineHeight){ - _this.lineHeight = newLineHeight; - _this.scaler = _this.lineHeight / DEFAULT_LINE_HEIGHT; - - return _this; -} - - -// Calculate the sign dimensions -var DEFAULT_CHAR_SIZE = 0.025; -var NUMBER = 0.05; -var DIGIT_REGEX = /\d/g; -var WHITE_SPACE_REGEX = /[ ]/g; -var SPACE = 0.018; -function getTotalTextLength(){ - // Map the string array to it's sizes - var lengthArray = _this.textArray.map(function(letter){ - if (charMap[letter]){ - return charMap[letter]; - } else if (letter.match(DIGIT_REGEX)){ - return NUMBER; - } else if (symbolMap[letter]) { - return symbolMap[letter]; - } else if (letter.match(WHITE_SPACE_REGEX)) { - return SPACE; - } else { - return DEFAULT_CHAR_SIZE; - } - }); - - // add up all the values in the array - var defaultTextLength = lengthArray.reduce(function(prev, curr){ - return prev + curr; - }, 0); - - adjustForScale(defaultTextLength); - - return _this.totalTextLength; -} - - -// #endregion -// ************************************* -// END API -// ************************************* - -TextHelper.prototype = { - setText: setText, - setLineHeight: setLineHeight, - getTotalTextLength: getTotalTextLength -}; - -module.exports = TextHelper; - -// var text = new TextHelper(); -// text.setText("lowbar"); -// text.setLineHeight("0.1"); -// text.getTotalTextLength(); \ No newline at end of file diff --git a/scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js b/scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js deleted file mode 100644 index 9b4d9cfad3..0000000000 --- a/scripts/system/simplifiedUI/simplifiedNametag/simplifiedNametag.js +++ /dev/null @@ -1,95 +0,0 @@ -// -// Simplified Nametag -// Created by Milad Nazeri on 2019-02-16 -// Copyright 2019 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 -// -// Click on someone to get a nametag for them -// -var PickRayController = Script.require('./resources/modules/pickRayController.js?' + Date.now()); -var NameTagListManager = Script.require('./resources/modules/nameTagListManager.js?' + Date.now()); -var pickRayController = new PickRayController(); -var nameTagListManager = new NameTagListManager(); - -// Handles avatar being solo'd -pickRayController - .registerEventHandler(selectAvatar) - .setType("avatar") - .setMapName("hifi_simplifiedNametag") - .setShouldDoublePress(true) - .create() - .enable(); - - -function selectAvatar(uuid, intersection) { - nameTagListManager.handleSelect(uuid, intersection); -} - - -// Handles reset of list if you change domains -function onDomainChange() { - nameTagListManager.reset(); -} - - -// Handles removing an avatar from the list if they leave the domain -function onAvatarRemoved(uuid) { - nameTagListManager.maybeRemove(uuid); -} - - -// Automatically add an avatar if they come into the domain. Mainly used for alwaysOn mode. -function onAvatarAdded(uuid) { - nameTagListManager.maybeAdd(uuid); -} - - -// Called on init -var avatarNametagMode; -function create() { - nameTagListManager.create(); - handleAvatarNametagMode(Settings.getValue("simplifiedNametag/avatarNametagMode", "on")); - - Window.domainChanged.connect(onDomainChange); - AvatarManager.avatarRemovedEvent.connect(onAvatarRemoved); - AvatarManager.avatarAddedEvent.connect(onAvatarAdded); -} - - -// Called when the script is closing -function destroy() { - nameTagListManager.destroy(); - pickRayController.destroy(); - Window.domainChanged.disconnect(onDomainChange); - AvatarManager.avatarRemovedEvent.disconnect(onAvatarRemoved); - AvatarManager.avatarAddedEvent.disconnect(onAvatarAdded); -} - - -// chose which mode you want the nametags in. On, off, or alwaysOn. -function handleAvatarNametagMode(newAvatarNameTagMode) { - avatarNametagMode = newAvatarNameTagMode; - nameTagListManager.handleAvatarNametagMode(avatarNametagMode); - Settings.setValue("simplifiedNametag/avatarNametagMode", avatarNametagMode); -} - - -// ************************************* -// START api -// ************************************* -// #region api - - -module.exports = { - create: create, - destroy: destroy, - handleAvatarNametagMode: handleAvatarNametagMode -}; - - -// #endregion -// ************************************* -// END api -// ************************************* \ No newline at end of file From 46475c23c16b216211f9923c2d3e88e6fd1a4edc Mon Sep 17 00:00:00 2001 From: milad Date: Fri, 24 May 2019 13:59:01 -0700 Subject: [PATCH 3/5] removed log --- .../ui/simplifiedNametag/resources/modules/nameTagListManager.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js index 1d5ead6975..18015a8d0c 100644 --- a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js +++ b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js @@ -10,7 +10,6 @@ // Helps manage the list of avatars added to the nametag list // -console.log("\nm\n\n\n\n\n\n\n\n\nTEST!!!\n\n\n\n\n\n") var EntityMaker = Script.require('./entityMaker.js?' + Date.now()); var entityProps = Script.require('./defaultLocalEntityProps.js?' + Date.now()); var textHelper = new (Script.require('./textHelper.js?' + Date.now())); From 81dd097940d8302268d2b87e7ea83eab7ba0dec6 Mon Sep 17 00:00:00 2001 From: milad Date: Fri, 24 May 2019 14:00:32 -0700 Subject: [PATCH 4/5] added an extra line --- .../ui/simplifiedNametag/resources/modules/nameTagListManager.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js index 18015a8d0c..a1479953bb 100644 --- a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js +++ b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js @@ -232,6 +232,7 @@ function nameTagListManager() { _this.redrawTimeout = null; } + // Get the correct display name function getCorrectName(uuid) { var avatar = _this.avatars[uuid]; From 03600f23ba74c355d42d9691277491192b8497f0 Mon Sep 17 00:00:00 2001 From: milad Date: Fri, 24 May 2019 14:12:36 -0700 Subject: [PATCH 5/5] removed terenary expression --- .../resources/modules/nameTagListManager.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js index a1479953bb..f8b6f2e6cd 100644 --- a/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js +++ b/scripts/simplifiedUI/ui/simplifiedNametag/resources/modules/nameTagListManager.js @@ -238,13 +238,15 @@ function getCorrectName(uuid) { var avatar = _this.avatars[uuid]; var avatarInfo = avatar.avatarInfo; - var displayNameToUse = avatarInfo.sessionDisplayName; + var displayNameToUse = avatarInfo.sessionDisplayName.trim(); + if (displayNameToUse === "") { - displayNameToUse = avatarInfo.displayName; + displayNameToUse = avatarInfo.displayName.trim(); } - - displayNameToUse= displayNameToUse === "" ? "anonymous" : displayNameToUse.trim(); + if (displayNameToUse === "") { + displayNameToUse = "anonymous"; + } return displayNameToUse; }