merge with master

This commit is contained in:
SamGondelman 2019-07-03 17:47:12 -07:00
commit 8b9fcd43b1
656 changed files with 49479 additions and 5243 deletions

View file

@ -106,3 +106,4 @@ The following build options can be used when running CMake
#### Devices
You can support external input/output devices such as Leap Motion, MIDI, and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device.

View file

@ -31,9 +31,9 @@ If you do not wish to use the Python installation bundled with Visual Studio, yo
### Step 2. Installing CMake
Download and install the latest version of CMake 3.9.
Download and install the latest version of CMake 3.14.
Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.9 Version page](https://cmake.org/files/v3.9/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted.
Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.14 Version page](https://cmake.org/files/v3.14/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted.
### Step 3. Create VCPKG environment variable
In the next step, you will use CMake to build High Fidelity. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them.

View file

@ -139,6 +139,7 @@ option(BUILD_MANUAL_TESTS "Build manual tests" ${BUILD_MANUAL_TESTS_OPTION})
option(BUILD_TOOLS "Build tools" ${BUILD_TOOLS_OPTION})
option(BUILD_INSTALLER "Build installer" ${BUILD_INSTALLER_OPTION})
option(USE_GLES "Use OpenGL ES" ${GLES_OPTION})
option(USE_KHR_ROBUSTNESS "Use KHR_robustness" OFF)
option(DISABLE_QML "Disable QML" ${DISABLE_QML_OPTION})
option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF)
option(
@ -149,6 +150,10 @@ option(
set(PLATFORM_QT_GL OpenGL)
if (USE_KHR_ROBUSTNESS)
add_definitions(-DUSE_KHR_ROBUSTNESS)
endif()
if (USE_GLES)
add_definitions(-DUSE_GLES)
add_definitions(-DGPU_POINTER_STORAGE_SHARED)

View file

@ -74,7 +74,8 @@
* avatar. <em>Read-only.</em>
* @property {number} sensorToWorldScale - The scale that transforms dimensions in the user's real world to the avatar's
* size in the virtual world. <em>Read-only.</em>
* @property {boolean} hasPriority - is the avatar in a Hero zone? <em>Read-only.</em>
* @property {boolean} hasPriority - <code>true</code> if the avatar is in a "hero" zone, <code>false</code> if it isn't.
* <em>Read-only.</em>
*
* @example <caption>Create a scriptable avatar.</caption>
* (function () {
@ -138,6 +139,9 @@ public:
/// Returns the index of the joint with the specified name, or -1 if not found/unknown.
Q_INVOKABLE virtual int getJointIndex(const QString& name) const override;
/**jsdoc
* @comment Uses the base class's JSDoc.
*/
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
/**jsdoc

View file

@ -57,7 +57,7 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
if (message->getSize() == 0) {
return;
}
QDataStream packetStream(message->getMessage());
// read a NodeConnectionData object from the packet so we can pass around this data while we're inspecting it
@ -88,11 +88,10 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
auto pendingAssignment = _pendingAssignedNodes.find(nodeConnection.connectUUID);
SharedNodePointer node;
QString username;
if (pendingAssignment != _pendingAssignedNodes.end()) {
node = processAssignmentConnectRequest(nodeConnection, pendingAssignment->second);
} else if (!STATICALLY_ASSIGNED_NODES.contains(nodeConnection.nodeType)) {
QString username;
QByteArray usernameSignature;
if (message->getBytesLeftToRead() > 0) {
@ -122,9 +121,14 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
nodeData->setNodeInterestSet(safeInterestSet);
nodeData->setPlaceName(nodeConnection.placeName);
qDebug() << "Allowed connection from node" << uuidStringWithoutCurlyBraces(node->getUUID())
<< "on" << message->getSenderSockAddr() << "with MAC" << nodeConnection.hardwareAddress
<< "and machine fingerprint" << nodeConnection.machineFingerprint;
qDebug() << "Allowed connection from node" << uuidStringWithoutCurlyBraces(node->getUUID())
<< "on" << message->getSenderSockAddr()
<< "with MAC" << nodeConnection.hardwareAddress
<< "and machine fingerprint" << nodeConnection.machineFingerprint
<< "user" << username
<< "reason" << QString(nodeConnection.connectReason ? "SilentDomainDisconnect" : "Connect")
<< "previous connection uptime" << nodeConnection.previousConnectionUpTime/USECS_PER_MSEC << "msec"
<< "sysinfo" << nodeConnection.SystemInfo;
// signal that we just connected a node so the DomainServer can get it a list
// and broadcast its presence right away
@ -132,7 +136,8 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
} else {
qDebug() << "Refusing connection from node at" << message->getSenderSockAddr()
<< "with hardware address" << nodeConnection.hardwareAddress
<< "and machine fingerprint" << nodeConnection.machineFingerprint;
<< "and machine fingerprint" << nodeConnection.machineFingerprint
<< "sysinfo" << nodeConnection.SystemInfo;
}
}
@ -468,7 +473,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
if (node->getPublicSocket() == nodeConnection.publicSockAddr && node->getLocalSocket() == nodeConnection.localSockAddr) {
// we have a node that already has these exact sockets
// this can occur if a node is failing to connect to the domain
// remove the old node before adding the new node
qDebug() << "Deleting existing connection from same sockaddr: " << node->getUUID();
existingNodeID = node->getUUID();
@ -842,7 +847,7 @@ void DomainGatekeeper::processICEPingPacket(QSharedPointer<ReceivedMessage> mess
// before we respond to this ICE ping packet, make sure we have a peer in the list that matches
QUuid icePeerID = QUuid::fromRfc4122({ message->getRawMessage(), NUM_BYTES_RFC4122_UUID });
if (_icePeers.contains(icePeerID)) {
auto pingReplyPacket = limitedNodeList->constructICEPingReplyPacket(*message, limitedNodeList->getSessionUUID());
@ -882,7 +887,6 @@ void DomainGatekeeper::getGroupMemberships(const QString& username) {
QJsonArray groupIDs = QJsonArray::fromStringList(groupIDSet.toList());
json["groups"] = groupIDs;
// if we've already asked, wait for the answer before asking again
QString lowerUsername = username.toLower();
if (_inFlightGroupMembershipsRequests.contains(lowerUsername)) {
@ -969,7 +973,7 @@ void DomainGatekeeper::getDomainOwnerFriendsList() {
QNetworkAccessManager::GetOperation, callbackParams, QByteArray(),
NULL, QVariantMap());
}
}
void DomainGatekeeper::getDomainOwnerFriendsListJSONCallback(QNetworkReply* requestReply) {

View file

@ -739,6 +739,10 @@ void DomainServer::setupNodeListAndAssignments() {
connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded);
connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled);
connect(nodeList.data(), &LimitedNodeList::localSockAddrChanged, this,
[this](const HifiSockAddr& localSockAddr) {
DependencyManager::get<LimitedNodeList>()->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, localSockAddr.getPort());
});
// register as the packet receiver for the types we want
PacketReceiver& packetReceiver = nodeList->getPacketReceiver();
@ -1079,7 +1083,7 @@ void DomainServer::processListRequestPacket(QSharedPointer<ReceivedMessage> mess
// client-side send time of last connect/domain list request
nodeData->setLastDomainCheckinTimestamp(nodeRequestData.lastPingTimestamp);
sendDomainListToNode(sendingNode, message->getFirstPacketReceiveTime(), message->getSenderSockAddr());
sendDomainListToNode(sendingNode, message->getFirstPacketReceiveTime(), message->getSenderSockAddr(), false);
}
bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) {
@ -1145,7 +1149,7 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode, quint64 reques
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(newNode->getLinkedData());
// reply back to the user with a PacketType::DomainList
sendDomainListToNode(newNode, requestReceiveTime, nodeData->getSendingSockAddr());
sendDomainListToNode(newNode, requestReceiveTime, nodeData->getSendingSockAddr(), true);
// if this node is a user (unassigned Agent), signal
if (newNode->getType() == NodeType::Agent && !nodeData->wasAssigned()) {
@ -1161,7 +1165,7 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode, quint64 reques
broadcastNewNode(newNode);
}
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr &senderSockAddr) {
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr &senderSockAddr, bool newConnection) {
const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID +
NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + 4;
@ -1181,6 +1185,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 r
extendedHeaderStream << nodeData->getLastDomainCheckinTimestamp();
extendedHeaderStream << quint64(duration_cast<microseconds>(system_clock::now().time_since_epoch()).count());
extendedHeaderStream << quint64(duration_cast<microseconds>(p_high_resolution_clock::now().time_since_epoch()).count()) - requestPacketReceiveTime;
extendedHeaderStream << newConnection;
auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader);
// always send the node their own UUID back
@ -1734,7 +1739,12 @@ void DomainServer::nodePingMonitor() {
nodeList->eachNode([now](const SharedNodePointer& node) {
quint64 lastHeard = now - node->getLastHeardMicrostamp();
if (lastHeard > 2 * USECS_PER_SECOND) {
qCDebug(domain_server) << "Haven't heard from " << node->getPublicSocket() << " in " << lastHeard / USECS_PER_MSEC << " msec";
QString username;
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(node->getLinkedData());
if (nodeData) {
username = nodeData->getUsername();
}
qCDebug(domain_server) << "Haven't heard from " << node->getPublicSocket() << username << " in " << lastHeard / USECS_PER_MSEC << " msec";
}
});
}

View file

@ -173,7 +173,7 @@ private:
void handleKillNode(SharedNodePointer nodeToKill);
void broadcastNodeDisconnect(const SharedNodePointer& disconnnectedNode);
void sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr& senderSockAddr);
void sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr& senderSockAddr, bool newConnection);
bool isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB);

View file

@ -35,6 +35,17 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c
// now the machine fingerprint
dataStream >> newHeader.machineFingerprint;
// and the operating system type
QByteArray compressedSystemInfo;
dataStream >> compressedSystemInfo;
if (!compressedSystemInfo.isEmpty()) {
newHeader.SystemInfo = qUncompress(compressedSystemInfo);
}
dataStream >> newHeader.connectReason;
dataStream >> newHeader.previousConnectionUpTime;
}
dataStream >> newHeader.lastPingTimestamp;

View file

@ -31,7 +31,9 @@ public:
QString placeName;
QString hardwareAddress;
QUuid machineFingerprint;
QString SystemInfo;
quint32 connectReason;
quint64 previousConnectionUpTime;
QByteArray protocolVersion;
};

View file

@ -1463,7 +1463,7 @@
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.5, 1.8, 2.3, 3.2, 4.5],
"characteristicSpeeds": [0.5, 1.8, 2.3, 3.0, 5.0],
"alphaVar": "moveForwardAlpha",
"desiredSpeedVar": "moveForwardSpeed"
},
@ -1509,8 +1509,8 @@
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/jog_fwd.fbx",
"startFrame": 0.0,
"endFrame": 25.0,
"startFrame": 1.0,
"endFrame": 22.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -1522,7 +1522,7 @@
"data": {
"url": "qrc:///avatar/animations/run_fwd.fbx",
"startFrame": 1.0,
"endFrame": 22.0,
"endFrame": 23.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -2099,4 +2099,4 @@
}
]
}
}
}

View file

@ -269,6 +269,9 @@ Item {
StatText {
text: "GPU: " + root.gpuFrameTime.toFixed(1) + " ms"
}
StatText {
text: "LOD Target: " + root.lodTargetFramerate + " Hz Angle: " + root.lodAngle + " deg"
}
StatText {
text: "Drawcalls: " + root.drawcalls
}

View file

@ -29,16 +29,6 @@ WebView {
userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard ]
onFeaturePermissionRequested: {
if (feature == 2) { // QWebEnginePage::MediaAudioCapture
grantFeaturePermission(securityOrigin, feature, true);
} else {
permissionsBar.securityOrigin = securityOrigin;
permissionsBar.feature = feature;
parentRoot.showPermissionsBar();
}
}
onLoadingChanged: {
if (loadRequest.status === WebEngineView.LoadSucceededStatus) {
addressBar.text = loadRequest.url

View file

@ -84,7 +84,7 @@ Item {
}
onFeaturePermissionRequested: {
grantFeaturePermission(securityOrigin, feature, true);
grantFeaturePermission(securityOrigin, feature, false);
}
onLoadingChanged: {

View file

@ -53,6 +53,9 @@ Item {
StatText {
text: root.recenterText
}
StatText {
text: root.overrideJointText
}
StatText {
text: "Anim Vars:--------------------------------------------------------------------------------"
}
@ -98,6 +101,9 @@ Item {
StatText {
text: root.sittingText
}
StatText {
text: root.flowText
}
StatText {
text: "State Machines:---------------------------------------------------------------------------"
}
@ -131,6 +137,9 @@ Item {
StatText {
text: root.walkingText
}
StatText {
text: root.networkGraphText
}
StatText {
text: "Alpha Values:--------------------------------------------------------------------------"
}

View file

@ -58,6 +58,7 @@ Windows.Window {
}
QmlSurface.load(source, contentHolder, function(newObject) {
dynamicContent = newObject;
updateInteractiveWindowSizeForMode();
if (dynamicContent && dynamicContent.anchors) {
dynamicContent.anchors.fill = contentHolder;
}
@ -81,10 +82,12 @@ Windows.Window {
}
function updateInteractiveWindowSizeForMode() {
if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
width = interactiveWindowSize.width;
height = interactiveWindowSize.height;
} else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
root.width = interactiveWindowSize.width;
root.height = interactiveWindowSize.height;
contentHolder.width = interactiveWindowSize.width;
contentHolder.height = interactiveWindowSize.height;
if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
nativeWindow.width = interactiveWindowSize.width;
nativeWindow.height = interactiveWindowSize.height;
}
@ -134,6 +137,9 @@ Windows.Window {
Window {
id: root;
width: interactiveWindowSize.width
height: interactiveWindowSize.height
Rectangle {
color: hifi.colors.baseGray
anchors.fill: parent

View file

@ -13,15 +13,14 @@ import QtQuick 2.4
import controlsUit 1.0 as HifiControlsUit
import stylesUit 1.0 as HifiStylesUit
import "LoginDialog"
FocusScope {
id: root
HifiStylesUit.HifiConstants { id: hifi }
objectName: "LoginDialog"
property bool shown: true
visible: shown
HifiStylesUit.HifiConstants { id: hifi }
anchors.fill: parent
readonly property bool isTablet: false
@ -33,12 +32,17 @@ FocusScope {
property bool keyboardRaised: false
property bool punctuationMode: false
property bool isPassword: false
property string title: ""
property string text: ""
property int titleWidth: 0
property alias bannerWidth: banner.width
property alias bannerHeight: banner.height
property string title: ""
property string text: ""
property int titleWidth: 0
property bool isHMD: HMD.active
function tryDestroy() {
root.destroy()
}

View file

@ -259,6 +259,35 @@ Item {
visible: root.expanded;
text: "Entity Servers In: " + root.entityPacketsInKbps + " kbps";
}
StatText {
visible: !root.expanded
text: "Octree Elements Server: " + root.serverElements +
" Local: " + root.localElements;
}
StatText {
visible: root.expanded
text: "Octree Sending Mode: " + root.sendingMode;
}
StatText {
visible: root.expanded
text: "Octree Packets to Process: " + root.packetStats;
}
StatText {
visible: root.expanded
text: "Octree Elements - ";
}
StatText {
visible: root.expanded
text: "\tServer: " + root.serverElements +
" Internal: " + root.serverInternal +
" Leaves: " + root.serverLeaves;
}
StatText {
visible: root.expanded
text: "\tLocal: " + root.localElements +
" Internal: " + root.localInternal +
" Leaves: " + root.localLeaves;
}
StatText {
visible: root.expanded;
text: "Downloads: " + root.downloads + "/" + root.downloadLimit +
@ -311,10 +340,13 @@ Item {
text: "GPU: " + root.gpuFrameTime.toFixed(1) + " ms"
}
StatText {
text: "GPU (Per pixel): " + root.gpuFrameTimePerPixel.toFixed(5) + " ns/pp"
text: "GPU (Per pixel): " + root.gpuFrameTimePerPixel.toFixed(1) + " ns/pp"
}
StatText {
text: "GPU frame size: " + root.gpuFrameSize.x + " x " + root.gpuFrameSize.y
text: "GPU frame size: " + root.gpuFrameSize.x.toFixed(0) + " x " + root.gpuFrameSize.y.toFixed(0)
}
StatText {
text: "LOD Target: " + root.lodTargetFramerate + " Hz Angle: " + root.lodAngle + " deg"
}
StatText {
text: "Drawcalls: " + root.drawcalls
@ -401,35 +433,6 @@ Item {
text: " out of view: " + root.shadowOutOfView +
" too small: " + root.shadowTooSmall;
}
StatText {
visible: !root.expanded
text: "Octree Elements Server: " + root.serverElements +
" Local: " + root.localElements;
}
StatText {
visible: root.expanded
text: "Octree Sending Mode: " + root.sendingMode;
}
StatText {
visible: root.expanded
text: "Octree Packets to Process: " + root.packetStats;
}
StatText {
visible: root.expanded
text: "Octree Elements - ";
}
StatText {
visible: root.expanded
text: "\tServer: " + root.serverElements +
" Internal: " + root.serverInternal +
" Leaves: " + root.serverLeaves;
}
StatText {
visible: root.expanded
text: "\tLocal: " + root.localElements +
" Internal: " + root.localInternal +
" Leaves: " + root.localLeaves;
}
StatText {
visible: root.expanded
text: "LOD: " + root.lodStatus;

View file

@ -141,7 +141,7 @@ Item {
}
onFeaturePermissionRequested: {
grantFeaturePermission(securityOrigin, feature, true);
grantFeaturePermission(securityOrigin, feature, false);
}
//disable popup

View file

@ -0,0 +1,25 @@
module controls
Button 1.0 Button.qml
ButtonAwesome 1.0 ButtonAwesome.qml
CheckBox 1.0 CheckBox.qml
ComboBox 1.0 ComboBox.qml
FlickableWebViewCore 1.0 FlickableWebViewCore.qml
FontAwesome 1.0 FontAwesome.qml
Player 1.0 Player.qml
RadioButton 1.0 RadioButton.qml
Slider 1.0 Slider.qml
Spacer 1.0 Spacer.qml
SpinBox 1.0 SpinBox.qml
TabletWebButton 1.0 TabletWebButton.qml
TabletWebScreen 1.0 TabletWebScreen.qml
TabletWebView 1.0 TabletWebView.qml
Text 1.0 Text.qml
TextAndSlider 1.0 TextAndSlider.qml
TextAndSpinBox 1.0 TextAndSpinBox.qml
TextArea 1.0 TextArea.qml
TextEdit 1.0 TextEdit.qml
TextField 1.0 TextField.qml
TextHeader 1.0 TextHeader.qml
TextInput 1.0 TextInput.qml
TextInputAndButton 1.0 TextInputAndButton.qml
WebView 1.0 WebView.qml

View file

@ -35,4 +35,8 @@ WebEngineView {
}
WebSpinner { }
onFeaturePermissionRequested: {
grantFeaturePermission(securityOrigin, feature, false);
}
}

View file

@ -23,43 +23,36 @@ FocusScope {
objectName: "LoginDialog"
visible: true
HifiStylesUit.HifiConstants { id: hifi }
anchors.fill: parent
width: parent.width
height: parent.height
property var tabletProxy: Tablet.getTablet("com.highfidelity.interface.tablet.system");
property bool isHMD: HMD.active
property bool gotoPreviousApp: false;
readonly property bool isTablet: true
readonly property bool isOverlay: false
property string iconText: hifi.glyphs.avatar
property int iconSize: 35
property bool keyboardEnabled: false
property bool keyboardRaised: false
property bool punctuationMode: false
property bool isPassword: false
readonly property bool isTablet: true
readonly property bool isOverlay: false
property alias text: loginKeyboard.mirroredText
property int titleWidth: 0
property alias bannerWidth: banner.width
property alias bannerHeight: banner.height
property string iconText: hifi.glyphs.avatar
property int iconSize: 35
property var pane: QtObject {
property real width: root.width
property real height: root.height
}
property int titleWidth: 0
function tryDestroy() {
tabletProxy.gotoHomeScreen();
}
property bool isHMD: HMD.active
MouseArea {
width: root.width
height: root.height
}
// TABLET SPECIFIC PROPERTIES START //
property alias text: loginKeyboard.mirroredText
width: parent.width
height: parent.height
property var tabletProxy: Tablet.getTablet("com.highfidelity.interface.tablet.system")
property bool gotoPreviousApp: false
property bool keyboardOverride: true
@ -70,7 +63,20 @@ FocusScope {
property alias loginDialog: loginDialog
property alias hifi: hifi
HifiStylesUit.HifiConstants { id: hifi }
property var pane: QtObject {
property real width: root.width
property real height: root.height
}
MouseArea {
width: root.width
height: root.height
}
// TABLET SPECIFIC PROPERTIES END //
function tryDestroy() {
tabletProxy.gotoHomeScreen();
}
Timer {
id: keyboardTimer
@ -102,6 +108,15 @@ FocusScope {
anchors.fill: parent
}
Rectangle {
z: -6
id: opaqueRect
height: parent.height
width: parent.width
opacity: 0.65
color: "black"
}
Item {
z: -5
id: bannerContainer
@ -119,15 +134,6 @@ FocusScope {
}
}
Rectangle {
z: -6
id: opaqueRect
height: parent.height
width: parent.width
opacity: 0.65
color: "black"
}
HifiControlsUit.Keyboard {
id: loginKeyboard
raised: root.keyboardEnabled && root.keyboardRaised

View file

@ -12,6 +12,8 @@ import controlsUit 1.0
OriginalDesktop.Desktop {
id: desktop
property alias toolbarObjectName: sysToolbar.objectName
MouseArea {
id: hoverWatch
anchors.fill: parent
@ -70,7 +72,12 @@ OriginalDesktop.Desktop {
x: sysToolbar.x
buttonModel: tablet ? tablet.buttons : null;
shown: tablet ? tablet.toolbarMode : false;
onVisibleChanged: {
desktop.toolbarVisibleChanged(visible, sysToolbar.objectName);
}
}
signal toolbarVisibleChanged(bool isVisible, string toolbarName);
QtSettings.Settings {
id: settings;

View file

@ -0,0 +1,18 @@
module dialogs
AboutDialog 1.0 AboutDialog.qml
AdvancedPreferencesDialog 1.0 AdvancedPreferencesDialog.qml
AudioBuffers 1.0 AudioBuffers.qml
AvatarPreferencesDialog 1.0 AvatarPreferencesDialog.qml
GeneralPreferencesDialog 1.0 GeneralPreferencesDialog.qml
LodPreferencesDialog 1.0 LodPreferencesDialog.qml
ModelBrowserDialog 1.0 ModelBrowserDialog.qml
NetworkingPreferencesDialog 1.0 NetworkingPreferencesDialog.qml
RunningScripts 1.0 RunningScripts.qml
TabletAboutDialog 1.0 TabletAboutDialog.qml
TabletAssetServer 1.0 TabletAssetServer.qml
TabletDCDialog 1.0 TabletDCDialog.qml
TabletDebugWindow 1.0 TabletDebugWindow.qml
TabletEntityStatistics 1.0 TabletEntityStatistics.qml
TabletEntityStatisticsItem 1.0 TabletEntityStatisticsItem.qml
TabletLODTools 1.0 TabletLODTools.qml
TabletRunningScripts 1.0 TabletRunningScripts.qml

View file

@ -75,21 +75,31 @@ ListModel {
// 1: equivalent to paging when reaching end (and not before).
// 0: don't getNextPage on scroll at all here. The application code will do it.
property real pageAhead: 2.0;
function needsEarlyYFetch() {
return flickable
&& !flickable.atYBeginning
&& (flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height));
function onContentXChanged() {
if (flickable &&
!flickable.atXBeginning &&
(flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width))) {
getNextPage();
}
}
function needsEarlyXFetch() {
return flickable
&& !flickable.atXBeginning
&& (flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width));
function onContentYChanged() {
if (flickable &&
!flickable.atYBeginning &&
(flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height))) {
getNextPage();
}
}
function getNextPageIfHorizontalScroll() {
if (needsEarlyXFetch()) { getNextPage(); }
function onWidthChanged() {
if (flickable &&
(flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width))) {
getNextPage();
}
}
function getNextPageIfVerticalScroll() {
if (needsEarlyYFetch()) { getNextPage(); }
function onHeightChanged() {
if (flickable &&
(flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height))) {
getNextPage();
}
}
function needsMoreHorizontalResults() {
return flickable
@ -118,8 +128,10 @@ ListModel {
initialized = true;
if (flickable && pageAhead > 0.0) {
// Pun: Scrollers are usually one direction or another, such that only one of the following will actually fire.
flickable.contentXChanged.connect(getNextPageIfHorizontalScroll);
flickable.contentYChanged.connect(getNextPageIfVerticalScroll);
flickable.contentXChanged.connect(onContentXChanged);
flickable.contentYChanged.connect(onContentYChanged);
flickable.widthChanged.connect(onWidthChanged);
flickable.heightChanged.connect(onHeightChanged);
flickable.contentWidthChanged.connect(getNextPageIfNotEnoughHorizontalResults);
flickable.contentHeightChanged.connect(getNextPageIfNotEnoughVerticalResults);
}

View file

@ -0,0 +1,3 @@
module hifiModels
PSFListModel 1.0 PSFListModel.qml
S3Model 1.0 S3Model.qml

View file

@ -10,6 +10,7 @@
import QtQuick 2.10
import "../simplifiedConstants" as SimplifiedConstants
import "../simplifiedControls" as SimplifiedControls
import "./components" as AvatarAppComponents
import stylesUit 1.0 as HifiStylesUit
import TabletScriptingInterface 1.0
@ -88,7 +89,7 @@ Rectangle {
Image {
id: accent
source: "../images/accent.svg"
source: "images/accent.svg"
anchors.top: parent.top
anchors.right: parent.right
width: 60
@ -122,7 +123,7 @@ Rectangle {
Tablet.playSound(TabletEnums.ButtonClick);
// Can't use `Window.location` in QML, so just use what setting `Window.location` actually calls under the hood:
// AddressManager.handleLookupString().
AddressManager.handleLookupString(LocationBookmarks.getHomeLocationAddress());
AddressManager.handleLookupString(LocationBookmarks.getAddress("hqhome"));
}
}
}
@ -245,6 +246,10 @@ Rectangle {
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
SimplifiedControls.VerticalScrollBar {
parent: inventoryContentsList
}
}

View file

@ -94,6 +94,7 @@ Item {
text: MyAvatar.sessionDisplayName === "" ? MyAvatar.displayName : MyAvatar.sessionDisplayName
maximumLength: 256
clip: true
selectByMouse: true
anchors.fill: parent
onEditingFinished: {
if (MyAvatar.displayName !== text) {

View file

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 268 B

View file

@ -33,6 +33,7 @@ Rectangle {
readonly property string unmutedIcon: "images/mic-unmute-i.svg"
readonly property string mutedIcon: "images/mic-mute-i.svg"
readonly property string pushToTalkIcon: "images/mic-ptt-i.svg"
readonly property string pushToTalkMutedIcon: "images/mic-ptt-mute-i.svg"
readonly property string clippingIcon: "images/mic-clip-i.svg"
readonly property string gatedIcon: "images/mic-gate-i.svg"
@ -48,18 +49,6 @@ Rectangle {
}
}
opacity: 0.7
onLevelChanged: {
var rectOpacity = (muted && (level >= userSpeakingLevel)) ? 1.0 : 0.7;
if (pushToTalk && !pushingToTalk) {
rectOpacity = (mouseArea.containsMouse) ? 1.0 : 0.7;
} else if (mouseArea.containsMouse && rectOpacity != 1.0) {
rectOpacity = 1.0;
}
micBar.opacity = rectOpacity;
}
color: "#00000000"
MouseArea {
@ -116,82 +105,84 @@ Rectangle {
Item {
id: icon
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.horizontalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.rightMargin: 2
width: 13
height: 21
width: pushToTalk ? 16 : (muted ? 20 : 16)
height: 22
Item {
anchors.fill: parent
opacity: mouseArea.containsMouse ? 1.0 : 0.7
Image {
id: image
visible: false
source: (pushToTalk) ? pushToTalkIcon : muted ? mutedIcon :
clipping ? clippingIcon : gated ? gatedIcon : unmutedIcon
anchors.fill: parent
fillMode: Image.PreserveAspectFit
}
ColorOverlay {
opacity: mouseArea.containsMouse ? 1.0 : 0.7
visible: level === 0 || micBar.muted || micBar.clipping
id: imageOverlay
anchors { fill: image }
source: image
color: pushToTalk ? (pushingToTalk ? colors.unmutedColor : colors.mutedColor) : colors.icon
color: pushToTalk ? (pushingToTalk ? colors.icon : colors.mutedColor) : colors.icon
}
OpacityMask {
id: bar
visible: level > 0 && !micBar.muted && !micBar.clipping
anchors.fill: meterGradient
source: meterGradient
maskSource: image
}
LinearGradient {
id: meterGradient
anchors { fill: parent }
visible: false
start: Qt.point(0, 0)
end: Qt.point(0, parent.height)
rotation: 180
gradient: Gradient {
GradientStop {
position: 1.0
color: colors.greenStart
}
GradientStop {
position: 0.5
color: colors.greenEnd
}
GradientStop {
position: 0.0
color: colors.yellow
}
}
}
}
}
Item {
id: bar
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.horizontalCenter
anchors.leftMargin: 2
width: 4
height: 21
Rectangle { // base
id: baseBar
radius: 4
anchors { fill: parent }
color: colors.gutter
}
Rectangle { // mask
id: mask
height: micBar.muted ? parent.height : parent.height * level
color: micBar.muted ? colors.mutedColor : "white"
Item {
width: parent.width
radius: 5
anchors {
bottom: parent.bottom
bottomMargin: 0
left: parent.left
leftMargin: 0
height: parent.height - parent.height * level
anchors.top: parent.top
anchors.left: parent.left
clip:true
Image {
id: maskImage
visible: false
source: (pushToTalk) ? pushToTalkIcon : muted ? mutedIcon :
clipping ? clippingIcon : gated ? gatedIcon : unmutedIcon
anchors.top: parent.top
anchors.left: parent.left
width: parent.width
height: parent.parent.height
}
}
LinearGradient {
anchors { fill: mask }
visible: mask.visible && !micBar.muted
source: mask
start: Qt.point(0, 0)
end: Qt.point(0, bar.height)
rotation: 180
gradient: Gradient {
GradientStop {
position: 0.0
color: colors.greenStart
}
GradientStop {
position: 0.5
color: colors.greenEnd
}
GradientStop {
position: 1.0
color: colors.yellow
}
ColorOverlay {
visible: level > 0 && !micBar.muted && !micBar.clipping
anchors { fill: maskImage }
source: maskImage
color: "#b2b2b2"
}
}
}

View file

@ -1,20 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18.338" height="32" fill="none" version="1.1" viewBox="0 0 18.338 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(-7)" clip-path="url(#clip0)">
<path d="m25.338 4.1345-1.467 1.4671c-1.9339-2.1339-4.668-3.5343-7.8022-3.5343-3.0008 0-5.6682 1.3337-7.602 3.3342l-1.4671-1.4671c2.2673-2.4006 5.5348-3.9344 9.0691-3.9344 3.6677 0 7.0019 1.6004 9.2692 4.1345zm-3.4007 3.4014-1.4671 1.4671c-1.0002-1.3337-2.6007-2.1339-4.4012-2.1339-1.6671 0-3.1342 0.80022-4.2011 1.9339l-1.4671-1.4671c1.4004-1.5338 3.4009-2.534 5.6682-2.534 2.334 0 4.4679 1.067 5.8683 2.7341zm-3.9801 22.621c0 1.0199-0.8268 1.8467-1.8467 1.8467s-1.8466-0.8268-1.8466-1.8467 0.8267-1.8467 1.8466-1.8467 1.8467 0.8268 1.8467 1.8467zm0.4057-19.077h-4.2035l0.8519 14.774h2.4751z" clip-rule="evenodd" fill="#ea4c5f" fill-rule="evenodd"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="32" height="32" fill="#fff"/>
</clipPath>
</defs>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 22" style="enable-background:new 0 0 16 22;" xml:space="preserve">
<g>
<g>
<path d="M8,10.07c0.98,0,1.79-0.8,1.79-1.77V1.77C9.79,0.8,8.98,0,8,0C7.02,0,6.21,0.8,6.21,1.77v6.52
C6.21,9.27,7.02,10.07,8,10.07z M8,14.55c0.99,0,1.79-0.79,1.79-1.77S8.99,11,8,11s-1.79,0.79-1.79,1.77S7.01,14.55,8,14.55z
M14.8,7.8c-0.66,0-1.2,0.53-1.2,1.19v1.05c0,3.32-2.51,6.03-5.6,6.03s-5.6-2.7-5.6-6.03V8.99c0-0.66-0.54-1.19-1.2-1.19
S0,8.33,0,8.99v1.05c0,4.21,2.96,7.71,6.8,8.31v1.27H4.15c-0.66,0-1.2,0.53-1.2,1.19c0,0.66,0.54,1.19,1.2,1.19h7.69
c0.66,0,1.2-0.53,1.2-1.19c0-0.66-0.54-1.19-1.2-1.19H9.2v-1.27c3.84-0.61,6.8-4.11,6.8-8.31V8.99C16,8.33,15.46,7.8,14.8,7.8z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 977 B

View file

@ -1,13 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14.666" height="32" fill="none" version="1.1" viewBox="0 0 14.666 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m7.1999 4.7259c1.305 0 2.3629-1.0579 2.3629-2.3629 0-1.305-1.0579-2.3629-2.3629-2.3629-1.3051 0-2.363 1.0579-2.363 2.3629 0 1.305 1.0579 2.3629 2.363 2.3629zm2.4668 7.0745v2.9333h-4.9333v-2.9333c0-1.3334 1.1333-2.4 2.4666-2.4 1.4 0 2.4667 1.0666 2.4667 2.4zm-4.9333 8.3328v-2.8666h4.9333v2.8666c0 1.3333-1.1334 2.4-2.4667 2.4s-2.4666-1.0667-2.4666-2.4zm9.9331 0.4668v-3.5333c0-0.6667-0.6-1.1333-1.2-1.1333-0.6667 0-1.1333 0.5333-1.1333 1.1999v3.4667c0 2.4666-2.2667 4.4666-5 4.4666s-4.9999-2-4.9999-4.4666v-3.5333c0-0.6667-0.4667-1.2-1.0667-1.2-0.66661-0.0667-1.2666 0.4-1.2666 1.0666v3.6667c0 3.3999 2.6666 6.1999 6.1333 6.7332v2.2666h-2.8667c-0.6666 0-1.2 0.5334-1.2 1.2 0 0.6667 0.5334 1.2 1.2 1.2h8.1999c0.6667 0 1.2-0.5333 1.2-1.2 0-0.6666-0.5333-1.2-1.2-1.2h-2.9333v-2.2666c3.4666-0.6 6.1333-3.3333 6.1333-6.7332z" clip-rule="evenodd" fill="#00b4ef" fill-opacity=".7" fill-rule="evenodd"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 22" style="enable-background:new 0 0 16 22;" xml:space="preserve">
<path d="M14.8,7.8c-0.66,0-1.2,0.53-1.2,1.19v1.05c0,3.32-2.51,6.03-5.6,6.03s-5.6-2.7-5.6-6.03V8.99c0-0.66-0.54-1.19-1.2-1.19
S0,8.33,0,8.99v1.05c0,4.21,2.96,7.71,6.8,8.31v1.27H4.15c-0.66,0-1.2,0.53-1.2,1.19c0,0.66,0.54,1.19,1.2,1.19h7.69
c0.66,0,1.2-0.53,1.2-1.19c0-0.66-0.54-1.19-1.2-1.19H9.2v-1.27c3.84-0.61,6.8-4.11,6.8-8.31V8.99C16,8.33,15.46,7.8,14.8,7.8z
M8,9.05c0.99,0,1.79-0.79,1.79-1.77S8.99,5.5,8,5.5S6.21,6.3,6.21,7.28S7.01,9.05,8,9.05z M8,3.55c0.99,0,1.79-0.79,1.79-1.77
S8.99,0,8,0S6.21,0.79,6.21,1.77S7.01,3.55,8,3.55z M8,14.55c0.99,0,1.79-0.79,1.79-1.77S8.99,11,8,11s-1.79,0.79-1.79,1.77
S7.01,14.55,8,14.55z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 996 B

View file

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18.831" height="31.718" fill="none" version="1.1" viewBox="0 0 18.831 31.718" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m18.644 4.1333-1.4666 1.4666c-1.9333-2.1333-4.6666-3.5333-7.7999-3.5333-3 0-5.6666 1.3333-7.5999 3.3333l-1.4666-1.4666c2.2666-2.4 5.5333-3.9333 9.0666-3.9333 3.6666 0 6.9999 1.6 9.2665 4.1333zm-4.8664 4.8674 1.4667-1.4666c-1.4-1.6666-3.5333-2.7333-5.8666-2.7333-2.2667 0-4.2666 0.99999-5.6666 2.5333l1.4666 1.4666c1.0667-1.1333 2.5333-1.9333 4.2-1.9333 1.7999 0 3.3999 0.79999 4.3999 2.1333zm-1.8974 3.0751v-0.3262c0-1.3051-1.104-2.3492-2.4028-2.3492-1.2988 0-2.4028 1.0441-2.4028 2.3492v4.5025zm-4.3373 9.4371-1.9317 1.6974c0.8846 1.0496 2.3028 1.7208 3.8661 1.7208 2.6626 0 4.8706-1.9576 4.8706-4.3721v-3.3932c0-0.6526 0.4546-1.1746 1.104-1.1746 0.5844 0 1.1689 0.4568 1.1689 1.1093v3.4585c0 3.328-2.5976 6.0687-5.9745 6.5908v2.2186h2.8574c0.6494 0 1.1689 0.5221 1.1689 1.1746 0 0.6526-0.5195 1.1746-1.1689 1.1746h-7.9877c-0.6494 0-1.169-0.522-1.169-1.1746 0-0.6525 0.5196-1.1746 1.169-1.1746h2.7924v-2.2186c-1.7757-0.2348-3.3496-1.1453-4.4314-2.4155l-1.9328 1.6984c-0.45458 0.3915-1.1689 0.3263-1.5586-0.1305l-0.12988-0.1305c-0.38965-0.4568-0.32471-1.1746 0.12988-1.5661l16.495-14.617c0.4546-0.39153 1.1689-0.32627 1.5586 0.13047l0.1299 0.1305c0.3896 0.5221 0.3247 1.1746-0.065 1.6314l-6.6238 5.8206v2.4002c0 1.3051-1.104 2.3492-2.4028 2.3492-0.8086 0-1.5031-0.3671-1.9345-0.938zm-3.9751-5.521c0.5844 0 1.039 0.522 1.039 1.1745v1.3051l-2.2729 2.0229v-3.4585c0.06494-0.5873 0.58447-1.1093 1.2339-1.044z" clip-rule="evenodd" fill="#ea4c5f" fill-rule="evenodd"/>
</svg>

Before

Width:  |  Height:  |  Size: 2 KiB

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18.831" height="31.718" fill="none" version="1.1" viewBox="0 0 18.831 31.718" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m18.644 4.1333-1.4666 1.4666c-1.9333-2.1333-4.6666-3.5333-7.7999-3.5333-3 0-5.6666 1.3333-7.5999 3.3333l-1.4666-1.4666c2.2666-2.4 5.5333-3.9333 9.0666-3.9333 3.6666 0 6.9999 1.6 9.2665 4.1333zm-4.8664 4.8674 1.4667-1.4666c-1.4-1.6666-3.5333-2.7333-5.8666-2.7333-2.2667 0-4.2666 0.99999-5.6666 2.5333l1.4666 1.4666c1.0667-1.1333 2.5333-1.9333 4.2-1.9333 1.7999 0 3.3999 0.79999 4.3999 2.1333zm-1.8974 3.0751v-0.3262c0-1.3051-1.104-2.3492-2.4028-2.3492-1.2988 0-2.4028 1.0441-2.4028 2.3492v4.5025zm-4.3373 9.4371-1.9317 1.6974c0.8846 1.0496 2.3028 1.7208 3.8661 1.7208 2.6626 0 4.8706-1.9576 4.8706-4.3721v-3.3932c0-0.6526 0.4546-1.1746 1.104-1.1746 0.5844 0 1.1689 0.4568 1.1689 1.1093v3.4585c0 3.328-2.5976 6.0687-5.9745 6.5908v2.2186h2.8574c0.6494 0 1.1689 0.5221 1.1689 1.1746 0 0.6526-0.5195 1.1746-1.1689 1.1746h-7.9877c-0.6494 0-1.169-0.522-1.169-1.1746 0-0.6525 0.5196-1.1746 1.169-1.1746h2.7924v-2.2186c-1.7757-0.2348-3.3496-1.1453-4.4314-2.4155l-1.9328 1.6984c-0.45458 0.3915-1.1689 0.3263-1.5586-0.1305l-0.12988-0.1305c-0.38965-0.4568-0.32471-1.1746 0.12988-1.5661l16.495-14.617c0.4546-0.39153 1.1689-0.32627 1.5586 0.13047l0.1299 0.1305c0.3896 0.5221 0.3247 1.1746-0.065 1.6314l-6.6238 5.8206v2.4002c0 1.3051-1.104 2.3492-2.4028 2.3492-0.8086 0-1.5031-0.3671-1.9345-0.938zm-3.9751-5.521c0.5844 0 1.039 0.522 1.039 1.1745v1.3051l-2.2729 2.0229v-3.4585c0.06495-0.5873 0.58447-1.1093 1.2339-1.044z" clip-rule="evenodd" fill="#ea4c5f" fill-rule="evenodd"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 20 22" style="enable-background:new 0 0 20 22;" xml:space="preserve">
<path d="M14.11,10.55V7.49l5.54-5.44c0.47-0.46,0.47-1.22,0-1.68c-0.47-0.46-1.24-0.46-1.71,0L0.35,17.64
c-0.47,0.46-0.47,1.22,0,1.68c0.24,0.23,0.55,0.35,0.86,0.35s0.62-0.12,0.86-0.35l2.84-2.79c1.1,0.94,2.44,1.59,3.92,1.82v1.27H6.14
c-0.67,0-1.21,0.53-1.21,1.19c0,0.66,0.54,1.19,1.21,1.19h7.77c0.67,0,1.21-0.53,1.21-1.19c0-0.66-0.54-1.19-1.21-1.19h-2.66v-1.27
c3.88-0.61,6.87-4.11,6.87-8.31V8.99c0-0.66-0.54-1.19-1.21-1.19c-0.67,0-1.21,0.53-1.21,1.19v1.05c0,0.02,0,0.05,0,0.07
c-0.03,2.85-1.93,5.23-4.44,5.81v-1.55C12.9,13.86,14.11,12.34,14.11,10.55z M8.82,15.92c-0.81-0.19-1.56-0.57-2.2-1.08l1.05-1.03
c0.35,0.24,0.73,0.43,1.15,0.56V15.92z M10.04,0L10.04,0C7.8,0,5.97,1.8,5.97,4v5.82l7.72-7.58C13.02,0.92,11.63,0,10.04,0z
M4.5,11.26c-0.08-0.4-0.12-0.81-0.12-1.23V8.99c0-0.66-0.54-1.19-1.21-1.19S1.96,8.33,1.96,8.99v1.05c0,1.11,0.21,2.17,0.59,3.15
L4.5,11.26z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Art" width="27.121" height="40.121" version="1.1" viewBox="0 0 27.121 40.121" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title>mic-ptt-a</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs>
<style>.cls-1{fill-rule:evenodd;}</style>
</defs>
<title>mic-ptt-a</title>
<path class="cls-1" d="m23.1 5.2112-1.85 1.85a13.19 13.19 0 0 0-9.82-4.46 13.35 13.35 0 0 0-9.58 4.2l-1.85-1.84a15.66 15.66 0 0 1 23.1 0.25zm-6.13 6.13 1.85-1.85a9.62 9.62 0 0 0-14.53-0.25l1.84 1.88a7.34 7.34 0 0 1 5.3-2.44 6.85 6.85 0 0 1 5.54 2.66zm-5.39-0.22a3.58 3.58 0 0 1 1.51 0.3 3.68 3.68 0 0 1 1.26 0.88 3.88 3.88 0 0 1 0.84 1.3 3.94 3.94 0 0 1 0.29 1.52v5.07a1.91 1.91 0 0 1 0.48-0.05 3.93 3.93 0 0 1 2.62 1.05 3.38 3.38 0 0 1 1.5-0.32 3.27 3.27 0 0 1 2.77 1.36 2.75 2.75 0 0 1 0.85-0.1 3.35 3.35 0 0 1 1.33 0.25 3.18 3.18 0 0 1 1.12 0.76 3.23 3.23 0 0 1 0.73 1.13 3.32 3.32 0 0 1 0.24 1.32v3.31a12.27 12.27 0 0 1-0.43 3.41l-1.36 5.65a2.67 2.67 0 0 1-1 1.55 2.89 2.89 0 0 1-1.75 0.61h-11a4.47 4.47 0 0 1-1.76-0.43 3.88 3.88 0 0 1-1.36-1.12l-5.78-7.75a3.72 3.72 0 0 1-0.8-2.35 3.64 3.64 0 0 1 0.28-1.5 3.75 3.75 0 0 1 0.84-1.27 3.9 3.9 0 0 1 2.77-1.18 4.5 4.5 0 0 1 2 0.54v-10.06a4.06 4.06 0 0 1 1.13-2.78 3.74 3.74 0 0 1 1.25-0.83 3.85 3.85 0 0 1 1.43-0.27zm0 2a1.89 1.89 0 0 0-0.74 0.12 2 2 0 0 0-1.06 1 1.92 1.92 0 0 0-0.15 0.74v15.35l-2.32-3.06a2 2 0 0 0-0.7-0.59 1.88 1.88 0 0 0-0.9-0.2 1.85 1.85 0 0 0-0.74 0.15 2 2 0 0 0-0.63 0.43 2 2 0 0 0-0.4 0.63 1.9 1.9 0 0 0-0.13 0.74 2 2 0 0 0 0.38 1.17l5.86 7.79a1.79 1.79 0 0 0 0.68 0.57 1.74 1.74 0 0 0 0.85 0.16h11a1.23 1.23 0 0 0 0.59-0.15 0.88 0.88 0 0 0 0.24-0.23 0.71 0.71 0 0 0 0.13-0.31l1.37-5.6a12 12 0 0 0 0.37-3v-3.28a1.7 1.7 0 0 0-0.43-1.07 1.31 1.31 0 0 0-0.47-0.37 1.35 1.35 0 0 0-0.59-0.11 1.46 1.46 0 0 0-0.55 0.11 1.23 1.23 0 0 0-0.46 0.32 1.64 1.64 0 0 0-0.43 1.07h-0.48v-1a1.52 1.52 0 0 0-0.12-0.66 1.61 1.61 0 0 0-0.37-0.56 1.63 1.63 0 0 0-1.22-0.54 2 2 0 0 0-1.23 0.54 1.77 1.77 0 0 0-0.36 0.53 1.57 1.57 0 0 0-0.11 0.64v1h-0.49v-1.33a2.22 2.22 0 0 0-0.58-1.44 1.71 1.71 0 0 0-0.62-0.44 1.88 1.88 0 0 0-0.79-0.12 2 2 0 0 0-0.74 0.13 1.85 1.85 0 0 0-0.63 0.41 2 2 0 0 0-0.53 1.36v1.5h-0.57v-10.4a2 2 0 0 0-0.54-1.44 1.75 1.75 0 0 0-0.63-0.44 1.73 1.73 0 0 0-0.76-0.12z" fill-rule="evenodd"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -1,8 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg id="Art" width="27.2" height="40.433" version="1.1" viewBox="0 0 27.2 40.433" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="m5.2 8.4327c-0.3 0.3-0.7 0.6-1 0.9l1.8 1.9c1.4-1.5 3.3-2.4 5.3-2.4 2.2 0 4.2 0.9 5.5 2.7l1.8-1.8c-3.3-4.2-9.3-4.7-13.4-1.3zm16-1.3 1.9-1.9c-0.3-0.3-0.6-0.7-1-1-6.3-5.9-16.2-5.6-22.1 0.7l1.9 1.8c2.5-2.6 5.9-4.2 9.6-4.2 3.6 0.2 7.2 1.8 9.7 4.6zm5.6 17.2c-0.2-0.4-0.4-0.8-0.7-1.1s-0.7-0.6-1.1-0.8c-0.5-0.1-0.9-0.2-1.4-0.2-0.3 0-0.6 0-0.8 0.1-0.6-0.9-1.7-1.4-2.8-1.4-0.5 0-1 0.1-1.5 0.3-0.7-0.7-1.6-1-2.6-1.1-0.2 0-0.3 0-0.5 0.1v-5c0-0.5-0.1-1-0.3-1.5s-0.5-0.9-0.8-1.3c-0.4-0.4-0.8-0.7-1.3-0.9s-1-0.3-1.5-0.3-1 0.1-1.4 0.3c-0.5 0.2-0.9 0.5-1.3 0.8-0.7 0.7-1.1 1.7-1.1 2.8v10.1c-0.6-0.3-1.3-0.5-2-0.5-1 0-2 0.4-2.8 1.2-0.4 0.4-0.6 0.8-0.8 1.3s-0.3 1-0.3 1.5c0 0.9 0.3 1.7 0.8 2.4l5.8 7.8c0.4 0.5 0.8 0.9 1.4 1.1 0.6 0.3 1.2 0.4 1.8 0.4h11c0.6 0 1.2-0.2 1.8-0.6 0.5-0.4 0.9-0.9 1-1.6l1.4-5.6c0.3-1.1 0.4-2.3 0.4-3.4v-3.3c-0.1-0.7-0.2-1.1-0.4-1.6zm-1.6 4.6c0 1-0.1 2-0.4 3l-1.3 5.6c0 0.1-0.1 0.2-0.1 0.3-0.1 0.1-0.1 0.2-0.2 0.2-0.3 0.1-0.5 0.2-0.7 0.2h-11c-0.3 0-0.6 0-0.8-0.2-0.3-0.1-0.5-0.3-0.7-0.6l-5.9-7.8c-0.2-0.3-0.4-0.7-0.4-1.2 0-0.3 0-0.5 0.1-0.7s0.2-0.4 0.4-0.6 0.4-0.3 0.6-0.4 0.5-0.2 0.7-0.2c0.3 0 0.6 0.1 0.9 0.2s0.5 0.3 0.7 0.6l2.3 3.1v-15.3c0-0.3 0.1-0.5 0.2-0.7 0.2-0.5 0.6-0.8 1.1-1 0.3-0.2 0.5-0.2 0.8-0.2s0.5 0 0.8 0.1c0.2 0.1 0.5 0.2 0.6 0.4 0.4 0.4 0.6 0.9 0.5 1.4v10.4h0.6v-1.5c0-0.5 0.2-1 0.5-1.4 0.2-0.2 0.4-0.3 0.6-0.4s0.5-0.1 0.7-0.1c0.3 0 0.5 0 0.8 0.1 0.2 0.1 0.4 0.2 0.6 0.4 0.4 0.4 0.6 0.9 0.6 1.4v1.3h0.5v-1c0-0.2 0-0.4 0.1-0.6s0.2-0.4 0.4-0.5c0.3-0.3 0.8-0.5 1.2-0.5 0.5 0 0.9 0.2 1.2 0.5 0.2 0.2 0.3 0.3 0.4 0.6 0.1 0.2 0.1 0.4 0.1 0.7v1h0.5c0-0.4 0.2-0.8 0.4-1.1 0.1-0.1 0.3-0.3 0.5-0.3 0.2-0.1 0.4-0.1 0.6-0.1s0.4 0 0.6 0.1 0.3 0.2 0.5 0.4c0.3 0.3 0.4 0.7 0.4 1.1z" fill="#fff"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 14 22" style="enable-background:new 0 0 14 22;" xml:space="preserve">
<path d="M0.69,3.64c0.32,0.19,0.74,0.08,0.93-0.25C2.34,2.14,3.67,1.37,5.1,1.37s2.77,0.77,3.48,2.02c0.13,0.22,0.35,0.34,0.59,0.34
c0.12,0,0.23-0.03,0.34-0.09C9.84,3.45,9.95,3.03,9.76,2.7C8.8,1.04,7.02,0,5.11,0s-3.7,1.04-4.66,2.7
C0.26,3.03,0.37,3.45,0.69,3.64z M12.87,12.23c-0.42,0-0.8,0.23-1,0.61c-0.01,0.01-0.08,0.14-0.23,0.14c-0.19,0-0.24-0.24-0.26-0.29
c-0.05-0.59-0.54-1.05-1.13-1.05c-0.42,0-0.81,0.24-1.01,0.64c0,0-0.06,0.11-0.22,0.11c-0.2,0-0.24-0.17-0.25-0.27
c-0.03-0.6-0.53-1.07-1.13-1.07c-0.42,0-0.81,0.24-1.01,0.63c0,0-0.07,0.13-0.22,0.13c-0.14,0-0.25-0.11-0.25-0.25v-5.2
c0-0.56-0.42-1.04-0.95-1.09c-0.3-0.03-0.59,0.07-0.81,0.27c-0.22,0.2-0.35,0.49-0.35,0.79v8.8c0,0.12-0.06,0.21-0.17,0.26
c-0.11,0.04-0.22,0.02-0.3-0.06l-1.76-1.77c-0.4-0.4-1.03-0.44-1.44-0.1c-0.23,0.2-0.37,0.47-0.38,0.77
c-0.01,0.29,0.09,0.58,0.29,0.79l3.1,4.12c0.37,0.6,1.99,2,2.42,2.21C6.62,21.77,7.53,22,8.45,22c1.13,0,2.22-0.34,3.13-0.98
c1.49-0.92,2.42-2.6,2.42-4.38v-3.27C14.01,12.75,13.5,12.23,12.87,12.23z M5.1,2.34c-1.04,0-2.02,0.56-2.54,1.47
C2.37,4.14,2.49,4.56,2.81,4.75C3.13,4.93,3.55,4.82,3.74,4.5C4.02,4.01,4.54,3.7,5.1,3.7s1.08,0.3,1.37,0.79
c0.13,0.22,0.35,0.34,0.59,0.34c0.12,0,0.23-0.03,0.34-0.09c0.32-0.19,0.43-0.61,0.25-0.93C7.12,2.9,6.15,2.34,5.1,2.34z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 22" style="enable-background:new 0 0 16 22;" xml:space="preserve">
<path d="M7.95,10.03c-0.38,0-0.73,0.21-0.91,0.56c-0.01,0.02-0.07,0.12-0.2,0.12c-0.13,0-0.23-0.1-0.23-0.23V5.77
c0-0.51-0.38-0.95-0.87-0.99C5.47,4.75,5.2,4.83,5,5.02C4.8,5.2,4.69,5.46,4.69,5.73v7.99c0,0.01,0,0.02-0.01,0.04l3.64-3.65
C8.21,10.06,8.08,10.03,7.95,10.03z M1.62,3.3c0.29,0.17,0.67,0.07,0.84-0.22c0.65-1.13,1.87-1.84,3.17-1.84s2.52,0.7,3.17,1.84
c0.11,0.2,0.32,0.31,0.53,0.31c0.11,0,0.21-0.03,0.31-0.08c0.29-0.17,0.4-0.55,0.23-0.85C9,0.94,7.37,0,5.63,0
C3.89,0,2.27,0.94,1.39,2.45C1.22,2.75,1.32,3.13,1.62,3.3z M15.69,6.26c-0.41-0.41-1.08-0.41-1.5,0L0.31,20.19
c-0.41,0.41-0.41,1.09,0,1.5C0.52,21.9,0.79,22,1.06,22s0.54-0.1,0.75-0.31l3.26-3.27c0.49,0.44,1,0.85,1.21,0.95
c0.73,0.4,1.56,0.61,2.4,0.61c1.03,0,2.02-0.31,2.85-0.89c1.36-0.84,2.2-2.36,2.2-3.97v-2.97c0-0.57-0.46-1.04-1.03-1.04
c-0.16,0-0.32,0.04-0.46,0.12l3.45-3.47C16.1,7.34,16.1,6.67,15.69,6.26z M11.72,11.74l0.06-0.06
C11.77,11.7,11.75,11.72,11.72,11.74z M2.79,15.65l1.68-1.68c-0.08,0.01-0.15-0.01-0.21-0.07l-1.6-1.61
c-0.36-0.36-0.94-0.4-1.31-0.09C1.13,12.38,1,12.63,0.99,12.9c-0.01,0.26,0.08,0.52,0.27,0.71L2.79,15.65z M6.87,4.08
c0.11,0.2,0.32,0.31,0.53,0.31c0.11,0,0.21-0.03,0.31-0.08c0.29-0.17,0.4-0.55,0.23-0.85C7.47,2.64,6.58,2.12,5.63,2.12
S3.79,2.64,3.32,3.46c-0.17,0.3-0.07,0.67,0.23,0.85c0.29,0.17,0.67,0.07,0.84-0.23c0.26-0.44,0.73-0.72,1.24-0.72
S6.62,3.64,6.87,4.08z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.333099"
height="31.9998"
viewBox="0 0 18.333099 31.9998"
version="1.1"
id="svg4"
sodipodi:docname="mic-unmute-a.svg"
style="fill:none"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1377"
id="namedview6"
showgrid="false"
inkscape:zoom="7.375"
inkscape:cx="9"
inkscape:cy="15.9998"
inkscape:window-x="2552"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M 16.8664,5.59992 18.3331,4.13328 C 16.0664,1.59998 12.7332,0 9.0665,0 5.5333,0 2.26664,1.53331 0,3.93328 L 1.46665,5.39993 C 3.4,3.39995 6.0666,2.06664 9.0665,2.06664 c 3.1333,0 5.8666,1.39998 7.7999,3.53328 z m -3.4,3.39983 1.4667,-1.46665 c -1.4,-1.66664 -3.5333,-2.7333 -5.8666,-2.7333 -2.2666,0 -4.2666,0.99999 -5.6666,2.5333 l 1.4666,1.46665 c 1.0667,-1.13332 2.5333,-1.93331 4.2,-1.93331 1.8,0 3.3999,0.79999 4.3999,2.13331 z m -1.933,2.80065 v 2.9333 H 6.6001 v -2.9333 c 0,-1.3334 1.1333,-2.40001 2.4666,-2.40001 1.4,0 2.4667,1.06661 2.4667,2.40001 z m -4.9333,5.4662 v 2.8666 c 0,1.3333 1.1333,2.4 2.4666,2.4 1.3333,0 2.4667,-1.0667 2.4667,-2.4 v -2.8666 z m 9.9331,-0.1999 V 20.6 c 0,3.3999 -2.6667,6.1332 -6.1333,6.7332 v 2.2666 h 2.9333 c 0.6667,0 1.2,0.5334 1.2,1.2 0,0.6667 -0.5333,1.2 -1.2,1.2 H 5.1333 c -0.6666,0 -1.2,-0.5333 -1.2,-1.2 0,-0.6666 0.5334,-1.2 1.2,-1.2 H 7.9999 V 27.3332 C 4.5333,26.7999 1.8667,23.9999 1.8667,20.6 v -3.6667 c 0,-0.6666 0.59999,-1.1333 1.2666,-1.0666 0.6,0 1.0667,0.5333 1.0667,1.2 V 20.6 c 0,2.4666 2.2666,4.4666 4.9999,4.4666 2.7333,0 5,-2 5,-4.4666 v -3.4667 c 0,-0.6666 0.4666,-1.1999 1.1333,-1.1999 0.6,0 1.2,0.4666 1.2,1.1333 z"
id="path2"
inkscape:connector-curvature="0"
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd" />
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -1,13 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18.333" height="32" fill="none" version="1.1" viewBox="0 0 18.333 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m16.866 5.5999 1.4667-1.4666c-2.2667-2.5333-5.5999-4.1333-9.2666-4.1333-3.5332 0-6.7999 1.5333-9.0665 3.9333l1.4666 1.4666c1.9334-2 4.6-3.3333 7.5998-3.3333 3.1333 0 5.8666 1.4 7.7999 3.5333zm-3.4 3.3998 1.4667-1.4666c-1.4-1.6666-3.5333-2.7333-5.8666-2.7333-2.2666 0-4.2666 0.99999-5.6666 2.5333l1.4666 1.4666c1.0667-1.1333 2.5333-1.9333 4.2-1.9333 1.8 0 3.3999 0.79999 4.3999 2.1333zm-1.933 2.8006v2.9333h-4.9333v-2.9333c0-1.3334 1.1333-2.4 2.4666-2.4 1.4 0 2.4667 1.0666 2.4667 2.4zm-4.9333 5.4662v2.8666c0 1.3333 1.1333 2.4 2.4666 2.4s2.4667-1.0667 2.4667-2.4v-2.8666zm9.9331-0.1999v3.5333c0 3.3999-2.6667 6.1332-6.1333 6.7332v2.2666h2.9333c0.6667 0 1.2 0.5334 1.2 1.2 0 0.6667-0.5333 1.2-1.2 1.2h-8.1999c-0.6666 0-1.2-0.5333-1.2-1.2 0-0.6666 0.5334-1.2 1.2-1.2h2.8666v-2.2666c-3.4666-0.5333-6.1332-3.3333-6.1332-6.7332v-3.6667c0-0.6666 0.59999-1.1333 1.2666-1.0666 0.6 0 1.0667 0.5333 1.0667 1.2v3.5333c0 2.4666 2.2666 4.4666 4.9999 4.4666s5-2 5-4.4666v-3.4667c0-0.6666 0.4666-1.1999 1.1333-1.1999 0.6 0 1.2 0.4666 1.2 1.1333z" clip-rule="evenodd" fill="#fff" fill-rule="evenodd"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 22" style="enable-background:new 0 0 16 22;" xml:space="preserve">
<path d="M14.8,7.8c-0.66,0-1.2,0.53-1.2,1.19v1.05c0,2.88-1.89,5.29-4.4,5.89v-1.55c1.64-0.51,2.83-2.03,2.83-3.82V4
c0-2.2-1.81-4-4.03-4S3.97,1.8,3.97,4v6.55c0,1.79,1.2,3.31,2.83,3.82v1.55c-2.51-0.59-4.4-3.01-4.4-5.89V8.99
c0-0.66-0.54-1.19-1.2-1.19S0,8.33,0,8.99v1.05c0,4.21,2.96,7.71,6.8,8.32v1.27H4.15c-0.66,0-1.2,0.53-1.2,1.19S3.48,22,4.15,22
h7.69c0.66,0,1.2-0.53,1.2-1.19s-0.54-1.19-1.2-1.19H9.2v-1.27c3.84-0.61,6.8-4.11,6.8-8.32V8.99C16,8.33,15.46,7.8,14.8,7.8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 834 B

View file

@ -9,21 +9,49 @@
//
import QtQuick 2.10
import QtQuick.Controls 2.3
import "../simplifiedConstants" as SimplifiedConstants
import "../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit
import "./audio" as AudioSettings
import "./general" as GeneralSettings
import "./vr" as VrSettings
import "./dev" as DevSettings
import "./about" as AboutSettings
Rectangle {
property string activeTabView: "generalTabView"
id: root
color: simplifiedUI.colors.darkBackground
anchors.fill: parent
property bool developerModeEnabled: Settings.getValue("simplifiedUI/developerModeEnabled", false)
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
focus: true
Keys.onPressed: {
if ((event.key == Qt.Key_D) && (event.modifiers & Qt.ControlModifier && event.modifiers & Qt.AltModifier && event.modifiers & Qt.ShiftModifier)) {
var currentSetting = Settings.getValue("simplifiedUI/developerModeEnabled", false);
var newSetting = !currentSetting;
Settings.setValue("simplifiedUI/developerModeEnabled", newSetting);
root.developerModeEnabled = newSetting;
if (newSetting) {
console.log("Developer mode ON. You are now a developer!");
} else {
console.log("Developer mode OFF.");
if (root.activeTabView === "devTabView") {
tabListView.currentIndex = 2;
root.activeTabView = "vrTabView";
}
}
}
}
Component.onCompleted: {
root.forceActiveFocus();
}
Rectangle {
@ -49,13 +77,34 @@ Rectangle {
tabTitle: "VR"
tabViewName: "vrTabView"
}
ListElement {
tabTitle: "About"
tabViewName: "aboutTabView"
}
ListElement {
tabTitle: "Dev"
tabViewName: "devTabView"
}
}
Component {
id: highlightBar
Rectangle {
width: tabListView.currentItem.width
height: tabListView.currentItem.height
color: simplifiedUI.colors.darkBackground
x: tabListView.currentItem.x
Behavior on x {
SmoothedAnimation {
duration: 250
}
}
Behavior on width {
SmoothedAnimation {
duration: 250
}
}
}
}
@ -68,9 +117,12 @@ Rectangle {
orientation: ListView.Horizontal
model: tabListModel
highlight: highlightBar
highlightFollowsCurrentItem: false
interactive: contentItem.width > width
delegate: Item {
width: tabTitleText.paintedWidth + 64
visible: model.tabTitle !== "Dev" || (model.tabTitle === "Dev" && root.developerModeEnabled)
width: tabTitleText.paintedWidth + 32
height: parent.height
HifiStylesUit.GraphikRegular {
@ -98,9 +150,7 @@ Rectangle {
id: tabViewContainers
anchors.top: tabContainer.bottom
anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right
anchors.rightMargin: 26
anchors.bottom: parent.bottom
@ -125,14 +175,34 @@ Rectangle {
visible: activeTabView === "vrTabView"
anchors.fill: parent
}
}
Image {
source: "../images/accent.svg"
anchors.right: parent.right
anchors.bottom: parent.bottom
width: 94
height: 175
DevSettings.Dev {
id: devTabViewContainer
visible: activeTabView === "devTabView"
anchors.fill: parent
}
AboutSettings.About {
id: aboutTabViewContainer
visible: activeTabView === "aboutTabView"
anchors.fill: parent
}
SimplifiedControls.VerticalScrollBar {
parent: {
if (activeTabView === "generalTabView") {
generalTabViewContainer
} else if (activeTabView === "audioTabView") {
audioTabViewContainer
} else if (activeTabView === "vrTabView") {
vrTabViewContainer
} else if (activeTabView === "devTabView") {
devTabViewContainer
} else if (activeTabView === "aboutTabView") {
aboutTabViewContainer
}
}
}
}

View file

@ -0,0 +1,326 @@
//
// About.qml
//
// Created by Zach Fox on 2019-06-18
// 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
//
import QtQuick 2.10
import QtQuick.Controls 2.3
import "../../simplifiedConstants" as SimplifiedConstants
import "../../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit
import QtQuick.Layouts 1.3
Flickable {
id: root
contentWidth: parent.width
contentHeight: aboutColumnLayout.height
clip: true
onVisibleChanged: {
if (visible) {
root.contentX = 0;
root.contentY = 0;
}
}
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
ColumnLayout {
id: aboutColumnLayout
anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top
spacing: 0
Image {
source: "images/logo.png"
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 16
Layout.preferredWidth: 160
Layout.preferredHeight: 120
fillMode: Image.PreserveAspectFit
mipmap: true
}
ColumnLayout {
id: platformInfoContainer
Layout.preferredWidth: parent.width
Layout.bottomMargin: 24
spacing: 0
HifiStylesUit.GraphikSemiBold {
text: "Version " + Window.checkVersion()
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikSemiBold {
text: "Platform Info"
Layout.maximumWidth: parent.width
Layout.topMargin: 8
Layout.bottomMargin: 8
height: paintedHeight
size: 22
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>Computer Vendor/Model:</b>"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
Component.onCompleted: {
var computer = JSON.parse(PlatformInfo.getComputer());
var computerVendor = computer.vendor;
if (computerVendor.length === 0) {
computerVendor = "Unknown";
}
var computerModel = computer.model;
if (computerModel.length === 0) {
computerModel = "Unknown";
}
text = "<b>Computer Vendor/Model:</b> " + computerVendor + "/" + computerModel;
}
}
HifiStylesUit.GraphikRegular {
text: "<b>Profiled Platform Tier:</b> " + PlatformInfo.getTierProfiled()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>OS Type:</b> " + PlatformInfo.getOperatingSystemType()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>CPU:</b>"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
Component.onCompleted: {
var cpu = JSON.parse(PlatformInfo.getCPU(0));
var cpuModel = cpu.model;
if (cpuModel.length === 0) {
cpuModel = "Unknown";
}
text = "<b>CPU:</b> " + cpuModel;
}
}
HifiStylesUit.GraphikRegular {
text: "<b># CPUs:</b> " + PlatformInfo.getNumCPUs()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b># CPU Cores:</b> " + PlatformInfo.getNumLogicalCores()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>RAM:</b> " + PlatformInfo.getTotalSystemMemoryMB() + " MB"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>GPU:</b> "
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
Component.onCompleted: {
var gpu = JSON.parse(PlatformInfo.getGPU(0));
var gpuModel = gpu.model;
if (gpuModel.length === 0) {
gpuModel = "Unknown";
}
text = "<b>GPU:</b> " + gpuModel;
}
}
HifiStylesUit.GraphikRegular {
text: "<b>VR Hand Controllers:</b> " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None"))
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
// This is a bit of a hack to get the name of the currently-selected audio input device
// in the current mode (Desktop or VR). The reason this is necessary is because it seems to me like
// the only way one can get a human-readable list of the audio I/O devices is by using a ListView
// and grabbing the names from the AudioScriptingInterface; you can't do it using a ListModel.
// See `AudioDevices.h`, specifically the comment above the declaration of `QVariant data()`.
ListView {
id: audioInputDevices
visible: false
property string selectedInputDeviceName
Layout.preferredWidth: parent.width
Layout.preferredHeight: contentItem.height
interactive: false
model: AudioScriptingInterface.devices.input
delegate: Item {
Component.onCompleted: {
if (HMD.active && selectedHMD) {
audioInputDevices.selectedInputDeviceName = model.devicename
} else if (!HMD.active && selectedDesktop) {
audioInputDevices.selectedInputDeviceName = model.devicename
}
}
}
}
HifiStylesUit.GraphikRegular {
text: "<b>Audio Input:</b> " + audioInputDevices.selectedInputDeviceName
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
// This is a bit of a hack to get the name of the currently-selected audio output device
// in the current mode (Desktop or VR). The reason this is necessary is because it seems to me like
// the only way one can get a human-readable list of the audio I/O devices is by using a ListView
// and grabbing the names from the AudioScriptingInterface; you can't do it using a ListModel.
// See `AudioDevices.h`, specifically the comment above the declaration of `QVariant data()`.
ListView {
id: audioOutputDevices
visible: false
property string selectedOutputDeviceName
Layout.preferredWidth: parent.width
Layout.preferredHeight: contentItem.height
interactive: false
model: AudioScriptingInterface.devices.output
delegate: Item {
Component.onCompleted: {
if (HMD.active && selectedHMD) {
audioOutputDevices.selectedOutputDeviceName = model.devicename
} else if (!HMD.active && selectedDesktop) {
audioOutputDevices.selectedOutputDeviceName = model.devicename
}
}
}
}
HifiStylesUit.GraphikRegular {
text: "<b>Audio Output:</b> " + audioOutputDevices.selectedOutputDeviceName
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
SimplifiedControls.Button {
Layout.topMargin: 8
width: 200
height: 32
text: "Copy to Clipboard"
temporaryText: "Copied!"
onClicked: {
Window.copyToClipboard(root.buildPlatformInfoTextToCopy());
showTemporaryText();
}
}
}
}
function buildPlatformInfoTextToCopy() {
var textToCopy = "**About Interface**\n";
textToCopy += "Interface Version: " + Window.checkVersion() + "\n";
textToCopy += "\n**Platform Info**\n";
var computer = JSON.parse(PlatformInfo.getComputer());
var computerVendor = computer.vendor;
if (computerVendor.length === 0) {
computerVendor = "Unknown";
}
var computerModel = computer.model;
if (computerModel.length === 0) {
computerModel = "Unknown";
}
textToCopy += "Computer Vendor/Model: " + computerVendor + "/" + computerModel + "\n";
textToCopy += "Profiled Platform Tier: " + PlatformInfo.getTierProfiled() + "\n";
textToCopy += "OS Type: " + PlatformInfo.getOperatingSystemType() + "\n";
var cpu = JSON.parse(PlatformInfo.getCPU(0));
var cpuModel = cpu.model;
if (cpuModel.length === 0) {
cpuModel = "Unknown";
}
textToCopy += "CPU: " + cpuModel + "\n";
textToCopy += "# CPUs: " + PlatformInfo.getNumCPUs() + "\n";
textToCopy += "# CPU Cores: " + PlatformInfo.getNumLogicalCores() + "\n";
textToCopy += "RAM: " + PlatformInfo.getTotalSystemMemoryMB() + " MB\n";
var gpu = JSON.parse(PlatformInfo.getGPU(0));
var gpuModel = gpu.model;
if (gpuModel.length === 0) {
gpuModel = "Unknown";
}
textToCopy += "GPU: " + gpuModel + "\n";
textToCopy += "VR Hand Controllers: " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None")) + "\n";
textToCopy += "Audio Input: " + audioInputDevices.selectedInputDeviceName + "\n";
textToCopy += "Audio Output: " + audioOutputDevices.selectedOutputDeviceName + "\n";
textToCopy += "\n**All Platform Info**\n";
textToCopy += JSON.stringify(JSON.parse(PlatformInfo.getPlatform()), null, 4);
return textToCopy;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -19,8 +19,6 @@ Flickable {
id: root
contentWidth: parent.width
contentHeight: audioColumnLayout.height
topMargin: 24
bottomMargin: 24
clip: true
function changePeakValuesEnabled(enabled) {
@ -33,7 +31,7 @@ Flickable {
AudioScriptingInterface.devices.input.peakValuesEnabled = visible;
if (visible) {
root.contentX = 0;
root.contentY = -root.topMargin;
root.contentY = 0;
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled);
} else {
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled);
@ -45,19 +43,38 @@ Flickable {
id: simplifiedUI
}
Image {
id: accent
source: "../images/accent2.svg"
anchors.left: parent.left
anchors.top: parent.top
width: 83
height: 156
transform: Scale {
xScale: -1
origin.x: accent.width / 2
origin.y: accent.height / 2
}
}
ColumnLayout {
id: audioColumnLayout
anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top
spacing: simplifiedUI.margins.settings.spacingBetweenSettings
ColumnLayout {
id: volumeControlsContainer
Layout.preferredWidth: parent.width
Layout.topMargin: 24
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: volumeControlsTitle
text: "Volume Controls"
Layout.preferredWidth: parent.width
@ -154,7 +171,7 @@ Flickable {
Layout.preferredWidth: parent.width
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: micControlsTitle
text: "Default Mute Controls"
Layout.maximumWidth: parent.width
@ -165,6 +182,7 @@ Flickable {
ColumnLayout {
id: micControlsSwitchGroup
Layout.preferredWidth: parent.width
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
SimplifiedControls.Switch {
@ -188,6 +206,22 @@ Flickable {
AudioScriptingInterface.pushToTalkDesktop = !AudioScriptingInterface.pushToTalkDesktop;
}
}
SimplifiedControls.Switch {
id: attenuateOutputSwitch
enabled: AudioScriptingInterface.pushToTalkDesktop
Layout.preferredHeight: 18
Layout.preferredWidth: parent.width
labelTextOn: "Reduce volume of other sounds while I'm pushing-to-talk"
checked: AudioScriptingInterface.pushingToTalkOutputGainDesktop !== 0.0
onClicked: {
if (AudioScriptingInterface.pushingToTalkOutputGainDesktop === 0.0) {
AudioScriptingInterface.pushingToTalkOutputGainDesktop = -20.0;
} else {
AudioScriptingInterface.pushingToTalkOutputGainDesktop = 0.0;
}
}
}
}
}
@ -196,7 +230,7 @@ Flickable {
Layout.preferredWidth: parent.width
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: inputDeviceTitle
text: "Which input device?"
Layout.maximumWidth: parent.width
@ -289,9 +323,10 @@ Flickable {
ColumnLayout {
id: outputDeviceContainer
Layout.preferredWidth: parent.width
Layout.bottomMargin: 24
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: outputDeviceTitle
text: "Which output device?"
Layout.maximumWidth: parent.width

View file

@ -0,0 +1,115 @@
//
// Dev.qml
//
// Created by Zach Fox on 2019-06-11
// 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
//
import QtQuick 2.10
import QtQuick.Controls 2.3
import "../../simplifiedConstants" as SimplifiedConstants
import "../../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit
import QtQuick.Layouts 1.3
Flickable {
id: root
contentWidth: parent.width
contentHeight: devColumnLayout.height
clip: true
onVisibleChanged: {
if (visible) {
root.contentX = 0;
root.contentY = 0;
}
}
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
Image {
id: accent
source: "../images/accent3.svg"
anchors.left: parent.left
anchors.top: parent.top
width: 83
height: 156
transform: Scale {
xScale: -1
origin.x: accent.width / 2
origin.y: accent.height / 2
}
}
ColumnLayout {
id: devColumnLayout
anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top
spacing: simplifiedUI.margins.settings.spacingBetweenSettings
ColumnLayout {
id: uiControlsContainer
Layout.preferredWidth: parent.width
Layout.topMargin: 24
Layout.bottomMargin: 24
spacing: 0
HifiStylesUit.GraphikSemiBold {
id: uiControlsTitle
text: "User Interface"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 22
color: simplifiedUI.colors.text.white
}
HifiStylesUit.GraphikRegular {
id: uiControlsSubtitle
text: "You'll have to restart Interface after changing either of these settings. If you don't get any Toolbar apps back after restarting, run defaultScripts.js manually."
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
ColumnLayout {
id: uiControlsSwitchGroup
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
SimplifiedControls.Switch {
id: keepMenusSwitch
width: parent.width
height: 18
labelTextOn: "Keep Old Menus (File, Edit, etc)"
checked: Settings.getValue("simplifiedUI/keepMenus", false);
onClicked: {
Settings.setValue("simplifiedUI/keepMenus", !Settings.getValue("simplifiedUI/keepMenus", false));
}
}
SimplifiedControls.Switch {
id: keepOldUIAndScriptsSwitch
width: parent.width
height: 18
labelTextOn: "Keep Old UI and Scripts"
checked: Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false);
onClicked: {
Settings.setValue("simplifiedUI/keepExistingUIAndScripts", !Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false));
}
}
}
}
}
}

View file

@ -9,6 +9,7 @@
//
import QtQuick 2.10
import QtQuick.Controls 2.3
import "../../simplifiedConstants" as SimplifiedConstants
import "../../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit
@ -20,8 +21,6 @@ Flickable {
id: root
contentWidth: parent.width
contentHeight: generalColumnLayout.height
topMargin: 24
bottomMargin: 24
clip: true
onAvatarNametagModeChanged: {
@ -31,7 +30,7 @@ Flickable {
onVisibleChanged: {
if (visible) {
root.contentX = 0;
root.contentY = -root.topMargin;
root.contentY = 0;
}
}
@ -39,19 +38,38 @@ Flickable {
id: simplifiedUI
}
Image {
id: accent
source: "../images/accent1.svg"
anchors.left: parent.left
anchors.top: parent.top
width: 83
height: 156
transform: Scale {
xScale: -1
origin.x: accent.width / 2
origin.y: accent.height / 2
}
}
ColumnLayout {
id: generalColumnLayout
anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top
spacing: simplifiedUI.margins.settings.spacingBetweenSettings
ColumnLayout {
id: avatarNameTagsContainer
Layout.preferredWidth: parent.width
Layout.topMargin: 24
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: avatarNameTagsTitle
text: "Avatar Name Tags"
Layout.maximumWidth: parent.width
@ -99,9 +117,9 @@ Flickable {
Layout.preferredWidth: parent.width
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: performanceTitle
text: "Graphics Preset"
text: "Graphics Settings"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 22
@ -115,7 +133,7 @@ Flickable {
SimplifiedControls.RadioButton {
id: performanceLow
text: "Low"
text: "Low Quality" + (PlatformInfo.getTierProfiled() === PerformanceEnums.LOW ? " (Recommended)" : "")
checked: Performance.getPerformancePreset() === PerformanceEnums.LOW
onClicked: {
Performance.setPerformancePreset(PerformanceEnums.LOW);
@ -124,7 +142,7 @@ Flickable {
SimplifiedControls.RadioButton {
id: performanceMedium
text: "Medium"
text: "Medium Quality" + (PlatformInfo.getTierProfiled() === PerformanceEnums.MID ? " (Recommended)" : "")
checked: Performance.getPerformancePreset() === PerformanceEnums.MID
onClicked: {
Performance.setPerformancePreset(PerformanceEnums.MID);
@ -133,7 +151,7 @@ Flickable {
SimplifiedControls.RadioButton {
id: performanceHigh
text: "High"
text: "High Quality" + (PlatformInfo.getTierProfiled() === PerformanceEnums.HIGH ? " (Recommended)" : "")
checked: Performance.getPerformancePreset() === PerformanceEnums.HIGH
onClicked: {
Performance.setPerformancePreset(PerformanceEnums.HIGH);
@ -147,7 +165,7 @@ Flickable {
Layout.preferredWidth: parent.width
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: cameraTitle
text: "Camera View"
Layout.maximumWidth: parent.width
@ -193,29 +211,36 @@ Flickable {
}
}
HifiStylesUit.GraphikRegular {
id: logoutText
text: (AccountServices.username === "Unknown user" ? "Log In" : "Logout " + AccountServices.username)
wrapMode: Text.Wrap
width: paintedWidth
height: paintedHeight
size: 22
color: simplifiedUI.colors.text.lightBlue
ColumnLayout {
id: logoutContainer
Layout.preferredWidth: parent.width
Layout.bottomMargin: 24
spacing: 0
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
parent.color = simplifiedUI.colors.text.lightBlueHover;
}
onExited: {
parent.color = simplifiedUI.colors.text.lightBlue;
}
onClicked: {
if (Account.loggedIn) {
AccountServices.logOut();
} else {
DialogsManager.showLoginDialog();
HifiStylesUit.GraphikRegular {
id: logoutText
text: (AccountServices.username === "Unknown user" ? "Log In" : "Logout " + AccountServices.username)
wrapMode: Text.Wrap
width: paintedWidth
height: paintedHeight
size: 14
color: simplifiedUI.colors.text.lightBlue
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
parent.color = simplifiedUI.colors.text.lightBlueHover;
}
onExited: {
parent.color = simplifiedUI.colors.text.lightBlue;
}
onClicked: {
if (Account.loggedIn) {
AccountServices.logOut();
} else {
DialogsManager.showLoginDialog();
}
}
}
}

View file

@ -0,0 +1,4 @@
<svg width="106" height="200" viewBox="0 0 106 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0L106 -9.26681e-06L83.1739 10.0481L0 0Z" fill="#FFED00"/>
<path d="M83.1738 10.0481L106 -1.99552e-06L106 200L83.1738 10.0481Z" fill="#FF42A7"/>
</svg>

After

Width:  |  Height:  |  Size: 263 B

View file

@ -0,0 +1,4 @@
<svg width="106" height="200" viewBox="0 0 106 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0L106 -9.26681e-06L83.1739 10.0481L0 0Z" fill="#FF42A7"/>
<path d="M83.1738 10.0481L106 -1.99552e-06L106 200L83.1738 10.0481Z" fill="#009EE0"/>
</svg>

After

Width:  |  Height:  |  Size: 263 B

View file

@ -0,0 +1,4 @@
<svg width="106" height="200" viewBox="0 0 106 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0L106 -9.26681e-06L83.1739 10.0481L0 0Z" fill="#009EE0"/>
<path d="M83.1738 10.0481L106 -1.99552e-06L106 200L83.1738 10.0481Z" fill="#FFED00"/>
</svg>

After

Width:  |  Height:  |  Size: 263 B

View file

@ -19,8 +19,6 @@ Flickable {
id: root
contentWidth: parent.width
contentHeight: vrColumnLayout.height
topMargin: 24
bottomMargin: 24
clip: true
function changePeakValuesEnabled(enabled) {
@ -33,7 +31,7 @@ Flickable {
AudioScriptingInterface.devices.input.peakValuesEnabled = visible;
if (visible) {
root.contentX = 0;
root.contentY = -root.topMargin;
root.contentY = 0;
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled);
} else {
AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled);
@ -45,19 +43,38 @@ Flickable {
id: simplifiedUI
}
Image {
id: accent
source: "../images/accent3.svg"
anchors.left: parent.left
anchors.top: parent.top
width: 83
height: 156
transform: Scale {
xScale: -1
origin.x: accent.width / 2
origin.y: accent.height / 2
}
}
ColumnLayout {
id: vrColumnLayout
anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top
spacing: simplifiedUI.margins.settings.spacingBetweenSettings
ColumnLayout {
id: controlsContainer
Layout.preferredWidth: parent.width
Layout.topMargin: 24
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: controlsTitle
text: "VR Movement Controls"
Layout.maximumWidth: parent.width
@ -143,7 +160,7 @@ Flickable {
Layout.preferredWidth: parent.width
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: micControlsTitle
text: "Default Mute Controls"
Layout.maximumWidth: parent.width
@ -154,6 +171,7 @@ Flickable {
ColumnLayout {
id: micControlsSwitchGroup
Layout.preferredWidth: parent.width
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
SimplifiedControls.Switch {
@ -185,7 +203,7 @@ Flickable {
Layout.preferredWidth: parent.width
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: inputDeviceTitle
text: "Which input device?"
Layout.maximumWidth: parent.width
@ -278,9 +296,10 @@ Flickable {
ColumnLayout {
id: outputDeviceContainer
Layout.preferredWidth: parent.width
Layout.bottomMargin: 24
spacing: 0
HifiStylesUit.GraphikRegular {
HifiStylesUit.GraphikSemiBold {
id: outputDeviceTitle
text: "Which output device?"
Layout.maximumWidth: parent.width

View file

@ -72,10 +72,14 @@ QtObject {
readonly property color border: "#00B4EF"
}
}
readonly property QtObject text: QtObject {
readonly property color enabled: "#FFFFFF"
readonly property color disabled: "#8F8F8F"
}
}
readonly property QtObject simplifiedSwitch: QtObject {
readonly property QtObject background: QtObject {
readonly property color disabled: "#616161"
readonly property color disabled: "#2B2B2B"
readonly property color off: "#616161"
readonly property color hover: "#616161"
readonly property color pressed: "#616161"
@ -144,6 +148,10 @@ QtObject {
readonly property color hover: "#FFFFFF"
readonly property color focus: "#FFFFFF"
}
readonly property QtObject scrollBar: QtObject {
readonly property color background: "#474747"
readonly property color contentItem: "#0198CB"
}
}
readonly property color darkSeparator: "#595959"
@ -183,7 +191,7 @@ QtObject {
readonly property QtObject settings: QtObject {
property int subtitleTopMargin: 2
property int settingsGroupTopMargin: 24
property int settingsGroupTopMargin: 14
property int spacingBetweenSettings: 48
property int spacingBetweenRadiobuttons: 14
}
@ -219,6 +227,10 @@ QtObject {
readonly property QtObject textField: QtObject {
readonly property int editPencilPadding: 6
}
readonly property QtObject scrollBar: QtObject {
readonly property int backgroundWidth: 9
readonly property int contentItemWidth: 7
}
}
}

View file

@ -16,6 +16,9 @@ import TabletScriptingInterface 1.0
Original.Button {
id: root
// The two properties below are used when calling showTemporaryText()
property string originalText: ""
property string temporaryText: ""
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
@ -103,4 +106,31 @@ Original.Button {
horizontalAlignment: Text.AlignHCenter
text: root.text
}
Timer {
id: showTemporaryTextTimer
interval: 1500
repeat: false
running: false
onTriggered: {
buttonText.text = root.originalText;
root.originalText = "";
}
}
function showTemporaryText() {
if (root.temporaryText === "") {
return;
}
if (showTemporaryTextTimer.running) {
showTemporaryTextTimer.restart();
return;
}
root.originalText = buttonText.text;
buttonText.text = root.temporaryText;
showTemporaryTextTimer.start();
}
}

View file

@ -44,7 +44,7 @@ Item {
anchors.bottom: parent.bottom
horizontalAlignment: Text.AlignRight
visible: sliderText.text != ""
color: simplifiedUI.colors.text.white
color: root.enabled ? simplifiedUI.colors.controls.slider.text.enabled : simplifiedUI.colors.controls.slider.text.disabled
size: simplifiedUI.sizes.controls.slider.labelTextSize
}

View file

@ -54,6 +54,7 @@ Item {
innerSwitchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.disabled;
return;
}
if (originalSwitch.checked) {
if (originalSwitch.hovered) {
innerSwitchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.hover;
@ -69,6 +70,10 @@ Item {
}
}
onEnabledChanged: {
originalSwitch.changeColor();
}
onCheckedChanged: {
originalSwitch.changeColor();
}
@ -88,7 +93,8 @@ Item {
background: Rectangle {
id: switchBackground
anchors.verticalCenter: parent.verticalCenter
color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.background.on : simplifiedUI.colors.controls.simplifiedSwitch.background.off
color: originalSwitch.enabled ? (originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.background.on :
simplifiedUI.colors.controls.simplifiedSwitch.background.off) : simplifiedUI.colors.controls.simplifiedSwitch.background.disabled
width: originalSwitch.width
height: simplifiedUI.sizes.controls.simplifiedSwitch.switchBackgroundHeight
radius: height/2
@ -113,7 +119,7 @@ Item {
height: width
radius: width/2
color: "transparent"
border.width: simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize
border.width: originalSwitch.enabled ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0
border.color: simplifiedUI.colors.controls.simplifiedSwitch.handle.activeBorder
}
@ -124,7 +130,7 @@ Item {
height: width
radius: width/2
color: simplifiedUI.colors.controls.simplifiedSwitch.handle.off
border.width: originalSwitch.pressed || originalSwitch.checked ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0
border.width: (originalSwitch.pressed || originalSwitch.checked) && originalSwitch.enabled ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0
border.color: originalSwitch.pressed ? simplifiedUI.colors.controls.simplifiedSwitch.handle.activeBorder : simplifiedUI.colors.controls.simplifiedSwitch.handle.checkedBorder
Component.onCompleted: {
@ -145,7 +151,7 @@ Item {
id: labelOff
text: ""
size: simplifiedUI.sizes.controls.simplifiedSwitch.labelTextSize
color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.text.off : simplifiedUI.colors.controls.simplifiedSwitch.text.on
color: originalSwitch.checked && !originalSwitch.enabled ? simplifiedUI.colors.controls.simplifiedSwitch.text.off : simplifiedUI.colors.controls.simplifiedSwitch.text.on
anchors.top: parent.top
anchors.topMargin: -2 // Necessary for text alignment
anchors.bottom: parent.bottom
@ -193,7 +199,7 @@ Item {
id: labelOn
text: ""
size: simplifiedUI.sizes.controls.simplifiedSwitch.labelTextSize
color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.text.on : simplifiedUI.colors.controls.simplifiedSwitch.text.off
color: originalSwitch.checked && originalSwitch.enabled ? simplifiedUI.colors.controls.simplifiedSwitch.text.on : simplifiedUI.colors.controls.simplifiedSwitch.text.off
anchors.top: parent.top
anchors.topMargin: -2 // Necessary for text alignment
anchors.left: parent.left

View file

@ -0,0 +1,51 @@
//
// VerticalScrollBar.qml
//
// Created by Zach Fox on 2019-06-17
// 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
//
import QtQuick 2.10
import QtQuick.Controls 2.3
import "../simplifiedConstants" as SimplifiedConstants
ScrollBar {
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
orientation: Qt.Vertical
policy: ScrollBar.AlwaysOn
anchors.top: parent.top
anchors.topMargin: 4
anchors.right: parent.right
anchors.rightMargin: 4
anchors.bottom: parent.bottom
anchors.bottomMargin: 4
width: simplifiedUI.sizes.controls.scrollBar.backgroundWidth
visible: parent.contentHeight > parent.parent.height
position: parent.contentY / parent.contentHeight
size: parent.parent.height / parent.contentHeight
minimumSize: 0.1
background: Rectangle {
color: simplifiedUI.colors.controls.scrollBar.background
anchors.fill: parent
}
contentItem: Rectangle {
width: simplifiedUI.sizes.controls.scrollBar.contentItemWidth
color: simplifiedUI.colors.controls.scrollBar.contentItem
anchors {
horizontalCenter: parent.horizontalCenter
topMargin: 1
bottomMargin: 1
}
}
onPositionChanged: {
if (pressed) {
parent.contentY = position * parent.contentHeight;
}
}
}

View file

@ -18,6 +18,16 @@ import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same c
Rectangle {
id: root
focus: true
signal keyPressEvent(int key, int modifiers)
Keys.onPressed: {
keyPressEvent(event.key, event.modifiers);
}
signal keyReleaseEvent(int key, int modifiers)
Keys.onReleased: {
keyReleaseEvent(event.key, event.modifiers);
}
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
@ -37,6 +47,12 @@ Rectangle {
onSkeletonModelURLChanged: {
root.updatePreviewUrl();
if ((MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) &&
topBarInventoryModel.count > 0) {
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url;
}
}
}
@ -83,6 +99,13 @@ Rectangle {
topBarInventoryModel.getNextPage();
} else {
inventoryFullyReceived = true;
// If we have an avatar in our inventory AND we haven't already auto-selected an avatar...
if ((!Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatar", false) ||
MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) && topBarInventoryModel.count > 0) {
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url;
}
}
}
}
@ -118,7 +141,7 @@ Rectangle {
id: avatarButtonContainer
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 16
anchors.leftMargin: 2
width: 48
height: width
@ -187,7 +210,7 @@ Rectangle {
id: inputDeviceButton
anchors.verticalCenter: parent.verticalCenter
anchors.left: avatarButtonContainer.right
anchors.leftMargin: 6
anchors.leftMargin: 2
width: 32
height: width
}
@ -197,7 +220,7 @@ Rectangle {
id: outputDeviceButtonContainer
anchors.verticalCenter: parent.verticalCenter
anchors.left: inputDeviceButton.right
anchors.leftMargin: 2
anchors.leftMargin: 7
width: 32
height: width
@ -209,9 +232,8 @@ Rectangle {
AudioScriptingInterface.systemInjectorGain === simplifiedUI.numericConstants.mutedValue
source: outputDeviceButton.outputMuted ? "./images/outputDeviceMuted.svg" : "./images/outputDeviceLoud.svg"
anchors.centerIn: parent
width: 20
height: 20
fillMode: Image.PreserveAspectFit
width: outputDeviceButton.outputMuted ? 25 : 26
height: 22
visible: false
}
@ -260,7 +282,7 @@ Rectangle {
id: statusButton
property string currentStatus
anchors.centerIn: parent
width: 15
width: 22
height: width
radius: width/2
visible: false
@ -281,6 +303,21 @@ Rectangle {
}
}
Image {
id: statusIcon
source: statusButton.currentStatus === "available" ? "images/statusPresent.svg" : "images/statusAway.svg"
anchors.centerIn: parent
width: statusButton.currentStatus === "busy" ? 13 : 14
height: statusButton.currentStatus === "busy" ? 2 : 10
}
ColorOverlay {
anchors.fill: statusIcon
opacity: statusButton.currentStatus ? (statusButtonMouseArea.containsMouse ? 1.0 : 0.7) : 0.7
source: statusIcon
color: "#ffffff"
}
MouseArea {
id: statusButtonMouseArea
anchors.fill: parent
@ -306,8 +343,8 @@ Rectangle {
id: hmdButtonContainer
anchors.verticalCenter: parent.verticalCenter
anchors.right: settingsButtonContainer.left
anchors.rightMargin: 14
width: 32
anchors.rightMargin: 8
width: 48
height: width
visible: false
@ -315,9 +352,8 @@ Rectangle {
id: displayModeImage
source: HMD.active ? "./images/desktopMode.svg" : "./images/vrMode.svg"
anchors.centerIn: parent
width: 29
height: 16
fillMode: Image.PreserveAspectFit
width: HMD.active ? 25 : 43
height: 22
visible: false
}
@ -376,17 +412,16 @@ Rectangle {
id: settingsButtonContainer
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 16
width: 32
anchors.rightMargin: 3
width: 36
height: width
Image {
id: settingsButtonImage
source: "./images/settings.svg"
anchors.centerIn: parent
width: 20
height: 20
fillMode: Image.PreserveAspectFit
width: 22
height: 22
visible: false
}
@ -455,5 +490,5 @@ Rectangle {
break;
}
}
signal sendToScript(var message);
signal sendToScript(var message)
}

View file

@ -1,13 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="30.941" height="22.781" fill="none" version="1.1" viewBox="0 0 30.941 22.781" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m29.57 1.4006c0.441 0.44032 0.7894 0.96444 1.0247 1.5415 0.2353 0.57705 0.3527 1.1954 0.3453 1.8185v9.06c0.0066 0.629-0.111 1.2531-0.3461 1.8366-0.2351 0.5834-0.583 1.1147-1.0239 1.5634-0.4179 0.4646-0.9304 0.8343-1.503 1.0844-0.5727 0.2501-1.1922 0.3747-1.817 0.3656h-9.69v2.11h6.33c0.2652 0 0.5196 0.1054 0.7071 0.2929 0.1876 0.1876 0.2929 0.4419 0.2929 0.7071s-0.1053 0.5196-0.2929 0.7071c-0.1875 0.1876-0.4419 0.2929-0.7071 0.2929h-14.53c-0.73 0-1.09-0.34-1.09-1s0.36001-1 1.09-1h6.25v-2.11h-9.92c-0.62489 0.0098-1.2446-0.1146-1.8173-0.3647-0.57272-0.2502-1.0851-0.6202-1.5027-1.0853-0.44084-0.4487-0.78878-0.98-1.0239-1.5634-0.23509-0.5835-0.35272-1.2076-0.34613-1.8366v-9.06c-0.007379-0.62314 0.11003-1.2414 0.34532-1.8185 0.23529-0.57706 0.58369-1.1012 1.0247-1.5415 0.42558-0.45144 0.94066-0.80913 1.5123-1.0502 0.57167-0.24106 1.1873-0.36021 1.8077-0.34981h21.56c0.6202-0.0091691 1.2355 0.11053 1.807 0.35152 0.5715 0.24099 1.0867 0.59802 1.513 1.0485zm-0.82 3.36c0.0079-0.33937-0.0536-0.67677-0.1809-0.99147-0.1272-0.3147-0.3175-0.60005-0.5591-0.83853-0.2262-0.23901-0.4992-0.42893-0.802-0.55795-0.3028-0.12903-0.6289-0.1944-0.958-0.19205h-21.56c-0.32929-0.00355-0.65573 0.06127-0.95868 0.19037-0.30295 0.12909-0.57581 0.31965-0.80132 0.55963-0.24352 0.23703-0.43506 0.52212-0.56246 0.83717-0.12739 0.31505-0.18785 0.65315-0.17754 0.99283v9.06c-0.01049 0.3412 0.04985 0.6809 0.17722 0.9976 0.12736 0.3167 0.31899 0.6035 0.56278 0.8424 0.22601 0.2387 0.49919 0.4277 0.80218 0.5551 0.303 0.1274 0.62918 0.1904 0.95782 0.1849h21.56c0.3285 0.0043 0.6543-0.0593 0.9571-0.1866s0.5762-0.3157 0.8029-0.5534c0.2419-0.2403 0.4322-0.5274 0.5595-0.8438 0.1272-0.3163 0.1886-0.6553 0.1805-0.9962z" fill="#000"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 25 22" style="enable-background:new 0 0 25 22;" xml:space="preserve">
<path d="M23.24,0H1.77C0.79,0,0,0.8,0,1.78v12.2c0,0.98,0.79,1.78,1.77,1.78h9.22v3.17H7.85c-0.83,0-1.52,0.69-1.52,1.53
S7.02,22,7.85,22h9.29c0.83,0,1.52-0.69,1.52-1.53s-0.68-1.53-1.52-1.53h-3.13v-3.17h9.22c0.97,0,1.77-0.8,1.77-1.78V1.78
C25.02,0.8,24.22,0,23.24,0z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 629 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="23.56" height="26.476" fill="none" version="1.1" viewBox="0 0 23.56 26.476" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m23.207 10.353c-0.0809-0.1096-0.1864-0.1987-0.3079-0.2601-0.1216-0.0613-0.2559-0.0933-0.3921-0.0933s-0.2705 0.032-0.3921 0.0933c-0.1216 0.0614-0.227 0.1505-0.3079 0.2601l-4.46 4.45c-0.1079 0.0831-0.1953 0.1899-0.2554 0.3121-0.0601 0.1223-0.0914 0.2567-0.0914 0.3929s0.0313 0.2706 0.0914 0.3928 0.1475 0.229 0.2554 0.3122c0.0819 0.1096 0.1883 0.1987 0.3107 0.26 0.1224 0.0614 0.2574 0.0933 0.3943 0.0933s0.2719-0.0319 0.3943-0.0933c0.1224-0.0613 0.2288-0.1504 0.3107-0.26l4.45-4.45c0.1097-0.082 0.1987-0.1883 0.2601-0.3107 0.0613-0.1224 0.0932-0.2574 0.0932-0.3943s-0.0319-0.2719-0.0932-0.3943c-0.0614-0.1224-0.1504-0.2288-0.2601-0.3107zm0 5.86c0.1097-0.082 0.1987-0.1883 0.2601-0.3107 0.0613-0.1224 0.0932-0.2574 0.0932-0.3943s-0.0319-0.2719-0.0932-0.3943c-0.0614-0.1224-0.1504-0.2288-0.2601-0.3107l-4.45-4.45c-0.0819-0.1097-0.1883-0.1987-0.3107-0.2601-0.1224-0.0613-0.2574-0.0933-0.3943-0.0933s-0.2719 0.032-0.3943 0.0933c-0.1224 0.0614-0.2288 0.1504-0.3107 0.2601-0.1079 0.0831-0.1953 0.1899-0.2554 0.3121-0.0601 0.1223-0.0914 0.2567-0.0914 0.3929s0.0313 0.2706 0.0914 0.3928 0.1475 0.229 0.2554 0.3122l4.46 4.45c0.0809 0.1096 0.1863 0.1986 0.3079 0.26s0.2559 0.0934 0.3921 0.0934 0.2705-0.032 0.3921-0.0934c0.1215-0.0614 0.227-0.1504 0.3079-0.26z" fill="#000"/>
<path d="m10.341 1.0357c0.3782-0.48138 0.9083-0.82052 1.5039-0.96216 0.5956-0.14164 1.2216-0.07743 1.7761 0.18216 0.6142 0.17933 1.1481 0.56434 1.5122 1.0905 0.3641 0.52616 0.5363 1.1615 0.4878 1.7995v0.55001 1.41c0 0.58-0.05 1.18-0.08 1.83s0 1.3 0 2v14.34c0.0746 0.634-0.0599 1.2749-0.383 1.8255-0.3231 0.5505-0.8172 0.9805-1.407 1.2245-0.3071 0.0833-0.6223 0.1336-0.94 0.15-0.4473 0.0083-0.8906-0.0856-1.2961-0.2745-0.4055-0.1888-0.7625-0.4678-1.0439-0.8155-2-2.19-3.39-3.7-4.22-4.53-0.07888-0.0913-0.17528-0.1657-0.28351-0.219-0.10822-0.0532-0.22607-0.0842-0.34649-0.091h-1.33c-0.5977 0.0074-1.1954-0.0194-1.79-0.08-0.33315-0.0238-0.6578-0.116-0.95373-0.2708-0.29594-0.1549-0.55679-0.3691-0.76624-0.6292-0.45471-0.5112-0.72881-1.1577-0.78003-1.84v-8.82c-0.010075-0.39268 0.068268-0.7826 0.22925-1.1409 0.16098-0.35831 0.40047-0.67584 0.70074-0.92909 0.627-0.54844 1.4373-0.84114 2.27-0.82001h2.42c0.12092-0.00919 0.23886-0.04218 0.34698-0.09709 0.10812-0.05492 0.20428-0.13068 0.28302-0.2229 0.97334-1.12 2.3367-2.6733 4.09-4.66zm-1.1 5.86c-0.36 0.37-0.91001 1-1.64 1.8-0.21506 0.26203-0.52331 0.4305-0.85999 0.47h-3.83v8.28h3.91c0.11347-5e-3 0.22682 0.0127 0.33331 0.0522s0.20395 0.1 0.28668 0.1778l2.11 2.35c0.21717 0.2771 0.45449 0.5378 0.70999 0.78l1 1.09c0.1508 0.1381 0.2821 0.2962 0.39 0.47l0.47 0.47 0.31 0.55v-20.24l-1.17 1.41c-0.92 1.04-1.55 1.78-2.02 2.34z" fill="#000"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 25 22" style="enable-background:new 0 0 25 22;" xml:space="preserve">
<path d="M1.23,15.44h0.95l9.04-8.98V3.22c0-1.03-1.32-1.55-2.1-0.82L5.15,6.22C4.92,6.43,4.61,6.55,4.28,6.55H1.23
C0.55,6.55,0,7.07,0,7.71v6.57C0,14.92,0.55,15.44,1.23,15.44z M21.53,2.57l0.3-0.3c0.52-0.52,0.52-1.36,0-1.88s-1.37-0.52-1.9,0
L0.47,19.72c-0.52,0.52-0.52,1.36,0,1.88C0.73,21.87,1.07,22,1.41,22c0.34,0,0.69-0.13,0.95-0.39l4.35-4.32l2.41,2.31
c0.77,0.73,2.1,0.21,2.1-0.82v-5.97l3.79-3.76c0.47,0.53,0.75,1.22,0.75,1.94c0,1.04-0.56,2.01-1.47,2.53
c-0.37,0.22-0.5,0.69-0.29,1.06c0.15,0.25,0.41,0.39,0.68,0.39c0.13,0,0.27-0.03,0.39-0.1c1.39-0.8,2.25-2.28,2.25-3.88
c0-1.14-0.45-2.23-1.21-3.04l1.65-1.64C18.94,7.58,19.6,9.23,19.6,11c0,2.46-1.34,4.76-3.49,6c-0.37,0.22-0.5,0.69-0.29,1.06
c0.15,0.25,0.41,0.39,0.68,0.39c0.13,0,0.27-0.03,0.39-0.1c2.63-1.51,4.27-4.33,4.27-7.35c0-2.18-0.82-4.22-2.29-5.78l1.55-1.54
c1.92,1.95,3.01,4.57,3.01,7.32c0,3.73-2.02,7.2-5.27,9.07c-0.37,0.22-0.5,0.69-0.29,1.06c0.15,0.25,0.41,0.39,0.68,0.39
c0.13,0,0.27-0.03,0.39-0.1C22.68,19.27,25,15.28,25,11C25,7.83,23.75,4.82,21.53,2.57z"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -1,13 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="26.34" height="26.48" fill="none" version="1.1" viewBox="0 0 26.34 26.48" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m25.675 11.57c0.4076 0.4141 0.6449 0.966 0.6651 1.5466v0.1238c0.0042 0.3038-0.0527 0.6053-0.167 0.8868s-0.2839 0.5372-0.4987 0.752c-0.2149 0.2149-0.4706 0.3844-0.752 0.4988-0.2815 0.1143-0.5831 0.1711-0.8869 0.1669-0.3355 8e-4 -0.6656-0.0844-0.9589-0.2474-0.3766-0.0257-0.747-0.1092-1.0982-0.2475-0.2256 1.0915-0.6334 2.1373-1.2063 3.0934 0.3383 0.1098 0.6351 0.3202 0.8506 0.6032h0.1237c0.2959 0.1271 0.5763 0.2879 0.8353 0.4794 0.2297 0.2182 0.4127 0.4809 0.5378 0.7721 0.125 0.2911 0.1894 0.6047 0.1894 0.9216 0 0.3168-0.0644 0.6304-0.1894 0.9216-0.1251 0.2911-0.3081 0.5538-0.5378 0.772-0.4755 0.3895-1.0713 0.6024-1.686 0.6024s-1.2103-0.2129-1.6858-0.6024c-0.1975-0.2634-0.3636-0.5489-0.495-0.8507 0 0 0-0.1237-0.1082-0.1237-0.1366-0.0967-0.2512-0.221-0.3365-0.3649s-0.1393-0.3042-0.1585-0.4703c-0.9266 0.5763-1.9476 0.9847-3.016 1.2064 0.1319 0.3478 0.2153 0.7121 0.2475 1.0827 0.1498 0.3031 0.229 0.6362 0.2319 0.9744 0.0075 0.6273-0.2313 1.2326-0.665 1.6859-0.1939 0.2211-0.4312 0.3999-0.6974 0.525-0.2661 0.1251-0.5553 0.1938-0.8493 0.2019-0.3179-7e-4 -0.6324-0.0654-0.9247-0.1903s-0.5564-0.3074-0.7766-0.5366c-0.2267-0.2181-0.4068-0.4801-0.5291-0.7699s-0.1843-0.6015-0.1824-0.916c0.0028-0.3382 0.0822-0.6713 0.232-0.9744 0.0245-0.3718 0.108-0.7372 0.2474-1.0827-1.0935-0.2189-2.1404-0.6272-3.0934-1.2064-0.13354 0.2927-0.29406 0.5723-0.47946 0.8352l-0.12377 0.1237c-0.04312 0.3351-0.2151 0.6403-0.47946 0.8507-0.22555 0.2094-0.4912 0.3709-0.78099 0.4745-0.28979 0.1037-0.59764 0.1475-0.90485 0.1287-0.30958 0.0191-0.61986-0.0244-0.91221-0.1281-0.29234-0.1036-0.5608-0.2652-0.7892-0.4751-0.22782-0.2193-0.40902-0.4824-0.5328-0.7734-0.12379-0.291-0.18758-0.604-0.18758-0.9202 0-0.3163 0.06379-0.6293 0.18758-0.9203 0.12378-0.291 0.30498-0.554 0.5328-0.7734 0.2904-0.2218 0.62143-0.3847 0.97442-0.4794 0-0.1702 0.35581-0.3712 0.85075-0.6032-0.58522-0.9517-0.99885-1.9987-1.2219-3.0934-0.30719 0.2451-0.68976 0.3762-1.0827 0.3712v-0.1237c-0.27587 0.2028-0.61935 0.2915-0.95893 0.2474-0.63061 3e-4 -1.2381-0.2371-1.7013-0.665-0.23125-0.2055-0.41581-0.4582-0.54121-0.741-0.1254-0.2828-0.18876-0.5892-0.18578-0.8985 9.9624e-4 -0.3156 0.06594-0.6276 0.19088-0.9174 0.12494-0.2897 0.30734-0.5512 0.53611-0.7685 0.22023-0.2292 0.48434-0.4117 0.77665-0.5366s0.60679-0.1897 0.92467-0.1904c0.33503 0.0032 0.66421 0.0882 0.95893 0.2475 0.37013 0.0252 0.73475 0.1034 1.0827 0.232 0.21231-1.0978 0.62669-2.1467 1.2219-3.0933-0.33511-0.04313-0.64032-0.21512-0.85075-0.47948h-0.12367c-0.30979-0.16124-0.59609-0.3642-0.85075-0.60321-0.43277-0.44917-0.6693-1.0519-0.6577-1.6755 0.01161-0.62362 0.27045-1.2171 0.71963-1.6499 0.44918-0.43277 1.0518-0.66938 1.6754-0.65777 0.62363 0.0116 1.2171 0.27046 1.6499 0.71964 0.23692 0.22641 0.40342 0.51644 0.47946 0.83521 0.30048 0.25161 0.512 0.59327 0.60323 0.97442 0.92503-0.65792 1.9796-1.1114 3.0934-1.3302-0.1612-0.29958-0.2461-0.63423-0.2474-0.97442v-0.10827c-0.2062-0.42346-0.2768-0.90022-0.202-1.3652 0.0747-0.46502 0.2911-0.89566 0.6195-1.2332 0.2128-0.21772 0.4683-0.38917 0.7504-0.50361 0.2821-0.11444 0.5848-0.16941 0.8891-0.16146 0.3109-0.0053511 0.6199 0.050637 0.9092 0.16476 0.2893 0.11412 0.5532 0.28413 0.7767 0.50032 0.2242 0.1913 0.405 0.42822 0.5304 0.69493s0.1923 0.55708 0.1965 0.85175c-0.0028 0.33814-0.0821 0.67126-0.2319 0.97442v0.10827c-0.0087 0.3392-0.0934 0.67214-0.2475 0.97441 1.056 0.3181 2.069 0.76483 3.016 1.3302 0.0142-0.18703 0.0653-0.36939 0.1502-0.53662 0.085-0.16723 0.2021-0.31601 0.3448-0.43779 0.1377-0.31908 0.3436-0.60415 0.6032-0.83521 0.1944-0.24043 0.4428-0.43159 0.725-0.55791 0.2822-0.12631 0.5902-0.18423 0.899-0.16904 0.2997-0.01337 0.599 0.03308 0.8805 0.13665s0.5395 0.26217 0.759 0.46656c0.2598 0.1993 0.4703 0.45571 0.6152 0.74939s0.2203 0.61676 0.2203 0.94423-0.0754 0.65054-0.2203 0.94422c-0.1449 0.29369-0.3554 0.55011-0.6152 0.7494-0.2362 0.26068-0.5265 0.46656-0.8507 0.60321-0.2883 0.22513-0.6201 0.38835-0.9744 0.47947 0.5779 0.96792 1.0252 2.0081 1.3301 3.0934 0.3032-0.1498 0.6363-0.2291 0.9745-0.232h0.1237c0.2933-0.1631 0.6234-0.2482 0.959-0.2475 0.3033 0.0194 0.5991 0.1024 0.8683 0.2436 0.2691 0.1412 0.5056 0.3375 0.6938 0.5762zm-9.0017 5.1968c0.5809-0.5759 1.0105-1.2864 1.2506-2.0684 0.2402-0.782 0.2833-1.6112 0.1257-2.4139-0.1576-0.8026-0.511-1.5539-1.029-2.1871-0.5179-0.63313-1.1843-1.1285-1.9399-1.442-0.7555-0.31354-1.5767-0.43555-2.3908-0.35517-0.814 0.08038-1.5956 0.36066-2.2753 0.81591-0.67959 0.45525-1.2362 1.0714-1.6203 1.7936-0.38412 0.7222-0.58387 1.5281-0.58143 2.3461 0.04947 1.2984 0.58636 2.5304 1.5036 3.4505 0.91727 0.9202 2.1476 1.4609 3.4458 1.5144 0.6529 0.0061 1.3004-0.1195 1.9036-0.3693 0.6033-0.2498 1.15-0.6187 1.6074-1.0846z" fill="#000"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 22 22" style="enable-background:new 0 0 22 22;" xml:space="preserve">
<path id="settings_filled_1_" d="M22,11L22,11c0-0.76-0.57-1.39-1.32-1.48l-2.54-0.3c0,0,0,0-0.01,0c-0.17-0.69-0.45-1.36-0.83-1.99
c0,0,0,0,0-0.01l1.59-2.01c0.47-0.59,0.42-1.44-0.12-1.98l0,0c-0.54-0.54-1.39-0.58-1.98-0.12l-2.01,1.59c0,0,0,0-0.01,0
c-0.63-0.38-1.3-0.65-1.99-0.82c0,0,0,0,0-0.01l-0.3-2.54C12.39,0.57,11.75,0,11,0l0,0c-0.76,0-1.39,0.57-1.48,1.32l-0.3,2.54
c0,0,0,0,0,0.01C8.52,4.04,7.85,4.32,7.22,4.69c0,0,0,0-0.01,0L5.2,3.11C4.61,2.64,3.76,2.69,3.22,3.22l0,0
C2.69,3.76,2.64,4.61,3.11,5.2l1.59,2.01c0,0,0,0,0,0.01c-0.38,0.63-0.65,1.3-0.82,1.99c0,0,0,0-0.01,0l-2.54,0.3
C0.57,9.61,0,10.25,0,11l0,0c0,0.76,0.57,1.39,1.32,1.48l2.54,0.3c0,0,0,0,0.01,0c0.17,0.69,0.45,1.36,0.83,1.99c0,0,0,0,0,0.01
L3.11,16.8c-0.47,0.59-0.42,1.44,0.12,1.98l0,0c0.54,0.54,1.39,0.58,1.98,0.12l2.01-1.59c0,0,0,0,0.01,0
c0.63,0.38,1.3,0.65,1.99,0.82c0,0,0,0,0,0.01l0.3,2.54C9.61,21.43,10.25,22,11,22l0,0c0.76,0,1.39-0.57,1.48-1.32l0.3-2.54
c0,0,0,0,0-0.01c0.69-0.17,1.36-0.45,1.99-0.83c0,0,0,0,0.01,0l2.01,1.59c0.59,0.47,1.44,0.42,1.98-0.12l0,0
c0.54-0.54,0.58-1.39,0.12-1.98l-1.59-2.01c0,0,0,0,0-0.01c0.38-0.63,0.65-1.3,0.82-1.99c0,0,0,0,0.01,0l2.54-0.3
C21.43,12.39,22,11.75,22,11z M13.98,13.29c-1.52,1.96-4.45,1.96-5.97,0c-1.04-1.33-1.04-3.25,0-4.58c1.52-1.96,4.45-1.96,5.97,0
C15.02,10.04,15.02,11.95,13.98,13.29z"/>
</svg>

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.2 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 72.48 12" style="enable-background:new 0 0 72.48 12;" xml:space="preserve">
<style type="text/css">
.st0{fill:#020202;}
</style>
<path class="st0" d="M66.48,12H6c-3.31,0-6-2.69-6-6s2.69-6,6-6h60.48c3.31,0,6,2.69,6,6S69.79,12,66.48,12z"/>
</svg>

After

Width:  |  Height:  |  Size: 530 B

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 76.13 54.75" style="enable-background:new 0 0 76.13 54.75;" xml:space="preserve">
<path d="M27.38,54.75c-1.54,0-3.07-0.59-4.24-1.76L1.76,31.61c-2.34-2.34-2.34-6.14,0-8.48c2.34-2.34,6.14-2.34,8.48,0l17.14,17.14
L65.9,1.76c2.34-2.34,6.14-2.34,8.48,0s2.34,6.14,0,8.48L31.62,53C30.44,54.18,28.9,54.75,27.38,54.75z"/>
</svg>

After

Width:  |  Height:  |  Size: 603 B

View file

@ -1,13 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="34.613" height="18.502" fill="none" version="1.1" viewBox="0 0 34.613 18.502" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<path d="m27.112 18.501h-5.47c-1 0-2-0.86-3.13-2.57-0.3008-0.5432-0.6971-1.0276-1.17-1.43l-1.17 1.41c-1.25 1.68-2.37 2.59-3.36 2.59h-5.23c-0.99178 0.0181-1.9771-0.1628-2.8978-0.5321s-1.7579-0.9194-2.4622-1.6179c-0.72014-0.6727-1.2901-1.4898-1.6727-2.3979-0.38256-0.9082-0.56906-1.8869-0.54731-2.8721v-3.58c-0.017013-0.99193 0.17144-1.9767 0.5535-2.8922s0.94946-1.7422 1.6665-2.4278c0.70151-0.70433 1.5376-1.2603 2.4584-1.6348 0.92084-0.37452 1.9076-0.55993 2.9016-0.54519h19.53c0.9864-0.0053033 1.9641 0.18507 2.8764 0.5601s1.7412 0.92727 2.4387 1.6248 1.2498 1.5264 1.6248 2.4387c0.375 0.91233 0.5654 1.89 0.5601 2.8764v3.51c0.0183 0.9778-0.1639 1.949-0.5354 2.8536-0.3715 0.9047-0.9244 1.7237-1.6246 2.4064-0.6896 0.718-1.5196 1.2864-2.4382 1.6701-0.9186 0.3836-1.9064 0.5742-2.9018 0.5599zm-9.77-6c0.83 0 1.77 0.78 2.81 2.34 0.84 1.09 1.3 1.66 1.49 1.66h5.47c0.7244 0.0102 1.4433-0.1263 2.1136-0.4013 0.6702-0.275 1.2779-0.6827 1.7864-1.1987 0.5281-0.495 0.9469-1.0951 1.2293-1.7615 0.2824-0.6665 0.4223-1.3847 0.4107-2.1085v-3.53c0.0116-0.72376-0.1283-1.442-0.4107-2.1084-0.2824-0.66649-0.7012-1.2665-1.2293-1.7616-0.5085-0.51598-1.1162-0.92372-1.7864-1.1987-0.6703-0.27497-1.3892-0.41148-2.1136-0.40132h-19.53c-0.72598-0.01094-1.4466 0.12518-2.1186 0.40015-0.67198 0.27498-1.2813 0.68312-1.7914 1.1999-0.52617 0.49655-0.94359 1.0969-1.2259 1.763s-0.4233 1.3836-0.41412 2.107v3.51c-0.00918 0.7234 0.13183 1.4409 0.41412 2.107s0.69971 1.2665 1.2259 1.763c0.50835 0.5204 1.117 0.9322 1.789 1.2106 0.67205 0.2785 1.3936 0.4178 2.121 0.4094h5.23c0.36 0 0.94-0.6 1.72-1.8 1.09-1.51 2-2.26 2.73-2.26z" fill="#000"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 42 22" style="enable-background:new 0 0 42 22;" xml:space="preserve">
<path d="M33.97,0H8.02C3.59,0,0,3.63,0,8.09v5.1C0,18.06,3.91,22,8.73,22h6.29c1.58,0,3.09-0.63,4.2-1.76l1.16-1.17
c0.34-0.35,0.9-0.35,1.24,0l1.16,1.17c1.12,1.13,2.63,1.76,4.2,1.76h6.99c4.43,0,8.03-3.63,8.03-8.1V8.1C41.99,3.63,38.4,0,33.97,0z
M17.41,13.39c-0.53,1.19-1.48,2.15-2.66,2.68C9.56,18.4,4.53,13.33,6.85,8.09C7.37,6.9,8.32,5.94,9.5,5.41
C14.69,3.08,19.72,8.15,17.41,13.39z M35.15,13.39c-0.53,1.19-1.48,2.15-2.66,2.68c-5.19,2.33-10.22-2.74-7.91-7.98
c0.52-1.19,1.48-2.15,2.66-2.68C32.43,3.08,37.46,8.15,35.15,13.39z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 892 B

View file

@ -24,7 +24,8 @@ StackView {
signal sendToScript(var message);
function pushSource(path) {
profileRoot.push(Qt.resolvedUrl(path));
var item = Qt.createComponent(Qt.resolvedUrl(path));
profileRoot.push(item);
}
function popSource() {

View file

@ -22,7 +22,8 @@ StackView {
signal sendToScript(var message);
function pushSource(path) {
profileRoot.push(Qt.reslovedUrl(path));
var item = Qt.createComponent(Qt.resolvedUrl(path));
profileRoot.push(item);
}
function popSource() {

View file

@ -5,6 +5,9 @@ import TabletScriptingInterface 1.0
Item {
id: tabletButton
// NOTE: These properties form part of the "TabletButtonProxy.ButtonProperties" type.
// Keep the type's JSDoc up to date with any changes.
property color defaultCaptionColor: "#ffffff"
property color captionColor: defaultCaptionColor
@ -18,15 +21,15 @@ Item {
property string activeText: tabletButton.text
property string activeHoverText: tabletButton.activeText
property bool isActive: false
property bool inDebugMode: false
property bool inDebugMode: false // tablet only
property bool isEntered: false
property double sortOrder: 100
property int stableOrder: 0
property var tabletRoot;
property var flickable: null
property var gridView: null
property var tabletRoot; // tablet only
property var flickable: null // tablet only
property var gridView: null // tablet only
property int buttonIndex: -1
property int buttonIndex: -1 // tablet only
width: 129
height: 129

View file

@ -22,7 +22,8 @@ StackView {
signal sendToScript(var message);
function pushSource(path) {
profileRoot.push(Qt.resolvedUrl(path));
var item = Qt.createComponent(Qt.resolvedUrl(path));
profileRoot.push(item);
}
function popSource() {

View file

@ -22,7 +22,8 @@ StackView {
signal sendToScript(var message);
function pushSource(path) {
profileRoot.push(Qt.resolvedUrl(path));
var item = Qt.createComponent(Qt.resolvedUrl(path));
profileRoot.push(item);
}
function popSource() {

View file

@ -22,7 +22,8 @@ StackView {
signal sendToScript(var message);
function pushSource(path) {
profileRoot.push(Qt.resolvedUrl(path));
var item = Qt.createComponent(Qt.resolvedUrl(path));
profileRoot.push(item);
}
function popSource() {

View file

@ -22,7 +22,8 @@ StackView {
signal sendToScript(var message);
function pushSource(path) {
profileRoot.push(Qt.resolvedUrl(path));
var item = Qt.createComponent(Qt.resolvedUrl(path));
profileRoot.push(item);
}
function popSource() {

View file

@ -3,6 +3,9 @@ import QtQuick 2.5
StateImage {
id: button
// NOTE: These properties form part of the "TabletButtonProxy.ButtonProperties" type.
// Keep the type's JSDoc up to date with any changes.
property color defaultCaptionColor: "#ffffff"
property color captionColor: defaultCaptionColor

View file

@ -0,0 +1,4 @@
module toolbars
StateImage 1.0 StateImage.qml
Toolbar 1.0 Toolbar.qml
ToolbarButton 1.0 ToolbarButton.qml

View file

@ -104,6 +104,7 @@
#include <hfm/ModelFormatRegistry.h>
#include <model-networking/ModelCacheScriptingInterface.h>
#include <material-networking/TextureCacheScriptingInterface.h>
#include <material-networking/MaterialCache.h>
#include <ModelEntityItem.h>
#include <NetworkAccessManager.h>
#include <NetworkingConstants.h>
@ -877,6 +878,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
DependencyManager::set<AudioScope>();
DependencyManager::set<DeferredLightingEffect>();
DependencyManager::set<TextureCache>();
DependencyManager::set<MaterialCache>();
DependencyManager::set<TextureCacheScriptingInterface>();
DependencyManager::set<FramebufferCache>();
DependencyManager::set<AnimationCache>();
@ -950,6 +952,19 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
DependencyManager::set<GrabManager>();
DependencyManager::set<AvatarPackager>();
QString setBookmarkValue = getCmdOption(argc, constArgv, "--setBookmark");
if (!setBookmarkValue.isEmpty()) {
// Bookmarks are expected to be in a name=url form.
// An `=` character in the name or url is unsupported.
auto parts = setBookmarkValue.split("=");
if (parts.length() != 2) {
qWarning() << "Malformed setBookmark argument: " << setBookmarkValue;
} else {
qDebug() << "Setting bookmark" << parts[0] << "to" << parts[1];
DependencyManager::get<LocationBookmarks>()->insert(parts[0], parts[1]);
}
}
return previousSessionCrashed;
}
@ -1330,9 +1345,22 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress);
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateThreadPoolCount);
connect(this, &Application::activeDisplayPluginChanged, this, [](){
connect(this, &Application::activeDisplayPluginChanged, this, [=](){
qApp->setProperty(hifi::properties::HMD, qApp->isHMDMode());
auto displayPlugin = qApp->getActiveDisplayPlugin();
if (displayPlugin->isHmd()) {
if (_preferredCursor.get() == Cursor::Manager::getIconName(Cursor::Icon::RETICLE)) {
setPreferredCursor(Cursor::Manager::getIconName(Cursor::Icon::RETICLE));
}
else {
setPreferredCursor(Cursor::Manager::getIconName(Cursor::Icon::ARROW));
}
}
else {
setPreferredCursor(Cursor::Manager::getIconName(Cursor::Icon::SYSTEM));
}
setCrashAnnotation("display_plugin", displayPlugin->getName().toStdString());
setCrashAnnotation("hmd", displayPlugin->isHmd() ? "1" : "0");
});
@ -1363,6 +1391,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(myAvatar.get(), &MyAvatar::positionGoneTo,
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
connect(myAvatar.get(), &MyAvatar::positionGoneTo, this, [this] {
if (!_physicsEnabled) {
// when we arrive somewhere without physics enabled --> startSafeLanding
_octreeProcessor.startSafeLanding();
}
}, Qt::QueuedConnection);
connect(myAvatar.get(), &MyAvatar::skeletonModelURLChanged, [](){
QUrl avatarURL = qApp->getMyAvatar()->getSkeletonModelURL();
setCrashAnnotation("avatar", avatarURL.toString().toStdString());
@ -2485,6 +2520,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
pauseUntilLoginDetermined();
}
void Application::setFailedToConnectToEntityServer() {
_failedToConnectToEntityServer = true;
}
void Application::updateVerboseLogging() {
auto menu = Menu::getInstance();
if (!menu) {
@ -2695,9 +2734,11 @@ void Application::cleanupBeforeQuit() {
}
getEntities()->shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
getEntities()->clear();
// Clear any queued processing (I/O, FBX/OBJ/Texture parsing)
QThreadPool::globalInstance()->clear();
QThreadPool::globalInstance()->waitForDone();
DependencyManager::destroy<RecordingScriptingInterface>();
@ -2761,7 +2802,6 @@ void Application::cleanupBeforeQuit() {
// destroy Audio so it and its threads have a chance to go down safely
// this must happen after QML, as there are unexplained audio crashes originating in qtwebengine
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "stop");
DependencyManager::destroy<AudioClient>();
DependencyManager::destroy<AudioScriptingInterface>();
@ -2827,6 +2867,7 @@ Application::~Application() {
DependencyManager::destroy<AnimationCacheScriptingInterface>();
DependencyManager::destroy<AnimationCache>();
DependencyManager::destroy<FramebufferCache>();
DependencyManager::destroy<MaterialCache>();
DependencyManager::destroy<TextureCacheScriptingInterface>();
DependencyManager::destroy<TextureCache>();
DependencyManager::destroy<ModelCacheScriptingInterface>();
@ -2862,6 +2903,16 @@ Application::~Application() {
// Can't log to file past this point, FileLogger about to be deleted
qInstallMessageHandler(LogHandler::verboseMessageHandler);
#ifdef Q_OS_MAC
// Clear the event queue before application is totally destructed.
// This will drain the messasge queue of pending "deleteLaters" queued up
// during shutdown of the script engines.
// We do this here because there is a possiblty that [NSApplication terminate:]
// will be called during processEvents which will invoke all static destructors.
// We want to postpone this utill the last possible moment.
QCoreApplication::processEvents();
#endif
}
void Application::initializeGL() {
@ -2921,8 +2972,10 @@ void Application::initializeGL() {
#if !defined(DISABLE_QML)
QStringList chromiumFlags;
// HACK: re-expose mic and camera to prevent crash on domain-change in chromium's media::FakeAudioInputStream::ReadAudioFromSource()
// Bug 21993: disable microphone and camera input
chromiumFlags << "--use-fake-device-for-media-stream";
//chromiumFlags << "--use-fake-device-for-media-stream";
// Disable signed distance field font rendering on ATI/AMD GPUs, due to
// https://highfidelity.manuscript.com/f/cases/13677/Text-showing-up-white-on-Marketplace-app
std::string vendor{ (const char*)glGetString(GL_VENDOR) };
@ -3065,7 +3118,22 @@ void Application::showLoginScreen() {
#endif
}
static const QUrl AUTHORIZED_EXTERNAL_QML_SOURCE { "https://content.highfidelity.com/Experiences/Releases" };
void Application::initializeUi() {
// Allow remote QML content from trusted sources ONLY
{
auto defaultUrlValidator = OffscreenQmlSurface::getUrlValidator();
auto newValidator = [=](const QUrl& url)->bool {
if (AUTHORIZED_EXTERNAL_QML_SOURCE.isParentOf(url)) {
return true;
}
return defaultUrlValidator(url);
};
OffscreenQmlSurface::setUrlValidator(newValidator);
}
AddressBarDialog::registerType();
ErrorDialog::registerType();
LoginDialog::registerType();
@ -3727,18 +3795,6 @@ void Application::resizeGL() {
DependencyManager::get<FramebufferCache>()->setFrameBufferSize(fromGlm(renderSize));
}
auto renderResolutionScale = getRenderResolutionScale();
if (displayPlugin->getRenderResolutionScale() != renderResolutionScale) {
auto renderConfig = _graphicsEngine.getRenderEngine()->getConfiguration();
assert(renderConfig);
auto mainView = renderConfig->getConfig("RenderMainView.RenderDeferredTask");
// mainView can be null if we're rendering in forward mode
if (mainView) {
mainView->setProperty("resolutionScale", renderResolutionScale);
}
displayPlugin->setRenderResolutionScale(renderResolutionScale);
}
// FIXME the aspect ratio for stereo displays is incorrect based on this.
float aspectRatio = displayPlugin->getRecommendedAspectRatio();
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio,
@ -5611,7 +5667,7 @@ void Application::resumeAfterLoginDialogActionTaken() {
scriptEngines->reloadLocalFiles();
// if the --scripts command-line argument was used.
if (!_defaultScriptsLocation.exists() && (arguments().indexOf(QString("--").append(SCRIPTS_SWITCH))) != -1) {
if (_defaultScriptsLocation.exists() && (arguments().indexOf(QString("--").append(SCRIPTS_SWITCH))) != -1) {
scriptEngines->loadDefaultScripts();
scriptEngines->defaultScriptsLocationOverridden(true);
} else {
@ -5908,10 +5964,8 @@ void Application::resetPhysicsReadyInformation() {
_gpuTextureMemSizeStabilityCount = 0;
_gpuTextureMemSizeAtLastCheck = 0;
_physicsEnabled = false;
_octreeProcessor.startEntitySequence();
}
void Application::reloadResourceCaches() {
resetPhysicsReadyInformation();
@ -5932,7 +5986,7 @@ void Application::reloadResourceCaches() {
DependencyManager::get<ResourceCacheSharedItems>()->clear();
DependencyManager::get<AnimationCache>()->refreshAll();
DependencyManager::get<SoundCache>()->refreshAll();
MaterialCache::instance().refreshAll();
DependencyManager::get<MaterialCache>()->refreshAll();
DependencyManager::get<ModelCache>()->refreshAll();
ShaderCache::instance().refreshAll();
DependencyManager::get<TextureCache>()->refreshAll();
@ -6158,6 +6212,24 @@ void Application::updateSecondaryCameraViewFrustum() {
static bool domainLoadingInProgress = false;
void Application::tryToEnablePhysics() {
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
if (gpuTextureMemSizeStable() || !enableInterstitial) {
_fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter;
_lastQueriedViews.clear(); // Force new view.
// process octree stats packets are sent in between full sends of a scene (this isn't currently true).
// We keep physics disabled until we've received a full scene and everything near the avatar in that
// scene is ready to compute its collision shape.
if (getMyAvatar()->isReadyForPhysics()) {
_physicsEnabled = true;
setIsInterstitialMode(false);
getMyAvatar()->updateMotionBehaviorFromMenu();
}
}
}
void Application::update(float deltaTime) {
PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_graphicsEngine._renderFrameCount + 1);
@ -6165,7 +6237,6 @@ void Application::update(float deltaTime) {
return;
}
if (!_physicsEnabled) {
if (!domainLoadingInProgress) {
PROFILE_ASYNC_BEGIN(app, "Scene Loading", "");
@ -6174,24 +6245,16 @@ void Application::update(float deltaTime) {
// we haven't yet enabled physics. we wait until we think we have all the collision information
// for nearby entities before starting bullet up.
quint64 now = usecTimestampNow();
if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) {
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
if (gpuTextureMemSizeStable() || !enableInterstitial) {
// we've received a new full-scene octree stats packet, or it's been long enough to try again anyway
_lastPhysicsCheckTime = now;
_fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter;
_lastQueriedViews.clear(); // Force new view.
// process octree stats packets are sent in between full sends of a scene (this isn't currently true).
// We keep physics disabled until we've received a full scene and everything near the avatar in that
// scene is ready to compute its collision shape.
if (getMyAvatar()->isReadyForPhysics()) {
_physicsEnabled = true;
setIsInterstitialMode(false);
getMyAvatar()->updateMotionBehaviorFromMenu();
}
if (isServerlessMode()) {
tryToEnablePhysics();
} else if (_failedToConnectToEntityServer) {
if (_octreeProcessor.safeLandingIsActive()) {
_octreeProcessor.stopSafeLanding();
}
} else {
_octreeProcessor.updateSafeLanding();
if (_octreeProcessor.safeLandingIsComplete()) {
tryToEnablePhysics();
}
}
} else if (domainLoadingInProgress) {
@ -6900,7 +6963,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType) {
bool interstitialModeEnabled = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
ConicalViewFrustum sphericalView;
sphericalView.setSimpleRadius(INITIAL_QUERY_RADIUS);
AABox box = getMyAvatar()->getGlobalBoundingBox();
float radius = glm::max(INITIAL_QUERY_RADIUS, 0.5f * glm::length(box.getDimensions()));
sphericalView.setPositionAndSimpleRadius(box.calcCenter(), radius);
if (interstitialModeEnabled) {
ConicalViewFrustum farView;
@ -7107,7 +7172,7 @@ void Application::clearDomainOctreeDetails(bool clearAll) {
DependencyManager::get<AnimationCache>()->clearUnusedResources();
DependencyManager::get<SoundCache>()->clearUnusedResources();
MaterialCache::instance().clearUnusedResources();
DependencyManager::get<MaterialCache>()->clearUnusedResources();
DependencyManager::get<ModelCache>()->clearUnusedResources();
ShaderCache::instance().clearUnusedResources();
DependencyManager::get<TextureCache>()->clearUnusedResources();
@ -7140,13 +7205,17 @@ void Application::resettingDomain() {
clearDomainOctreeDetails(false);
}
void Application::nodeAdded(SharedNodePointer node) const {
void Application::nodeAdded(SharedNodePointer node) {
if (node->getType() == NodeType::EntityServer) {
if (!_failedToConnectToEntityServer) {
if (_failedToConnectToEntityServer && !_entityServerConnectionTimer.isActive()) {
_failedToConnectToEntityServer = false;
_octreeProcessor.stopSafeLanding();
_octreeProcessor.startSafeLanding();
} else if (_entityServerConnectionTimer.isActive()) {
_entityServerConnectionTimer.stop();
_entityServerConnectionTimer.setInterval(ENTITY_SERVER_CONNECTION_TIMEOUT);
_entityServerConnectionTimer.start();
}
_entityServerConnectionTimer.setInterval(ENTITY_SERVER_CONNECTION_TIMEOUT);
_entityServerConnectionTimer.start();
}
}
@ -7156,7 +7225,6 @@ void Application::nodeActivated(SharedNodePointer node) {
#if !defined(DISABLE_QML)
auto offscreenUi = getOffscreenUI();
if (offscreenUi) {
auto nodeList = DependencyManager::get<NodeList>();
@ -8532,23 +8600,7 @@ void Application::shareSnapshot(const QString& path, const QUrl& href) {
}
float Application::getRenderResolutionScale() const {
auto menu = Menu::getInstance();
if (!menu) {
return 1.0f;
}
if (menu->isOptionChecked(MenuOption::RenderResolutionOne)) {
return 1.0f;
} else if (menu->isOptionChecked(MenuOption::RenderResolutionTwoThird)) {
return 0.666f;
} else if (menu->isOptionChecked(MenuOption::RenderResolutionHalf)) {
return 0.5f;
} else if (menu->isOptionChecked(MenuOption::RenderResolutionThird)) {
return 0.333f;
} else if (menu->isOptionChecked(MenuOption::RenderResolutionQuarter)) {
return 0.25f;
} else {
return 1.0f;
}
return RenderScriptingInterface::getInstance()->getViewportResolutionScale();
}
void Application::notifyPacketVersionMismatch() {

View file

@ -512,7 +512,7 @@ private slots:
void loadSettings();
void saveSettings() const;
void setFailedToConnectToEntityServer() { _failedToConnectToEntityServer = true; }
void setFailedToConnectToEntityServer();
bool acceptSnapshot(const QString& urlString);
bool askToSetAvatarUrl(const QString& url);
@ -527,7 +527,7 @@ private slots:
void domainURLChanged(QUrl domainURL);
void updateWindowTitle() const;
void nodeAdded(SharedNodePointer node) const;
void nodeAdded(SharedNodePointer node);
void nodeActivated(SharedNodePointer node);
void nodeKilled(SharedNodePointer node);
static void packetSent(quint64 length);
@ -564,6 +564,7 @@ private:
void cleanupBeforeQuit();
void idle();
void tryToEnablePhysics();
void update(float deltaTime);
// Various helper functions called during update()
@ -786,8 +787,6 @@ private:
qint64 _gpuTextureMemSizeStabilityCount { 0 };
qint64 _gpuTextureMemSizeAtLastCheck { 0 };
quint64 _lastPhysicsCheckTime { usecTimestampNow() }; // when did we last check to see if physics was ready
bool _keyboardDeviceHasFocus { true };
ConnectionMonitor _connectionMonitor;

View file

@ -28,6 +28,7 @@ public:
Bookmarks();
virtual void setupMenus(Menu* menubar, MenuWrapper* menu) = 0;
void insert(const QString& name, const QVariant& address); // Overwrites any existing entry with same name.
QString addressForBookmark(const QString& name) const;
protected:
@ -37,7 +38,6 @@ protected:
virtual void addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) = 0;
void enableMenuItems(bool enabled);
virtual void readFromFile();
void insert(const QString& name, const QVariant& address); // Overwrites any existing entry with same name.
void sortActions(Menu* menubar, MenuWrapper* menu);
int getMenuItemLocation(QList<QAction*> actions, const QString& name) const;
void removeBookmarkFromMenu(Menu* menubar, const QString& name);

View file

@ -351,7 +351,18 @@ float LODManager::getHMDLODTargetFPS() const {
}
float LODManager::getLODTargetFPS() const {
auto refreshRateFPS = qApp->getRefreshRateManager().getActiveRefreshRate();
// Use the current refresh rate as the recommended rate target used to cap the LOD manager control value.
// When focused, Use the Focus Inactive as the targget LOD to void abrupt changes from the lod controller.
auto& refreshRateManager = qApp->getRefreshRateManager();
auto refreshRateRegime = refreshRateManager.getRefreshRateRegime();
auto refreshRateProfile = refreshRateManager.getRefreshRateProfile();
auto refreshRateUXMode = refreshRateManager.getUXMode();
auto refreshRateFPS = refreshRateManager.getActiveRefreshRate();
if (refreshRateRegime == RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE) {
refreshRateFPS = refreshRateManager.queryRefreshRateTarget(refreshRateProfile, RefreshRateManager::RefreshRateRegime::FOCUS_INACTIVE, refreshRateUXMode);
}
auto lodTargetFPS = getDesktopLODTargetFPS();
if (qApp->isHMDMode()) {
lodTargetFPS = getHMDLODTargetFPS();

View file

@ -67,6 +67,10 @@ QString LocationBookmarks::getHomeLocationAddress() {
return addressForBookmark(HOME_BOOKMARK);
}
QString LocationBookmarks::getAddress(const QString& bookmarkName) {
return addressForBookmark(bookmarkName);
}
void LocationBookmarks::teleportToBookmark() {
QAction* action = qobject_cast<QAction*>(sender());
QString address = action->data().toString();

View file

@ -34,6 +34,13 @@ public:
void setupMenus(Menu* menubar, MenuWrapper* menu) override;
static const QString HOME_BOOKMARK;
/**jsdoc
* @function LocationBookmarks.getAddress
* @param {string} bookmarkName Name of the bookmark to get the address for.
* @returns {string} The url for the specified bookmark. If the bookmark does not exist, the empty string will be returned.
*/
Q_INVOKABLE QString getAddress(const QString& bookmarkName);
public slots:
/**jsdoc
@ -48,7 +55,7 @@ public slots:
void setHomeLocationToAddress(const QVariant& address);
/**jsdoc
* @function LocationBookmarksgetHomeLocationAddress
* @function LocationBookmarks.getHomeLocationAddress
* @returns {string} The url for the home location bookmark
*/
QString getHomeLocationAddress();

View file

@ -382,28 +382,6 @@ Menu::Menu() {
// Developer > Render > OpenVR threaded submit
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::OpenVrThreadedSubmit, 0, true);
// Developer > Render > Resolution
MenuWrapper* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution);
QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu);
resolutionGroup->setExclusive(true);
#if defined(Q_OS_MAC)
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionOne, 0, false));
#else
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionOne, 0, true));
#endif
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionTwoThird, 0, false));
#if defined(Q_OS_MAC)
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionHalf, 0, true));
#else
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionHalf, 0, false));
#endif
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionThird, 0, false));
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionQuarter, 0, false));
//const QString = "Automatic Texture Memory";
//const QString = "64 MB";
//const QString = "256 MB";

View file

@ -168,12 +168,6 @@ namespace MenuOption {
const QString RenderMaxTexture4096MB = "4096 MB";
const QString RenderMaxTexture6144MB = "6144 MB";
const QString RenderMaxTexture8192MB = "8192 MB";
const QString RenderResolution = "Scale Resolution";
const QString RenderResolutionOne = "1";
const QString RenderResolutionTwoThird = "2/3";
const QString RenderResolutionHalf = "1/2";
const QString RenderResolutionThird = "1/3";
const QString RenderResolutionQuarter = "1/4";
const QString RenderSensorToWorldMatrix = "Show SensorToWorld Matrix";
const QString RenderIKTargets = "Show IK Targets";
const QString RenderIKConstraints = "Show IK Constraints";

View file

@ -13,6 +13,7 @@
#include <platform/Profiler.h>
#include "scripting/RenderScriptingInterface.h"
#include "LODManager.h"
PerformanceManager::PerformanceManager()
{
@ -62,17 +63,29 @@ PerformanceManager::PerformancePreset PerformanceManager::getPerformancePreset()
void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformancePreset preset) {
// Ugly case that prevent us to run deferred everywhere...
bool isDeferredCapable = platform::Profiler::isRenderMethodDeferredCapable();
switch (preset) {
case PerformancePreset::HIGH:
RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::DEFERRED);
RenderScriptingInterface::getInstance()->setRenderMethod( ( isDeferredCapable ?
RenderScriptingInterface::RenderMethod::DEFERRED :
RenderScriptingInterface::RenderMethod::FORWARD ) );
RenderScriptingInterface::getInstance()->setShadowsEnabled(true);
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::REALTIME);
DependencyManager::get<LODManager>()->setWorldDetailQuality(0.5f);
break;
case PerformancePreset::MID:
RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::DEFERRED);
RenderScriptingInterface::getInstance()->setRenderMethod((isDeferredCapable ?
RenderScriptingInterface::RenderMethod::DEFERRED :
RenderScriptingInterface::RenderMethod::FORWARD));
RenderScriptingInterface::getInstance()->setShadowsEnabled(false);
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::INTERACTIVE);
DependencyManager::get<LODManager>()->setWorldDetailQuality(0.5f);
break;
case PerformancePreset::LOW:
@ -80,6 +93,8 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP
RenderScriptingInterface::getInstance()->setShadowsEnabled(false);
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::ECO);
DependencyManager::get<LODManager>()->setWorldDetailQuality(0.75f);
break;
case PerformancePreset::UNKNOWN:
default:

View file

@ -107,9 +107,7 @@ RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile
RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME;
if (getUXMode() != RefreshRateManager::UXMode::VR) {
profile =(RefreshRateManager::RefreshRateProfile) _refreshRateProfileSettingLock.resultWithReadLock<int>([&] {
return _refreshRateProfileSetting.get();
});
return _refreshRateProfile;
}
return profile;
@ -138,15 +136,17 @@ void RefreshRateManager::setUXMode(RefreshRateManager::UXMode uxMode) {
}
}
int RefreshRateManager::queryRefreshRateTarget(RefreshRateProfile profile, RefreshRateRegime regime, UXMode uxMode) const {
int targetRefreshRate = VR_TARGET_RATE;
if (uxMode == RefreshRateManager::UXMode::DESKTOP) {
targetRefreshRate = REFRESH_RATE_PROFILES[profile][regime];
}
return targetRefreshRate;
}
void RefreshRateManager::updateRefreshRateController() const {
if (_refreshRateOperator) {
int targetRefreshRate;
if (_uxMode == RefreshRateManager::UXMode::DESKTOP) {
targetRefreshRate = REFRESH_RATE_PROFILES[_refreshRateProfile][_refreshRateRegime];
} else {
targetRefreshRate = VR_TARGET_RATE;
}
int targetRefreshRate = queryRefreshRateTarget(_refreshRateProfile, _refreshRateRegime, _uxMode);
_refreshRateOperator(targetRefreshRate);
_activeRefreshRate = targetRefreshRate;
}

View file

@ -65,6 +65,9 @@ public:
int getActiveRefreshRate() const { return _activeRefreshRate; }
void updateRefreshRateController() const;
// query the refresh rate target at the specified combination
int queryRefreshRateTarget(RefreshRateProfile profile, RefreshRateRegime regime, UXMode uxMode) const;
void resetInactiveTimer();
void toggleInactive();

View file

@ -19,13 +19,15 @@
* The <code>"far-grab"</code> {@link Entities.ActionType|ActionType} moves and rotates an entity to a target position and
* orientation, optionally relative to another entity. Collisions between the entity and the user's avatar are disabled during
* the far-grab.
* It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}.
* It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}:
*
* @typedef {object} Entities.ActionArguments-FarGrab
* @property {Uuid} otherID=null - If an entity ID, the <code>targetPosition</code> and <code>targetRotation</code> are
* relative to the entity's position and rotation.
* @property {Uuid} otherJointIndex=null - If a joint index in the <code>otherID</code> entity, the <code>targetPosition</code>
* and <code>targetRotation</code> are relative to the entity joint's position and rotation.
* @property {Vec3} targetPosition=0,0,0 - The target position.
* @property {Quat} targetRotation=0,0,0,1 - The target rotation.
* @property {Uuid} otherID=null - If an entity ID, the <code>targetPosition</code> and <code>targetRotation</code> are
* relative to this entity's position and rotation.
* @property {number} linearTimeScale=3.4e+38 - Controls how long it takes for the entity's position to catch up with the
* target position. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the action
* is applied using an exponential decay.
@ -33,6 +35,7 @@
* target orientation. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the
* action is applied using an exponential decay.
*/
// The properties are per ObjectActionTractor.
class AvatarActionFarGrab : public ObjectActionTractor {
public:
AvatarActionFarGrab(const QUuid& id, EntityItemPointer ownerEntity);

View file

@ -447,22 +447,24 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) {
/**jsdoc
* The <code>"hold"</code> {@link Entities.ActionType|ActionType} positions and rotates an entity relative to an avatar's hand.
* Collisions between the entity and the user's avatar are disabled during the hold.
* It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}.
* It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}:
*
* @typedef {object} Entities.ActionArguments-Hold
* @property {Uuid} holderID=MyAvatar.sessionUUID - The ID of the avatar holding the entity.
* @property {string} hand=right - The hand holding the entity: <code>"left"</code> or <code>"right"</code>.
* @property {Vec3} relativePosition=0,0,0 - The target position relative to the avatar's hand.
* @property {Vec3} relativeRotation=0,0,0,1 - The target rotation relative to the avatar's hand.
* @property {number} timeScale=3.4e+38 - Controls how long it takes for the entity's position and rotation to catch up with
* the target. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the action is
* applied using an exponential decay.
* @property {string} hand=right - The hand holding the entity: <code>"left"</code> or <code>"right"</code>.
* @property {boolean} kinematic=false - If <code>true</code>, the entity is made kinematic during the action; the entity won't
* lag behind the hand but constraint actions such as <code>"hinge"</code> won't act properly.
* @property {boolean} kinematicSetVelocity=false - If <code>true</code> and <code>kinematic</code> is <code>true</code>, the
* entity's <code>velocity</code> property will be set during the action, e.g., so that other scripts may use the value.
* @property {boolean} ignoreIK=false - If <code>true</code>, the entity follows the HMD controller rather than the avatar's
* hand.
* @property {boolean} kinematic=false - <code>true</code> if the entity is made kinematic during the action; the entity won't
* lag behind the hand but constraint actions such as <code>"hinge"</code> won't act properly. <code>false</code> if the
* entity is not made kinematic during the action
* @property {boolean} kinematicSetVelocity=false - <code>true</code> if, when <code>kinematic</code> is <code>true</code>, the
* entity's velocity will be set during the action, e.g., so that other scripts may use the value. <code>false</code> if
* the entity's velocity will not be set during the action.
* @property {boolean} ignoreIK=false - <code>true</code> if the entity follows the HMD controller, <code>false</code> if it
* follows the avatar's hand.
*/
QVariantMap AvatarActionHold::getArguments() {
QVariantMap arguments = ObjectDynamic::getArguments();

View file

@ -435,7 +435,7 @@ DetailedMotionState* AvatarManager::createDetailedMotionState(OtherAvatarPointer
return nullptr;
}
void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar) {
void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) {
if (!avatar->_motionState) {
avatar->_motionState = new AvatarMotionState(avatar, nullptr);
}
@ -452,20 +452,24 @@ void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction
transaction.objectsToAdd.push_back(motionState);
}
motionState->clearIncomingDirtyFlags();
}
// Rather than reconcile numbers of joints after change to model or LOD
// we blow away old detailedMotionStates and create anew all around.
void AvatarManager::removeDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) {
// delete old detailedMotionStates
auto& detailedMotionStates = avatar->getDetailedMotionStates();
if (detailedMotionStates.size() != 0) {
for (auto& detailedMotionState : detailedMotionStates) {
transaction.objectsToRemove.push_back(detailedMotionState);
}
avatar->resetDetailedMotionStates();
avatar->forgetDetailedMotionStates();
}
}
// build new detailedMotionStates
void AvatarManager::rebuildDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) {
// Rather than reconcile numbers of joints after change to model or LOD
// we blow away old detailedMotionStates and create anew all around.
removeDetailedAvatarPhysics(transaction, avatar);
auto& detailedMotionStates = avatar->getDetailedMotionStates();
OtherAvatar::BodyLOD lod = avatar->getBodyLOD();
if (lod == OtherAvatar::BodyLOD::Sphere) {
auto dMotionState = createDetailedMotionState(avatar, -1);
@ -483,7 +487,7 @@ void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction
}
}
}
avatar->_needsReinsertion = false;
avatar->_needsDetailedRebuild = false;
}
void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) {
@ -494,13 +498,10 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
if (isInPhysics) {
transaction.objectsToRemove.push_back(avatar->_motionState);
avatar->_motionState = nullptr;
auto& detailedMotionStates = avatar->getDetailedMotionStates();
for (auto& motionState : detailedMotionStates) {
transaction.objectsToRemove.push_back(motionState);
}
avatar->resetDetailedMotionStates();
removeDetailedAvatarPhysics(transaction, avatar);
} else {
rebuildAvatarPhysics(transaction, avatar);
rebuildDetailedAvatarPhysics(transaction, avatar);
}
} else if (isInPhysics) {
AvatarMotionState* motionState = avatar->_motionState;
@ -519,6 +520,10 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
}
motionState->clearIncomingDirtyFlags();
}
if (avatar->_needsDetailedRebuild) {
rebuildDetailedAvatarPhysics(transaction, avatar);
}
}
}
_otherAvatarsToChangeInPhysics.clear();

View file

@ -274,7 +274,9 @@ public slots:
protected:
AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) override;
DetailedMotionState* createDetailedMotionState(OtherAvatarPointer avatar, int32_t jointIndex);
void rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar);
void rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar);
void removeDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar);
void rebuildDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar);
private:
explicit AvatarManager(QObject* parent = 0);

View file

@ -1416,6 +1416,10 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
}
}
void MyAvatar::setDebugDrawAnimPoseName(QString poseName) {
_debugDrawAnimPoseName.set(poseName);
}
void MyAvatar::setEnableDebugDrawPosition(bool isEnabled) {
if (isEnabled) {
const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
@ -2488,12 +2492,12 @@ QVariantList MyAvatar::getAvatarEntitiesVariant() {
QVariantMap avatarEntityData;
avatarEntityData["id"] = entityID;
EntityItemProperties entityProperties = entity->getProperties(desiredProperties);
QScriptValue scriptProperties;
{
std::lock_guard<std::mutex> guard(_scriptEngineLock);
QScriptValue scriptProperties;
scriptProperties = EntityItemPropertiesToScriptValue(_scriptEngine, entityProperties);
avatarEntityData["properties"] = scriptProperties.toVariant();
}
avatarEntityData["properties"] = scriptProperties.toVariant();
avatarEntitiesData.append(QVariant(avatarEntityData));
}
}
@ -3086,15 +3090,26 @@ void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) {
}
if (_enableDebugDrawAnimPose && animSkeleton) {
// build absolute AnimPoseVec from rig
AnimPoseVec absPoses;
const Rig& rig = _skeletonModel->getRig();
absPoses.reserve(rig.getJointStateCount());
for (int i = 0; i < rig.getJointStateCount(); i++) {
absPoses.push_back(AnimPose(rig.getJointTransform(i)));
const glm::vec4 CYAN(0.1f, 0.6f, 0.6f, 1.0f);
QString name = _debugDrawAnimPoseName.get();
if (name.isEmpty()) {
// build absolute AnimPoseVec from rig transforms. i.e. the same that are used for rendering.
absPoses.reserve(rig.getJointStateCount());
for (int i = 0; i < rig.getJointStateCount(); i++) {
absPoses.push_back(AnimPose(rig.getJointTransform(i)));
}
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, CYAN);
} else {
AnimNode::ConstPointer node = rig.findAnimNodeByName(name);
if (node) {
rig.buildAbsoluteRigPoses(node->getPoses(), absPoses);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, CYAN);
}
}
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, cyan);
}
}
@ -6085,6 +6100,30 @@ QVariantList MyAvatar::getCollidingFlowJoints() {
return result;
}
int MyAvatar::getOverrideJointCount() const {
if (_skeletonModel) {
return _skeletonModel->getRig().getOverrideJointCount();
} else {
return 0;
}
}
bool MyAvatar::getFlowActive() const {
if (_skeletonModel) {
return _skeletonModel->getRig().getFlowActive();
} else {
return false;
}
}
bool MyAvatar::getNetworkGraphActive() const {
if (_skeletonModel) {
return _skeletonModel->getRig().getNetworkGraphActive();
} else {
return false;
}
}
void MyAvatar::initFlowFromFST() {
if (_skeletonModel->isLoaded()) {
auto &flowData = _skeletonModel->getHFMModel().flowData;

View file

@ -39,6 +39,23 @@ class ModelItemID;
class MyHead;
class DetailedMotionState;
/**jsdoc
* <p>Locomotion control types.</p>
* <table>
* <thead>
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
* </thead>
* <tbody>
* <tr><td><code>0</code></td><td>Default</td><td>Your walking speed is constant; it doesn't change depending on how far
* forward you push your controller's joystick. Fully pushing your joystick forward makes your avatar run.</td></tr>
* <tr><td><code>1</code></td><td>Analog</td><td>Your walking speed changes in steps based on how far forward you push your
* controller's joystick. Fully pushing your joystick forward makes your avatar run.</td></tr>
* <tr><td><code>2</code></td><td>AnalogPlus</td><td>Your walking speed changes proportionally to how far forward you push
* your controller's joystick. Fully pushing your joystick forward makes your avatar run.</td></tr>
* </tbody>
* </table>
* @typedef {number} MyAvatar.LocomotionControlsMode
*/
enum LocomotionControlsMode {
CONTROLS_DEFAULT = 0,
CONTROLS_ANALOG,
@ -128,6 +145,8 @@ class MyAvatar : public Avatar {
* avatar. <em>Read-only.</em>
* @property {number} sensorToWorldScale - The scale that transforms dimensions in the user's real world to the avatar's
* size in the virtual world. <em>Read-only.</em>
* @property {boolean} hasPriority - <code>true</code> if the avatar is in a "hero" zone, <code>false</code> if it isn't.
* <em>Read-only.</em>
*
* @comment IMPORTANT: This group of properties is copied from Avatar.h; they should NOT be edited here.
* @property {Vec3} skeletonOffset - Can be used to apply a translation offset between the avatar's position and the
@ -239,9 +258,16 @@ class MyAvatar : public Avatar {
* where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain). Note: Likely to be deprecated.
* <em>Read-only.</em>
*
* @property {number} walkSpeed - The walk speed of your avatar.
* @property {number} walkBackwardSpeed - The walk backward speed of your avatar.
* @property {number} sprintSpeed - The sprint speed of your avatar.
* @property {number} walkSpeed - The walk speed of your avatar for the current control scheme (see
* {@link MyAvatar.getControlScheme|getControlScheme}).
* @property {number} walkBackwardSpeed - The walk backward speed of your avatar for the current control scheme (see
* {@link MyAvatar.getControlScheme|getControlScheme}).
* @property {number} sprintSpeed - The sprint (run) speed of your avatar for the current control scheme (see
* {@link MyAvatar.getControlScheme|getControlScheme}).
* @property {number} analogPlusWalkSpeed - The walk speed of your avatar for the "AnalogPlus" control scheme.
* <p><strong>Warning:</strong> Setting this value also sets the value of <code>analogPlusSprintSpeed</code> to twice
* the value.</p>
* @property {number} analogPlusSprintSpeed - The sprint (run) speed of your avatar for the "AnalogPlus" control scheme.
* @property {MyAvatar.SitStandModelType} userRecenterModel - Controls avatar leaning and recentering behavior.
* @property {number} isInSittingState - <code>true</code> if your avatar is sitting (avatar leaning is disabled,
* recenntering is enabled), <code>false</code> if it is standing (avatar leaning is enabled, and avatar recenters if it
@ -281,6 +307,7 @@ class MyAvatar : public Avatar {
* @borrows Avatar.updateAvatarEntity as updateAvatarEntity
* @borrows Avatar.clearAvatarEntity as clearAvatarEntity
* @borrows Avatar.setForceFaceTrackerConnected as setForceFaceTrackerConnected
* @borrows Avatar.setSkeletonModelURL as setSkeletonModelURL
* @borrows Avatar.getAttachmentData as getAttachmentData
* @borrows Avatar.setAttachmentData as setAttachmentData
* @borrows Avatar.attach as attach
@ -308,7 +335,6 @@ class MyAvatar : public Avatar {
* @comment Avatar.setAbsoluteJointTranslationInObjectFrame as setAbsoluteJointTranslationInObjectFrame - Don't borrow because implementation is different.
* @borrows Avatar.getTargetScale as getTargetScale
* @borrows Avatar.resetLastSent as resetLastSent
* @borrows Avatar.hasPriority as hasPriority
*/
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
Q_PROPERTY(QVector3D qmlPosition READ getQmlPosition)
@ -583,14 +609,13 @@ public:
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
* <a href="https://docs.highfidelity.com/create/avatars/avatar-standards">Avatar Standards</a>.</p>
* @function MyAvatar.overrideAnimation
* @param url {string} The URL to the animation file. Animation files need to be FBX format, but only need to contain the
* @param {string} url - The URL to the animation file. Animation files need to be FBX format, but only need to contain the
* avatar skeleton and animation data.
* @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param loop {boolean} Set to true if the animation should loop.
* @param firstFrame {number} The frame the animation should start at.
* @param lastFrame {number} The frame the animation should end at.
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
* @param {number} firstFrame - The frame to start the animation at.
* @param {number} lastFrame - The frame to end the animation at.
* @example <caption> Play a clapping animation on your avatar for three seconds. </caption>
* // Clap your hands for 3 seconds then restore animation back to the avatar.
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
@ -601,18 +626,18 @@ public:
Q_INVOKABLE void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
/**jsdoc
* <code>overrideHandAnimation()</code> Gets the overrides the default hand poses that are triggered with controller buttons.
* use {@link MyAvatar.restoreHandAnimation}.</p> to restore the default poses.
* Overrides the default hand poses that are triggered with controller buttons.
* Use {@link MyAvatar.restoreHandAnimation} to restore the default poses.
* @function MyAvatar.overrideHandAnimation
* @param isLeft {boolean} Set true if using the left hand
* @param url {string} The URL to the animation file. Animation files need to be FBX format, but only need to contain the
* @param isLeft {boolean} <code>true</code> to override the left hand, <code>false</code> to override the right hand.
* @param {string} url - The URL of the animation file. Animation files need to be FBX format, but only need to contain the
* avatar skeleton and animation data.
* @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param loop {boolean} Set to true if the animation should loop.
* @param firstFrame {number} The frame the animation should start at.
* @param lastFrame {number} The frame the animation should end at
* @example <caption> Override left hand animation for three seconds. </caption>
* // Override the left hand pose then restore the default pose.
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
* @param {number} firstFrame - The frame to start the animation at.
* @param {number} lastFrame - The frame to end the animation at.
* @example <caption> Override left hand animation for three seconds.</caption>
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
* MyAvatar.restoreHandAnimation();
@ -629,7 +654,6 @@ public:
* animation, this function has no effect.</p>
* @function MyAvatar.restoreAnimation
* @example <caption> Play a clapping animation on your avatar for three seconds. </caption>
* // Clap your hands for 3 seconds then restore animation back to the avatar.
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
@ -639,16 +663,15 @@ public:
Q_INVOKABLE void restoreAnimation();
/**jsdoc
* Restores the default hand animation state machine that is driven by the state machine in the avatar-animation json.
* Restores the default hand animation state machine that is driven by the state machine in the avatar-animation JSON.
* <p>The avatar animation system includes a set of default animations along with rules for how those animations are blended
* together with procedural data (such as look at vectors, hand sensors etc.). Playing your own custom animations will
* override the default animations. <code>restoreHandAnimation()</code> is used to restore the default hand poses
* If you aren't currently playing an override hand
* animation, this function has no effect.</p>
* override the default animations. <code>restoreHandAnimation()</code> is used to restore the default hand poses.
* If you aren't currently playing an override hand animation, this function has no effect.</p>
* @function MyAvatar.restoreHandAnimation
* @param isLeft {boolean} Set to true if using the left hand
* @example <caption> Override left hand animation for three seconds. </caption>
* // Override the left hand pose then restore the default pose.
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
* MyAvatar.restoreHandAnimation();
@ -689,12 +712,13 @@ public:
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
* <a href="https://docs.highfidelity.com/create/avatars/avatar-standards">Avatar Standards</a>.
* @function MyAvatar.overrideRoleAnimation
* @param role {string} The animation role to override
* @param url {string} The URL to the animation file. Animation files need to be in FBX format, but only need to contain the avatar skeleton and animation data.
* @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param loop {boolean} Set to true if the animation should loop
* @param firstFrame {number} The frame the animation should start at
* @param lastFrame {number} The frame the animation should end at
* @param {string} role - The animation role to override
* @param {string} url - The URL to the animation file. Animation files need to be in FBX format, but only need to contain
* the avatar skeleton and animation data.
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
* @param {number} firstFrame - The frame the animation should start at.
* @param {number} lastFrame - The frame the animation should end at.
* @example <caption>The default avatar-animation.json defines an "idleStand" animation role. This role specifies that when the avatar is not moving,
* an animation clip of the avatar idling with hands hanging at its side will be used. It also specifies that when the avatar moves, the animation
* will smoothly blend to the walking animation used by the "walkFwd" animation role.
@ -782,33 +806,42 @@ public:
* mode.
*/
Q_INVOKABLE bool getSnapTurn() const { return _useSnapTurn; }
/**jsdoc
* Sets whether your should do snap turns or smooth turns in HMD mode.
* Sets whether you do snap turns or smooth turns in HMD mode.
* @function MyAvatar.setSnapTurn
* @param {boolean} on - <code>true</code> to do snap turns in HMD mode; <code>false</code> to do smooth turns in HMD mode.
*/
Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; }
/**
/**jsdoc
* Gets the control scheme that is in use.
* @function MyAvatar.getControlScheme
* @returns {number}
*/
* @returns {MyAvatar.LocomotionControlsMode} The control scheme that is in use.
*/
Q_INVOKABLE int getControlScheme() const { return _controlSchemeIndex; }
/**
/**jsdoc
* Sets the control scheme to use.
* @function MyAvatar.setControlScheme
* @param {number} index
*/
* @param {MyAvatar.LocomotionControlsMode} controlScheme - The control scheme to use.
*/
Q_INVOKABLE void setControlScheme(int index) { _controlSchemeIndex = (index >= 0 && index <= 2) ? index : 0; }
/**jsdoc
* Gets whether your avatar hovers when its feet are not on the ground.
* @function MyAvatar.hoverWhenUnsupported
* @returns {boolean}
* @returns {boolean} <code>true</code> if your avatar hovers when its feet are not on the ground, <code>false</code> if it
* falls.
*/
// FIXME: Should be named, getHoverWhenUnsupported().
Q_INVOKABLE bool hoverWhenUnsupported() const { return _hoverWhenUnsupported; }
/**jsdoc
* Sets whether your avatar hovers when its feet are not on the ground.
* @function MyAvatar.setHoverWhenUnsupported
* @param {boolean} on
* @param {boolean} hover - <code>true</code> if your avatar hovers when its feet are not on the ground, <code>false</code>
* if it falls.
*/
Q_INVOKABLE void setHoverWhenUnsupported(bool on) { _hoverWhenUnsupported = on; }
@ -826,26 +859,31 @@ public:
* @returns {string} <code>"left"</code> for the left hand, <code>"right"</code> for the right hand.
*/
Q_INVOKABLE QString getDominantHand() const;
/**jsdoc
* @function MyAVatar.setStrafeEnabled
* @param {bool} enabled
*/
* Sets whether strafing is enabled.
* @function MyAvatar.setStrafeEnabled
* @param {boolean} enabled - <code>true</code> if strafing is enabled, <code>false</code> if it isn't.
*/
Q_INVOKABLE void setStrafeEnabled(bool enabled);
/**jsdoc
* @function MyAvatar.getStrafeEnabled
* @returns {bool}
*/
* Gets whether strafing is enabled.
* @function MyAvatar.getStrafeEnabled
* @returns {boolean} <code>true</code> if strafing is enabled, <code>false</code> if it isn't.
*/
Q_INVOKABLE bool getStrafeEnabled() const;
/**jsdoc
* Sets the HMD alignment relative to your avatar.
* @function MyAvatar.setHmdAvatarAlignmentType
* @param {string} type - <code>"head"</code> to align your head and your avatar's head, <code>"eyes"</code> to align your
* eyes and your avatar's eyes.
*
*/
Q_INVOKABLE void setHmdAvatarAlignmentType(const QString& type);
/**jsdoc
* Gets the HMD alignment for your avatar.
* Gets the HMD alignment relative to your avatar.
* @function MyAvatar.getHmdAvatarAlignmentType
* @returns {string} <code>"head"</code> if aligning your head and your avatar's head, <code>"eyes"</code> if aligning your
* eyes and your avatar's eyes.
@ -1495,18 +1533,8 @@ public:
*/
Q_INVOKABLE float getDriveGear5();
/**jsdoc
* Choose the control scheme.
* @function MyAvatar.setControlSchemeIndex
* @param {number} Choose the control scheme to be used.
*/
void setControlSchemeIndex(int index);
/**jsdoc
* Check what control scheme is in use.
* @function MyAvatar.getControlSchemeIndex
* @returns {number} Returns the index associated with a given control scheme.
*/
int getControlSchemeIndex();
/**jsdoc
@ -1584,8 +1612,8 @@ public:
Q_INVOKABLE bool getCharacterControllerEnabled(); // deprecated
/**jsdoc
* @comment Different behavior to the Avatar version of this method.
* Gets the rotation of a joint relative to the avatar.
* @comment Different behavior to the Avatar version of this method.
* @function MyAvatar.getAbsoluteJointRotationInObjectFrame
* @param {number} index - The index of the joint.
* @returns {Quat} The rotation of the joint relative to the avatar.
@ -1597,8 +1625,8 @@ public:
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
/**jsdoc
* @comment Different behavior to the Avatar version of this method.
* Gets the translation of a joint relative to the avatar.
* @comment Different behavior to the Avatar version of this method.
* @function MyAvatar.getAbsoluteJointTranslationInObjectFrame
* @param {number} index - The index of the joint.
* @returns {Vec3} The translation of the joint relative to the avatar.
@ -1807,6 +1835,10 @@ public:
*/
Q_INVOKABLE QVariantList getCollidingFlowJoints();
int getOverrideJointCount() const;
bool getFlowActive() const;
bool getNetworkGraphActive() const;
public slots:
/**jsdoc
@ -1990,12 +2022,20 @@ public slots:
void setEnableDebugDrawDefaultPose(bool isEnabled);
/**jsdoc
* Displays animation debug graphics.
* Displays animation debug graphics. By default it shows the animation poses used for rendering.
* However, the property MyAvatar.setDebugDrawAnimPoseName can be used to draw a specific animation node.
* @function MyAvatar.setEnableDebugDrawAnimPose
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/
void setEnableDebugDrawAnimPose(bool isEnabled);
/**jsdoc
* If set it determines which animation debug graphics to draw, when MyAvatar.setEnableDebugDrawAnimPose is set to true.
* @function MyAvatar.setDebugDrawAnimPoseName
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/
void setDebugDrawAnimPoseName(QString poseName);
/**jsdoc
* Displays position debug graphics.
* @function MyAvatar.setEnableDebugDrawPosition
@ -2162,33 +2202,35 @@ signals:
void audioListenerModeChanged();
/**jsdoc
* Notifies when the analogPlusWalkSpeed value is changed.
* Triggered when the walk speed set for the "AnalogPlus" control scheme changes.
* @function MyAvatar.analogPlusWalkSpeedChanged
* @param {float} value - the new avatar walk speed
* @param {number} speed - The new walk speed set for the "AnalogPlus" control scheme.
* @returns {Signal}
*/
void analogPlusWalkSpeedChanged(float value);
/**jsdoc
* Notifies when the analogPlusSprintSpeed value is changed.
* Triggered when the sprint (run) speed set for the "AnalogPlus" control scheme changes.
* @function MyAvatar.analogPlusSprintSpeedChanged
* @param {float} value - the new avatar sprint speed
* @param {number} speed - The new sprint speed set for the "AnalogPlus" control scheme.
* @returns {Signal}
*/
void analogPlusSprintSpeedChanged(float value);
/**jsdoc
* Notifies when the sprintSpeed value is changed.
* Triggered when the sprint (run) speed set for the current control scheme (see
* {@link MyAvatar.getControlScheme|getControlScheme}) changes.
* @function MyAvatar.sprintSpeedChanged
* @param {float} value - the new avatar sprint speed
* @param {number} speed -The new sprint speed set for the current control scheme.
* @returns {Signal}
*/
void sprintSpeedChanged(float value);
/**jsdoc
* Notifies when the walkBackwardSpeed value is changed.
* Triggered when the walk backward speed set for the current control scheme (see
* {@link MyAvatar.getControlScheme|getControlScheme}) changes.
* @function MyAvatar.walkBackwardSpeedChanged
* @param {float} value - the new avatar walk backward speed
* @param {number} speed - The new walk backward speed set for the current control scheme.
* @returns {Signal}
*/
void walkBackwardSpeedChanged(float value);
@ -2441,6 +2483,9 @@ private:
void updateEyeContactTarget(float deltaTime);
// These are made private for MyAvatar so that you will use the "use" methods instead
/**jsdoc
* @comment Borrows the base class's JSDoc.
*/
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
virtual void updatePalms() override {}
@ -2635,6 +2680,8 @@ private:
bool _enableDebugDrawIKChains { false };
bool _enableDebugDrawDetailedCollision { false };
ThreadSafeValueCache<QString> _debugDrawAnimPoseName;
mutable bool _cauterizationNeedsUpdate { false }; // do we need to scan children and update their "cauterized" state?
AudioListenerMode _audioListenerMode;

View file

@ -398,15 +398,13 @@ DetailedMotionState* MyCharacterController::createDetailedMotionStateForJoint(in
}
void MyCharacterController::clearDetailedMotionStates() {
// we don't actually clear the MotionStates here
// instead we twiddle some flags as a signal of what to do later
_pendingFlags |= PENDING_FLAG_REMOVE_DETAILED_FROM_SIMULATION;
// We make sure we don't add them again
_pendingFlags &= ~PENDING_FLAG_ADD_DETAILED_TO_SIMULATION;
}
void MyCharacterController::resetDetailedMotionStates() {
_detailedMotionStates.clear();
}
void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) {
for (size_t i = 0; i < _detailedMotionStates.size(); i++) {
_detailedMotionStates[i]->forceActive();
@ -416,6 +414,8 @@ void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction&
for (size_t i = 0; i < _detailedMotionStates.size(); i++) {
transaction.objectsToRemove.push_back(_detailedMotionStates[i]);
}
// NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove
// See AvatarManager::handleProcessedPhysicsTransaction()
_detailedMotionStates.clear();
}
if (_pendingFlags & PENDING_FLAG_ADD_DETAILED_TO_SIMULATION) {

View file

@ -48,7 +48,6 @@ public:
DetailedMotionState* createDetailedMotionStateForJoint(int32_t jointIndex);
std::vector<DetailedMotionState*>& getDetailedMotionStates() { return _detailedMotionStates; }
void clearDetailedMotionStates();
void resetDetailedMotionStates();
void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction);

View file

@ -177,7 +177,7 @@ const btCollisionShape* OtherAvatar::createCollisionShape(int32_t jointIndex, bo
return ObjectMotionState::getShapeManager()->getShape(shapeInfo);
}
void OtherAvatar::resetDetailedMotionStates() {
void OtherAvatar::forgetDetailedMotionStates() {
// NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove
// See AvatarManager::handleProcessedPhysicsTransaction()
_detailedMotionStates.clear();
@ -209,7 +209,7 @@ void OtherAvatar::computeShapeLOD() {
if (newLOD != _bodyLOD) {
_bodyLOD = newLOD;
if (isInPhysicsSimulation()) {
_needsReinsertion = true;
_needsDetailedRebuild = true;
}
}
}
@ -224,14 +224,14 @@ bool OtherAvatar::shouldBeInPhysicsSimulation() const {
bool OtherAvatar::needsPhysicsUpdate() const {
constexpr uint32_t FLAGS_OF_INTEREST = Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS | Simulation::DIRTY_POSITION | Simulation::DIRTY_COLLISION_GROUP;
return (_needsReinsertion || (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST)));
return (_needsDetailedRebuild || (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST)));
}
void OtherAvatar::rebuildCollisionShape() {
if (_motionState) {
// do not actually rebuild here, instead flag for later
_motionState->addDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
_needsReinsertion = true;
_needsDetailedRebuild = true;
}
}

View file

@ -54,7 +54,7 @@ public:
const btCollisionShape* createCollisionShape(int32_t jointIndex, bool& isBound, std::vector<int32_t>& boundJoints);
std::vector<DetailedMotionState*>& getDetailedMotionStates() { return _detailedMotionStates; }
void resetDetailedMotionStates();
void forgetDetailedMotionStates();
BodyLOD getBodyLOD() { return _bodyLOD; }
void computeShapeLOD();
@ -90,7 +90,7 @@ protected:
int32_t _spaceIndex { -1 };
uint8_t _workloadRegion { workload::Region::INVALID };
BodyLOD _bodyLOD { BodyLOD::Sphere };
bool _needsReinsertion { false };
bool _needsDetailedRebuild { false };
};
using OtherAvatarPointer = std::shared_ptr<OtherAvatar>;

View file

@ -132,6 +132,10 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI
bool GraphicsEngine::shouldPaint() const {
auto displayPlugin = qApp->getActiveDisplayPlugin();
if (!displayPlugin) {
// We're shutting down
return false;
}
#ifdef DEBUG_PAINT_DELAY
static uint64_t paintDelaySamples{ 0 };
@ -175,6 +179,10 @@ void GraphicsEngine::render_performFrame() {
{
PROFILE_RANGE(render, "/getActiveDisplayPlugin");
displayPlugin = qApp->getActiveDisplayPlugin();
if (!displayPlugin) {
// We're shutting down
return;
}
}
{

View file

@ -108,8 +108,8 @@ void WorldBoxRenderData::renderWorldBox(RenderArgs* args, gpu::Batch& batch) {
glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY,
geometryIds[17]);
geometryCache->renderWireCubeInstance(args, batch, GREY4);
auto pipeline = geometryCache->getShapePipelinePointer(false, false, args->_renderMethod == render::Args::RenderMethod::FORWARD);
geometryCache->renderWireCubeInstance(args, batch, GREY4, pipeline);
// Draw meter markers along the 3 axis to help with measuring things
const float MARKER_DISTANCE = 1.0f;
@ -117,22 +117,22 @@ void WorldBoxRenderData::renderWorldBox(RenderArgs* args, gpu::Batch& batch) {
transform = Transform().setScale(MARKER_RADIUS);
batch.setModelTransform(transform);
geometryCache->renderSolidSphereInstance(args, batch, RED);
geometryCache->renderSolidSphereInstance(args, batch, RED, pipeline);
transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS);
batch.setModelTransform(transform);
geometryCache->renderSolidSphereInstance(args, batch, RED);
geometryCache->renderSolidSphereInstance(args, batch, RED, pipeline);
transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS);
batch.setModelTransform(transform);
geometryCache->renderSolidSphereInstance(args, batch, GREEN);
geometryCache->renderSolidSphereInstance(args, batch, GREEN, pipeline);
transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS);
batch.setModelTransform(transform);
geometryCache->renderSolidSphereInstance(args, batch, BLUE);
geometryCache->renderSolidSphereInstance(args, batch, BLUE, pipeline);
transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS);
batch.setModelTransform(transform);
geometryCache->renderSolidSphereInstance(args, batch, GREY);
geometryCache->renderSolidSphereInstance(args, batch, GREY, pipeline);
}

View file

@ -85,6 +85,7 @@ int main(int argc, const char* argv[]) {
QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts <path>", "path");
QCommandLineOption responseTokensOption("tokens", "set response tokens <json>", "json");
QCommandLineOption displayNameOption("displayName", "set user display name <string>", "string");
QCommandLineOption setBookmarkOption("setBookmark", "set bookmark key=value pair", "string");
parser.addOption(urlOption);
parser.addOption(noLauncherOption);
@ -97,6 +98,7 @@ int main(int argc, const char* argv[]) {
parser.addOption(allowMultipleInstancesOption);
parser.addOption(responseTokensOption);
parser.addOption(displayNameOption);
parser.addOption(setBookmarkOption);
if (!parser.parse(arguments)) {
std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam

View file

@ -63,7 +63,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
// construct a new packet from the piggybacked one
auto buffer = std::unique_ptr<char[]>(new char[piggybackBytes]);
memcpy(buffer.get(), message->getRawMessage() + statsMessageLength, piggybackBytes);
auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, message->getSenderSockAddr());
message = QSharedPointer<ReceivedMessage>::create(*newPacket);
} else {
@ -80,7 +79,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
const QUuid& senderUUID = sendingNode->getUUID();
if (!versionDebugSuppressMap.contains(senderUUID, packetType)) {
qDebug() << "Was stats packet? " << wasStatsPacket;
qDebug() << "OctreePacketProcessor - piggyback packet version mismatch on" << packetType << "- Sender"
<< senderUUID << "sent" << (int) message->getVersion() << "but"
@ -115,7 +113,9 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
auto renderer = qApp->getEntities();
if (renderer) {
renderer->processDatagram(*message, sendingNode);
_safeLanding->noteReceivedsequenceNumber(renderer->getLastOctreeMessageSequence());
if (_safeLanding && _safeLanding->isTracking()) {
_safeLanding->addToSequence(renderer->getLastOctreeMessageSequence());
}
}
}
} break;
@ -124,7 +124,9 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
// Read sequence #
OCTREE_PACKET_SEQUENCE completionNumber;
message->readPrimitive(&completionNumber);
_safeLanding->setCompletionSequenceNumbers(0, completionNumber);
if (_safeLanding) {
_safeLanding->finishSequence(0, completionNumber);
}
} break;
default: {
@ -133,6 +135,31 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
}
}
void OctreePacketProcessor::startEntitySequence() {
_safeLanding->startEntitySequence(qApp->getEntities());
void OctreePacketProcessor::startSafeLanding() {
if (_safeLanding) {
_safeLanding->startTracking(qApp->getEntities());
}
}
void OctreePacketProcessor::updateSafeLanding() {
if (_safeLanding) {
_safeLanding->updateTracking();
}
}
void OctreePacketProcessor::stopSafeLanding() {
if (_safeLanding) {
_safeLanding->stopTracking();
}
}
bool OctreePacketProcessor::safeLandingIsActive() const {
return _safeLanding && _safeLanding->isTracking();
}
bool OctreePacketProcessor::safeLandingIsComplete() const {
if (_safeLanding) {
return _safeLanding->trackingIsComplete();
}
return false;
}

View file

@ -25,8 +25,12 @@ public:
OctreePacketProcessor();
~OctreePacketProcessor();
void startEntitySequence();
bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); }
void startSafeLanding();
void updateSafeLanding();
void stopSafeLanding();
bool safeLandingIsActive() const;
bool safeLandingIsComplete() const;
float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); }
signals:

View file

@ -19,6 +19,11 @@
const int SafeLanding::SEQUENCE_MODULO = std::numeric_limits<OCTREE_PACKET_SEQUENCE>::max() + 1;
CalculateEntityLoadingPriority SafeLanding::entityLoadingOperatorElevateCollidables = [](const EntityItem& entityItem) {
const int COLLIDABLE_ENTITY_PRIORITY = 10.0f;
return entityItem.getCollisionless() * COLLIDABLE_ENTITY_PRIORITY;
};
namespace {
template<typename T> bool lessThanWraparound(int a, int b) {
constexpr int MAX_T_VALUE = std::numeric_limits<T>::max();
@ -33,61 +38,46 @@ bool SafeLanding::SequenceLessThan::operator()(const int& a, const int& b) const
return lessThanWraparound<OCTREE_PACKET_SEQUENCE>(a, b);
}
void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityTreeRenderer) {
void SafeLanding::startTracking(QSharedPointer<EntityTreeRenderer> entityTreeRenderer) {
if (!entityTreeRenderer.isNull()) {
auto entityTree = entityTreeRenderer->getTree();
if (entityTree) {
if (entityTree && !_trackingEntities) {
Locker lock(_lock);
_entityTreeRenderer = entityTreeRenderer;
_trackedEntities.clear();
_trackingEntities = true;
_maxTrackedEntityCount = 0;
_initialStart = INVALID_SEQUENCE;
_initialEnd = INVALID_SEQUENCE;
_sequenceNumbers.clear();
_trackingEntities = true;
_startTime = usecTimestampNow();
connect(std::const_pointer_cast<EntityTree>(entityTree).get(),
&EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection);
connect(std::const_pointer_cast<EntityTree>(entityTree).get(),
&EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity);
_sequenceNumbers.clear();
_initialStart = INVALID_SEQUENCE;
_initialEnd = INVALID_SEQUENCE;
_startTime = usecTimestampNow();
EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority);
_prevEntityLoadingPriorityOperator = EntityTreeRenderer::getEntityLoadingPriorityOperator();
EntityTreeRenderer::setEntityLoadingPriorityFunction(entityLoadingOperatorElevateCollidables);
}
}
}
void SafeLanding::stopEntitySequence() {
Locker lock(_lock);
_trackingEntities = false;
_maxTrackedEntityCount = 0;
_trackedEntityStabilityCount = 0;
_initialStart = INVALID_SEQUENCE;
_initialEnd = INVALID_SEQUENCE;
_trackedEntities.clear();
_sequenceNumbers.clear();
}
void SafeLanding::addTrackedEntity(const EntityItemID& entityID) {
if (_trackingEntities) {
if (_trackingEntities && _entityTreeRenderer) {
Locker lock(_lock);
auto entityTree = _entityTreeRenderer->getTree();
if (entityTree) {
EntityItemPointer entity = entityTree->findEntityByID(entityID);
if (entity && !entity->isLocalEntity() && entity->getCreated() < _startTime) {
_trackedEntities.emplace(entityID, entity);
if (_entityTreeRenderer.isNull() || _entityTreeRenderer->getTree() == nullptr) {
return;
}
EntityItemPointer entity = _entityTreeRenderer->getTree()->findEntityByID(entityID);
if (entity && !entity->isLocalEntity() && entity->getCreated() < _startTime) {
_trackedEntities.emplace(entityID, entity);
int trackedEntityCount = (int)_trackedEntities.size();
if (trackedEntityCount > _maxTrackedEntityCount) {
_maxTrackedEntityCount = trackedEntityCount;
_trackedEntityStabilityCount = 0;
int trackedEntityCount = (int)_trackedEntities.size();
if (trackedEntityCount > _maxTrackedEntityCount) {
_maxTrackedEntityCount = trackedEntityCount;
_trackedEntityStabilityCount = 0;
}
}
//qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
}
}
}
@ -97,32 +87,92 @@ void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) {
_trackedEntities.erase(entityID);
}
void SafeLanding::setCompletionSequenceNumbers(int first, int last) {
void SafeLanding::finishSequence(int first, int last) {
Locker lock(_lock);
if (_initialStart == INVALID_SEQUENCE) {
if (_trackingEntities) {
_initialStart = first;
_initialEnd = last;
}
}
void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) {
if (_trackingEntities) {
void SafeLanding::addToSequence(int sequenceNumber) {
Locker lock(_lock);
_sequenceNumbers.insert(sequenceNumber);
}
void SafeLanding::updateTracking() {
if (!_trackingEntities || !_entityTreeRenderer) {
return;
}
{
Locker lock(_lock);
_sequenceNumbers.insert(sequenceNumber);
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
auto entityMapIter = _trackedEntities.begin();
while (entityMapIter != _trackedEntities.end()) {
auto entity = entityMapIter->second;
bool isVisuallyReady = true;
if (enableInterstitial) {
auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first);
if (!entityRenderable) {
_entityTreeRenderer->addingEntity(entityMapIter->first);
}
isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete());
}
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
entityMapIter = _trackedEntities.erase(entityMapIter);
} else {
if (!isVisuallyReady) {
entity->requestRenderUpdate();
}
entityMapIter++;
}
}
if (enableInterstitial) {
_trackedEntityStabilityCount++;
}
}
if (_trackedEntities.empty()) {
// no more tracked entities --> check sequenceNumbers
if (_initialStart != INVALID_SEQUENCE) {
bool shouldStop = false;
{
Locker lock(_lock);
int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart:
_initialEnd + SEQUENCE_MODULO - _initialStart;
auto startIter = _sequenceNumbers.find(_initialStart);
auto endIter = _sequenceNumbers.find(_initialEnd - 1);
bool missingSequenceNumbers = qApp->isMissingSequenceNumbers();
shouldStop = (sequenceSize == 0 ||
(startIter != _sequenceNumbers.end() &&
endIter != _sequenceNumbers.end() &&
((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers)));
}
if (shouldStop) {
stopTracking();
}
}
}
}
bool SafeLanding::isLoadSequenceComplete() {
if ((isEntityLoadingComplete() && isSequenceNumbersComplete()) || qApp->failedToConnectToEntityServer()) {
Locker lock(_lock);
_initialStart = INVALID_SEQUENCE;
_initialEnd = INVALID_SEQUENCE;
_entityTreeRenderer.clear();
_trackingEntities = false; // Don't track anything else that comes in.
EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority);
void SafeLanding::stopTracking() {
Locker lock(_lock);
_trackingEntities = false;
if (_entityTreeRenderer) {
auto entityTree = _entityTreeRenderer->getTree();
disconnect(std::const_pointer_cast<EntityTree>(entityTree).get(),
&EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity);
disconnect(std::const_pointer_cast<EntityTree>(entityTree).get(),
&EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity);
_entityTreeRenderer.reset();
}
EntityTreeRenderer::setEntityLoadingPriorityFunction(_prevEntityLoadingPriorityOperator);
}
return !_trackingEntities;
bool SafeLanding::trackingIsComplete() const {
return !_trackingEntities && (_initialStart != INVALID_SEQUENCE);
}
float SafeLanding::loadingProgressPercentage() {
@ -141,29 +191,6 @@ float SafeLanding::loadingProgressPercentage() {
return entityReadyPercentage;
}
bool SafeLanding::isSequenceNumbersComplete() {
if (_initialStart != INVALID_SEQUENCE) {
Locker lock(_lock);
int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart:
_initialEnd + SEQUENCE_MODULO - _initialStart;
auto startIter = _sequenceNumbers.find(_initialStart);
auto endIter = _sequenceNumbers.find(_initialEnd - 1);
bool missingSequenceNumbers = qApp->isMissingSequenceNumbers();
if (sequenceSize == 0 ||
(startIter != _sequenceNumbers.end()
&& endIter != _sequenceNumbers.end()
&& ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) {
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
if (!enableInterstitial) {
_trackingEntities = false; // Don't track anything else that comes in.
}
return true;
}
}
return false;
}
bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) {
if (entity && !entity->getCollisionless()) {
const auto& entityType = entity->getType();
@ -181,56 +208,9 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) {
}
}
}
return true;
}
bool SafeLanding::isEntityLoadingComplete() {
Locker lock(_lock);
auto entityTree = qApp->getEntities();
auto entityMapIter = _trackedEntities.begin();
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
while (entityMapIter != _trackedEntities.end()) {
auto entity = entityMapIter->second;
bool isVisuallyReady = true;
if (enableInterstitial) {
auto entityRenderable = entityTree->renderableForEntityId(entityMapIter->first);
if (!entityRenderable) {
entityTree->addingEntity(entityMapIter->first);
}
isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete());
}
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
entityMapIter = _trackedEntities.erase(entityMapIter);
} else {
if (!isVisuallyReady) {
entity->requestRenderUpdate();
}
entityMapIter++;
}
}
if (enableInterstitial) {
_trackedEntityStabilityCount++;
}
return _trackedEntities.empty();
}
float SafeLanding::ElevatedPriority(const EntityItem& entityItem) {
return entityItem.getCollisionless() ? 0.0f : 10.0f;
}
void SafeLanding::debugDumpSequenceIDs() const {
int p = -1;
qCDebug(interfaceapp) << "Sequence set size:" << _sequenceNumbers.size();

Some files were not shown because too many files have changed in this diff Show more