Merge pull request #5 from kasenvr/master

Upgrading to last master branch
This commit is contained in:
Alezia Kurdis 2020-09-17 19:38:24 -04:00 committed by GitHub
commit f8cbf74b37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 256 additions and 72 deletions

View file

@ -80,6 +80,13 @@ Where /path/to/directory is the path to a directory where you wish the build fil
// The type of release. // The type of release.
RELEASE_TYPE=PRODUCTION|PR|DEV RELEASE_TYPE=PRODUCTION|PR|DEV
// The Interface will have a custom default home and startup location.
INITIAL_STARTUP_LOCATION=Location/IP/URL
// Code-signing environment variables must be set during runtime of CMake AND globally when the signing takes place.
HF_PFX_FILE=Path to certificate
HF_PFX_PASSPHRASE=Passphrase for certificate
// Determine the build type // Determine the build type
PRODUCTION_BUILD=0|1 PRODUCTION_BUILD=0|1
PR_BUILD=0|1 PR_BUILD=0|1

View file

@ -1,5 +1,7 @@
# Creating an Installer # Creating an Installer
*Last Updated on August 24, 2020*
Follow the [build guide](BUILD.md) to figure out how to build Vircadia for your platform. Follow the [build guide](BUILD.md) to figure out how to build Vircadia for your platform.
During generation, CMake should produce an `install` target and a `package` target. During generation, CMake should produce an `install` target and a `package` target.
@ -13,6 +15,8 @@ To produce an installer, run the `package` target. However you will want to foll
#### Windows #### Windows
##### Prerequisites
To produce an executable installer on Windows, the following are required: To produce an executable installer on Windows, the following are required:
1. [7-zip](<https://www.7-zip.org/download.html>) 1. [7-zip](<https://www.7-zip.org/download.html>)
@ -59,6 +63,12 @@ To produce an executable installer on Windows, the following are required:
1. [Node.JS and NPM](<https://www.npmjs.com/get-npm>) 1. [Node.JS and NPM](<https://www.npmjs.com/get-npm>)
1. Install version 10.15.0 LTS 1. Install version 10.15.0 LTS
##### Code Signing (optional)
For code signing to work, you will need to set the `HF_PFX_FILE` and `HF_PFX_PASSPHRASE` environment variables to be present during CMake runtime and globally as we proceed to package the installer.
##### Creating the Installer
1. Perform a clean cmake from a new terminal. 1. Perform a clean cmake from a new terminal.
1. Open the `vircadia.sln` solution with elevated (administrator) permissions on Visual Studio and select the **Release** configuration. 1. Open the `vircadia.sln` solution with elevated (administrator) permissions on Visual Studio and select the **Release** configuration.
1. Build the solution. 1. Build the solution.

View file

@ -183,7 +183,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
} }
QString assignmentServerHostname; QString assignmentServerHostname;
if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION)) {
assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString(); assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString();
} }
if (parser.isSet(assignmentServerHostnameOption)) { if (parser.isSet(assignmentServerHostnameOption)) {
@ -192,7 +192,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
// check for an overriden assignment server port // check for an overriden assignment server port
quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT; quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT;
if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) {
assignmentServerPort = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toUInt(); assignmentServerPort = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toUInt();
} }

View file

@ -23,6 +23,7 @@ macro(SET_PACKAGING_PARAMETERS)
set_from_env(RELEASE_TYPE RELEASE_TYPE "DEV") set_from_env(RELEASE_TYPE RELEASE_TYPE "DEV")
set_from_env(RELEASE_NUMBER RELEASE_NUMBER "") set_from_env(RELEASE_NUMBER RELEASE_NUMBER "")
set_from_env(STABLE_BUILD STABLE_BUILD 0) set_from_env(STABLE_BUILD STABLE_BUILD 0)
set_from_env(INITIAL_STARTUP_LOCATION INITIAL_STARTUP_LOCATION "")
message(STATUS "The RELEASE_TYPE variable is: ${RELEASE_TYPE}") message(STATUS "The RELEASE_TYPE variable is: ${RELEASE_TYPE}")

View file

@ -22,11 +22,12 @@ namespace BuildInfo {
const QString DOMAIN_SERVER_NAME = "domain-server"; const QString DOMAIN_SERVER_NAME = "domain-server";
const QString AC_CLIENT_SERVER_NAME = "ac-client"; const QString AC_CLIENT_SERVER_NAME = "ac-client";
const QString MODIFIED_ORGANIZATION = "@BUILD_ORGANIZATION@"; const QString MODIFIED_ORGANIZATION = "@BUILD_ORGANIZATION@";
const QString ORGANIZATION_DOMAIN = "highfidelity.io"; const QString ORGANIZATION_DOMAIN = "vircadia.com";
const QString VERSION = "@BUILD_VERSION@"; const QString VERSION = "@BUILD_VERSION@";
const QString BUILD_NUMBER = "@BUILD_NUMBER@"; const QString BUILD_NUMBER = "@BUILD_NUMBER@";
const QString BUILD_GLOBAL_SERVICES = "@BUILD_GLOBAL_SERVICES@"; const QString BUILD_GLOBAL_SERVICES = "@BUILD_GLOBAL_SERVICES@";
const QString BUILD_TIME = "@BUILD_TIME@"; const QString BUILD_TIME = "@BUILD_TIME@";
const QString INITIAL_STARTUP_LOCATION = "@INITIAL_STARTUP_LOCATION@";
enum BuildType { enum BuildType {
Dev, Dev,

View file

@ -49,6 +49,12 @@ ScrollingWindow {
desktop.setAutoAdd(auto); desktop.setAutoAdd(auto);
} }
function openExternalBrowser() {
Qt.openUrlExternally(addressBar.text);
root.shown = false;
root.windowClosed();
}
Item { Item {
id:item id:item
width: pane.contentWidth width: pane.contentWidth
@ -58,34 +64,49 @@ ScrollingWindow {
id: buttons id: buttons
spacing: 4 spacing: 4
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 8 anchors.topMargin: 4
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 8 anchors.leftMargin: 8
HiFiGlyphs { HiFiGlyphs {
id: back; id: back
enabled: webview.canGoBack; enabled: webview.canGoBack
text: hifi.glyphs.backward text: hifi.glyphs.backward
color: enabled ? hifi.colors.text : hifi.colors.disabledText color: enabled ? (backMouseArea.containsMouse ? hifi.colors.blueHighlight : hifi.colors.faintGray) : hifi.colors.lightGray
size: 48 size: 48
MouseArea { anchors.fill: parent; onClicked: webview.goBack() } MouseArea {
id: backMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: webview.goBack();
}
} }
HiFiGlyphs { HiFiGlyphs {
id: forward; id: forward
enabled: webview.canGoForward; enabled: webview.canGoForward
text: hifi.glyphs.forward text: hifi.glyphs.forward
color: enabled ? hifi.colors.text : hifi.colors.disabledText color: enabled ? (forwardMouseArea.containsMouse ? hifi.colors.blueHighlight : hifi.colors.faintGray) : hifi.colors.lightGray
size: 48 size: 48
MouseArea { anchors.fill: parent; onClicked: webview.goForward() } MouseArea {
id: forwardMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: webview.goForward();
}
} }
HiFiGlyphs { HiFiGlyphs {
id: reload; id: reload
enabled: webview.canGoForward; enabled: url !== ""
text: webview.loading ? hifi.glyphs.close : hifi.glyphs.reload text: webview.loading ? hifi.glyphs.close : hifi.glyphs.reload
color: enabled ? hifi.colors.text : hifi.colors.disabledText color: enabled ? (reloadMouseArea.containsMouse ? hifi.colors.blueHighlight : hifi.colors.faintGray) : hifi.colors.lightGray
size: 48 size: 48
MouseArea { anchors.fill: parent; onClicked: webview.goForward() } MouseArea {
id: reloadMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: webview.loading ? webview.stop() : webview.reload();
}
} }
} }
@ -94,52 +115,82 @@ ScrollingWindow {
id: border id: border
height: 48 height: 48
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 8 anchors.topMargin: 4
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 8 anchors.rightMargin: 8
anchors.left: buttons.right anchors.left: buttons.right
anchors.leftMargin: 8 anchors.leftMargin: 8
HiFiGlyphs {
id: externalBrowser
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 4
enabled: !HMD.active && url !== ""
font.family: "FontAwesome"
text: "\uf24d"
rotation: -90
color: enabled ? (externalBrowserMouseArea.containsMouse ? hifi.colors.blueHighlight : hifi.colors.faintGray) : hifi.colors.lightGray
size: 32
MouseArea {
id: externalBrowserMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: openExternalBrowser();
}
}
Item { Item {
id: barIcon id: barIcon
width: parent.height width: parent.height
height: parent.height height: parent.height
Image { Image {
source: webview.icon; source: webview.loading ? "" : webview.icon
x: (parent.height - height) / 2 x: (parent.height - height) / 2
y: (parent.width - width) / 2 y: (parent.width - width) / 2
sourceSize: Qt.size(width, height); width: 28
verticalAlignment: Image.AlignVCenter; height: 28
verticalAlignment: Image.AlignVCenter
horizontalAlignment: Image.AlignHCenter horizontalAlignment: Image.AlignHCenter
} }
} }
TextField { TextField {
id: addressBar id: addressBar
anchors.right: parent.right anchors.right: externalBrowser.left
anchors.rightMargin: 8 anchors.rightMargin: 32
anchors.left: barIcon.right anchors.left: barIcon.right
anchors.leftMargin: 0 anchors.leftMargin: 0
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
focus: true focus: true
colorScheme: hifi.colorSchemes.dark colorScheme: hifi.colorSchemes.dark
placeholderText: "Enter URL" placeholderText: "Enter URL"
inputMethodHints: Qt.ImhUrlCharactersOnly
Component.onCompleted: ScriptDiscoveryService.scriptsModelFilter.filterRegExp = new RegExp("^.*$", "i") Component.onCompleted: ScriptDiscoveryService.scriptsModelFilter.filterRegExp = new RegExp("^.*$", "i")
Keys.onPressed: { Keys.onPressed: {
switch(event.key) { switch(event.key) {
case Qt.Key_Enter: case Qt.Key_Enter:
case Qt.Key_Return: case Qt.Key_Return:
event.accepted = true event.accepted = true
if (text.indexOf("http") != 0) { if (text.indexOf("http") !== 0) {
text = "http://" + text; text = "http://" + text;
} }
// Setting webiew.url directly doesn't add the URL to the navigation history.
//webview.url = text;
// The following works around this bug.
text = encodeURI(text);
text = text.replace(/;/g, "%3b"); // Prevent script injection.
text = text.replace(/'/g, "%25"); // ""
webview.runJavaScript("window.location='" + text + "'");
root.hidePermissionsBar(); root.hidePermissionsBar();
root.keyboardRaised = false; root.keyboardRaised = false;
webview.url = text;
break; break;
} }
} }
} }
} }
Rectangle { Rectangle {
@ -204,7 +255,7 @@ ScrollingWindow {
parentRoot: root parentRoot: root
anchors.top: buttons.bottom anchors.top: buttons.bottom
anchors.topMargin: 8 anchors.topMargin: 4
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -216,7 +267,7 @@ ScrollingWindow {
Keys.onPressed: { Keys.onPressed: {
switch(event.key) { switch(event.key) {
case Qt.Key_L: case Qt.Key_L:
if (event.modifiers == Qt.ControlModifier) { if (event.modifiers === Qt.ControlModifier) {
event.accepted = true event.accepted = true
addressBar.selectAll() addressBar.selectAll()
addressBar.forceActiveFocus() addressBar.forceActiveFocus()
@ -224,4 +275,5 @@ ScrollingWindow {
break; break;
} }
} }
} // dialog } // dialog

View file

@ -3976,6 +3976,11 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
// If this is a first run we short-circuit the address passed in // If this is a first run we short-circuit the address passed in
if (_firstRun.get()) { if (_firstRun.get()) {
if (!BuildInfo::INITIAL_STARTUP_LOCATION.isEmpty()) {
DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS);
Menu::getInstance()->triggerOption(MenuOption::HomeLocation);
}
if (!_overrideEntry) { if (!_overrideEntry) {
DependencyManager::get<AddressManager>()->goToEntry(); DependencyManager::get<AddressManager>()->goToEntry();
sentTo = SENT_TO_ENTRY; sentTo = SENT_TO_ENTRY;
@ -7105,9 +7110,9 @@ void Application::updateWindowTitle() const {
QString currentPlaceName; QString currentPlaceName;
if (isServerlessMode()) { if (isServerlessMode()) {
if (isInErrorState) { if (isInErrorState) {
currentPlaceName = "serverless: " + nodeList->getDomainHandler().getErrorDomainURL().toString(); currentPlaceName = "Serverless: " + nodeList->getDomainHandler().getErrorDomainURL().toString();
} else { } else {
currentPlaceName = "serverless: " + DependencyManager::get<AddressManager>()->getDomainURL().toString(); currentPlaceName = "Serverless: " + DependencyManager::get<AddressManager>()->getDomainURL().toString();
} }
} else { } else {
currentPlaceName = DependencyManager::get<AddressManager>()->getDomainURL().host(); currentPlaceName = DependencyManager::get<AddressManager>()->getDomainURL().host();

View file

@ -238,11 +238,11 @@ Menu::Menu() {
// Navigate > Start-up Location // Navigate > Start-up Location
MenuWrapper* startupLocationMenu = navigateMenu->addMenu(MenuOption::StartUpLocation); MenuWrapper* startupLocationMenu = navigateMenu->addMenu(MenuOption::StartUpLocation);
QActionGroup* startupLocatiopnGroup = new QActionGroup(startupLocationMenu); QActionGroup* startupLocationGroup = new QActionGroup(startupLocationMenu);
startupLocatiopnGroup->setExclusive(true); startupLocationGroup->setExclusive(true);
startupLocatiopnGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::HomeLocation, 0, startupLocationGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::HomeLocation, 0,
false)); false));
startupLocatiopnGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::LastLocation, 0, startupLocationGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::LastLocation, 0,
true)); true));
// Settings menu ---------------------------------- // Settings menu ----------------------------------

View file

@ -2072,7 +2072,6 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi
// NOTE: device start() uses the Qt internal device list // NOTE: device start() uses the Qt internal device list
Lock lock(_deviceMutex); Lock lock(_deviceMutex);
Lock localAudioLock(_localAudioMutex);
_localSamplesAvailable.exchange(0, std::memory_order_release); _localSamplesAvailable.exchange(0, std::memory_order_release);
//wait on local injectors prep to finish running //wait on local injectors prep to finish running
@ -2080,6 +2079,8 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi
_localPrepInjectorFuture.waitForFinished(); _localPrepInjectorFuture.waitForFinished();
} }
Lock localAudioLock(_localAudioMutex);
// cleanup any previously initialized device // cleanup any previously initialized device
if (_audioOutput) { if (_audioOutput) {
_audioOutputIODevice.close(); _audioOutputIODevice.close();

View file

@ -1460,6 +1460,31 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
emit requestRenderUpdate(); emit requestRenderUpdate();
} }
if (!_allProceduralMaterialsLoaded) {
std::lock_guard<std::mutex> lock(_materialsLock);
bool allProceduralMaterialsLoaded = true;
for (auto& shapeMaterialPair : _materials) {
auto material = shapeMaterialPair.second;
while (!material.empty()) {
auto mat = material.top();
if (mat.material && mat.material->isProcedural() && !mat.material->isReady()) {
allProceduralMaterialsLoaded = false;
break;
}
material.pop();
}
if (!allProceduralMaterialsLoaded) {
break;
}
}
if (!allProceduralMaterialsLoaded) {
emit requestRenderUpdate();
} else {
_allProceduralMaterialsLoaded = true;
model->setRenderItemsNeedUpdate();
}
}
// When the individual mesh parts of a model finish fading, they will mark their Model as needing updating // When the individual mesh parts of a model finish fading, they will mark their Model as needing updating
// we will watch for that and ask the model to update it's render items // we will watch for that and ask the model to update it's render items
if (model->getRenderItemsNeedUpdate()) { if (model->getRenderItemsNeedUpdate()) {
@ -1584,6 +1609,10 @@ void ModelEntityRenderer::addMaterial(graphics::MaterialLayer material, const st
if (_model && _model->fetchRenderItemIDs().size() > 0) { if (_model && _model->fetchRenderItemIDs().size() > 0) {
_model->addMaterial(material, parentMaterialName); _model->addMaterial(material, parentMaterialName);
} }
if (material.material && material.material->isProcedural()) {
_allProceduralMaterialsLoaded = false;
emit requestRenderUpdate();
}
} }
void ModelEntityRenderer::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) { void ModelEntityRenderer::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {

View file

@ -202,10 +202,10 @@ private:
bool _prevModelLoaded { false }; bool _prevModelLoaded { false };
void processMaterials(); void processMaterials();
bool _allProceduralMaterialsLoaded { false };
static void metaBlendshapeOperator(render::ItemID renderItemID, int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets, static void metaBlendshapeOperator(render::ItemID renderItemID, int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets,
const QVector<int>& blendedMeshSizes, const render::ItemIDs& subItemIDs); const QVector<int>& blendedMeshSizes, const render::ItemIDs& subItemIDs);
}; };
} } // namespace } } // namespace

View file

@ -32,7 +32,7 @@ bool ShapeEntityRenderer::needsRenderUpdate() const {
if (resultWithReadLock<bool>([&] { if (resultWithReadLock<bool>([&] {
auto mat = _materials.find("0"); auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() &&
mat->second.top().material->isEnabled()) { mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material); auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) { if (procedural->isFading()) {
return true; return true;
@ -88,7 +88,7 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
withReadLock([&] { withReadLock([&] {
auto mat = _materials.find("0"); auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && mat->second.top().material->isEnabled()) { if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material); auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) { if (procedural->isFading()) {
procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f); procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f);
@ -140,7 +140,7 @@ bool ShapeEntityRenderer::isTransparent() const {
auto mat = _materials.find("0"); auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material) { if (mat != _materials.end() && mat->second.top().material) {
if (mat->second.top().material->isProcedural() && mat->second.top().material->isEnabled()) { if (mat->second.top().material->isProcedural() && mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material); auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) { if (procedural->isFading()) {
return true; return true;

View file

@ -746,6 +746,10 @@ QString ModelEntityItem::getBlendshapeCoefficients() const {
} }
void ModelEntityItem::setBlendshapeCoefficients(const QString& blendshapeCoefficients) { void ModelEntityItem::setBlendshapeCoefficients(const QString& blendshapeCoefficients) {
if (blendshapeCoefficients.isEmpty()) {
return;
}
QJsonParseError error; QJsonParseError error;
QJsonDocument newCoefficientsJSON = QJsonDocument::fromJson(blendshapeCoefficients.toUtf8(), &error); QJsonDocument newCoefficientsJSON = QJsonDocument::fromJson(blendshapeCoefficients.toUtf8(), &error);
if (error.error != QJsonParseError::NoError) { if (error.error != QJsonParseError::NoError) {

View file

@ -1019,7 +1019,9 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
hfmModel.meshes.append(HFMMesh()); hfmModel.meshes.append(HFMMesh());
HFMMesh& mesh = hfmModel.meshes[hfmModel.meshes.size() - 1]; HFMMesh& mesh = hfmModel.meshes[hfmModel.meshes.size() - 1];
if (!hfmModel.hasSkeletonJoints) { mesh.modelTransform = globalTransforms[nodeIndex];
if (!hfmModel.hasSkeletonJoints) {
HFMCluster cluster; HFMCluster cluster;
cluster.jointIndex = nodecount; cluster.jointIndex = nodecount;
cluster.inverseBindMatrix = glm::mat4(); cluster.inverseBindMatrix = glm::mat4();

View file

@ -27,16 +27,22 @@
#include "NodeList.h" #include "NodeList.h"
#include "NetworkLogging.h" #include "NetworkLogging.h"
#include "NetworkingConstants.h"
#include "UserActivityLogger.h" #include "UserActivityLogger.h"
#include "udt/PacketHeaders.h" #include "udt/PacketHeaders.h"
const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json"; const QString REDIRECT_HIFI_ADDRESS = NetworkingConstants::REDIRECT_HIFI_ADDRESS;
const QString DEFAULT_HOME_ADDRESS = "file:///~/serverless/tutorial.json";
const QString REDIRECT_HIFI_ADDRESS = "file:///~/serverless/redirect.json";
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager"; const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address"; const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
Setting::Handle<QUrl> currentAddressHandle(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP << "address", DEFAULT_HIFI_ADDRESS); const QString DEFAULT_VIRCADIA_ADDRESS = (!BuildInfo::INITIAL_STARTUP_LOCATION.isEmpty())
? BuildInfo::INITIAL_STARTUP_LOCATION
: NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS;
const QString DEFAULT_HOME_ADDRESS = (!BuildInfo::INITIAL_STARTUP_LOCATION.isEmpty())
? BuildInfo::INITIAL_STARTUP_LOCATION
: NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS;
Setting::Handle<QUrl> currentAddressHandle(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP << "address", DEFAULT_VIRCADIA_ADDRESS);
bool AddressManager::isConnected() { bool AddressManager::isConnected() {
return DependencyManager::get<NodeList>()->getDomainHandler().isConnected(); return DependencyManager::get<NodeList>()->getDomainHandler().isConnected();

View file

@ -22,8 +22,8 @@
#include "AccountManager.h" #include "AccountManager.h"
extern const QString DEFAULT_HIFI_ADDRESS;
extern const QString REDIRECT_HIFI_ADDRESS; extern const QString REDIRECT_HIFI_ADDRESS;
extern const QString DEFAULT_VIRCADIA_ADDRESS;
extern const QString DEFAULT_HOME_ADDRESS; extern const QString DEFAULT_HOME_ADDRESS;
const QString SANDBOX_HIFI_ADDRESS = "hifi://localhost"; const QString SANDBOX_HIFI_ADDRESS = "hifi://localhost";
@ -292,7 +292,8 @@ public slots:
* location history is correctly maintained. * location history is correctly maintained.
*/ */
void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) { void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) {
handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger); } handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger);
}
/**jsdoc /**jsdoc
* Takes you to the default "welcome" metaverse address. * Takes you to the default "welcome" metaverse address.
@ -300,7 +301,9 @@ public slots:
* @param {location.LookupTrigger} trigger=StartupFromSettings - The reason for the function call. Helps ensure that user's * @param {location.LookupTrigger} trigger=StartupFromSettings - The reason for the function call. Helps ensure that user's
* location history is correctly maintained. * location history is correctly maintained.
*/ */
void goToEntry(LookupTrigger trigger = LookupTrigger::StartupFromSettings) { handleUrl(DEFAULT_HIFI_ADDRESS, trigger); } void goToEntry(LookupTrigger trigger = LookupTrigger::StartupFromSettings) {
handleUrl(DEFAULT_VIRCADIA_ADDRESS, trigger);
}
/**jsdoc /**jsdoc
* Takes you to the specified user's location. * Takes you to the specified user's location.

View file

@ -56,7 +56,10 @@ namespace NetworkingConstants {
const QUrl HELP_SCRIPTING_REFERENCE_URL{ "https://apidocs.vircadia.dev/" }; const QUrl HELP_SCRIPTING_REFERENCE_URL{ "https://apidocs.vircadia.dev/" };
const QUrl HELP_RELEASE_NOTES_URL{ "https://docs.vircadia.dev/release-notes.html" }; const QUrl HELP_RELEASE_NOTES_URL{ "https://docs.vircadia.dev/release-notes.html" };
const QUrl HELP_BUG_REPORT_URL{ "https://github.com/kasenvr/project-athena/issues" }; const QUrl HELP_BUG_REPORT_URL{ "https://github.com/kasenvr/project-athena/issues" };
const QString DEFAULT_VIRCADIA_ADDRESS = "file:///~/serverless/tutorial.json";
const QString DEFAULT_HOME_ADDRESS = "file:///~/serverless/tutorial.json";
const QString REDIRECT_HIFI_ADDRESS = "file:///~/serverless/redirect.json";
} }
const QString HIFI_URL_SCHEME_ABOUT = "about"; const QString HIFI_URL_SCHEME_ABOUT = "about";

View file

@ -520,8 +520,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
batch.setDrawcallUniform(drawcallInfo); batch.setDrawcallUniform(drawcallInfo);
} }
if (!_drawMaterials.empty() && _drawMaterials.top().material && _drawMaterials.top().material->isProcedural() && if (_shapeKey.hasOwnPipeline()) {
_drawMaterials.top().material->isReady()) {
if (!(enableMaterialProceduralShaders)) { if (!(enableMaterialProceduralShaders)) {
return; return;
} }

View file

@ -12,7 +12,9 @@
#include "ContextAwareProfile.h" #include "ContextAwareProfile.h"
#include <cassert> #include <cassert>
#include <QtCore/QReadLocker>
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtCore/QWriteLocker>
#include <QtQml/QQmlContext> #include <QtQml/QQmlContext>
#include <shared/QtHelpers.h> #include <shared/QtHelpers.h>
@ -20,20 +22,63 @@
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess"; static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : QReadWriteLock ContextAwareProfile::_contextMapProtect;
ContextAwareProfileParent(context), _context(context) { ContextAwareProfile::ContextMap ContextAwareProfile::_contextMap;
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : ContextAwareProfileParent(context), _context(context) {
assert(context); assert(context);
{ // register our object for future updates
QWriteLocker guard(&_contextMapProtect);
ContextMap::iterator setLookup = _contextMap.find(_context);
if (setLookup == _contextMap.end()) {
setLookup = _contextMap.insert(_context, ContextAwareProfileSet());
}
assert(setLookup != _contextMap.end());
ContextAwareProfileSet& profileSet = setLookup.value();
assert(profileSet.find(this) == profileSet.end());
profileSet.insert(this);
}
_isRestricted.store(isRestrictedGetProperty());
} }
ContextAwareProfile::~ContextAwareProfile() {
// deregister our object
QWriteLocker guard(&_contextMapProtect);
ContextMap::iterator setLookup = _contextMap.find(_context);
assert(setLookup != _contextMap.end());
if (setLookup != _contextMap.end()) {
ContextAwareProfileSet& profileSet = setLookup.value();
assert(profileSet.find(this) != profileSet.end());
profileSet.remove(this);
if (profileSet.isEmpty()) {
_contextMap.erase(setLookup);
}
}
}
void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) { void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) {
// set the QML property
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict); context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict);
// broadcast the new value to any registered ContextAwareProfile objects
QReadLocker guard(&_contextMapProtect);
ContextMap::const_iterator setLookup = _contextMap.find(context);
if (setLookup != _contextMap.end()) {
const ContextAwareProfileSet& profileSet = setLookup.value();
for (ContextAwareProfileSet::const_iterator profileIterator = profileSet.begin();
profileIterator != profileSet.end(); profileIterator++) {
(*profileIterator)->_isRestricted.store(restrict);
}
}
} }
bool ContextAwareProfile::isRestrictedInternal() { bool ContextAwareProfile::isRestrictedGetProperty() {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
bool restrictedResult = false; bool restrictedResult = false;
BLOCKING_INVOKE_METHOD(this, "isRestrictedInternal", Q_RETURN_ARG(bool, restrictedResult)); BLOCKING_INVOKE_METHOD(this, "isRestrictedGetProperty", Q_RETURN_ARG(bool, restrictedResult));
return restrictedResult; return restrictedResult;
} }
@ -48,10 +93,5 @@ bool ContextAwareProfile::isRestrictedInternal() {
} }
bool ContextAwareProfile::isRestricted() { bool ContextAwareProfile::isRestricted() {
auto now = usecTimestampNow(); return _isRestricted.load();
if (now > _cacheExpiry) {
_cachedValue = isRestrictedInternal();
_cacheExpiry = now + MAX_CACHE_AGE;
}
return _cachedValue;
} }

View file

@ -11,7 +11,11 @@
#ifndef hifi_ContextAwareProfile_h #ifndef hifi_ContextAwareProfile_h
#define hifi_ContextAwareProfile_h #define hifi_ContextAwareProfile_h
#include <QtCore/QtGlobal> #include <atomic>
#include <QtCore/QHash>
#include <QtCore/QReadWriteLock>
#include <QtCore/QSet>
#include <QtCore/QSharedPointer>
#if !defined(Q_OS_ANDROID) #if !defined(Q_OS_ANDROID)
#include <QtWebEngine/QQuickWebEngineProfile> #include <QtWebEngine/QQuickWebEngineProfile>
@ -26,8 +30,6 @@ using ContextAwareProfileParent = QObject;
using RequestInterceptorParent = QObject; using RequestInterceptorParent = QObject;
#endif #endif
#include <NumericalConstants.h>
class QQmlContext; class QQmlContext;
class ContextAwareProfile : public ContextAwareProfileParent { class ContextAwareProfile : public ContextAwareProfileParent {
@ -35,7 +37,7 @@ class ContextAwareProfile : public ContextAwareProfileParent {
public: public:
static void restrictContext(QQmlContext* context, bool restrict = true); static void restrictContext(QQmlContext* context, bool restrict = true);
bool isRestricted(); bool isRestricted();
Q_INVOKABLE bool isRestrictedInternal(); Q_INVOKABLE bool isRestrictedGetProperty();
protected: protected:
class RequestInterceptor : public RequestInterceptorParent { class RequestInterceptor : public RequestInterceptorParent {
@ -47,10 +49,17 @@ protected:
}; };
ContextAwareProfile(QQmlContext* parent); ContextAwareProfile(QQmlContext* parent);
~ContextAwareProfile();
private:
typedef QSet<ContextAwareProfile*> ContextAwareProfileSet;
typedef QHash<QQmlContext*, ContextAwareProfileSet> ContextMap;
QQmlContext* _context{ nullptr }; QQmlContext* _context{ nullptr };
bool _cachedValue{ false }; std::atomic<bool> _isRestricted{ false };
quint64 _cacheExpiry{ 0 };
constexpr static quint64 MAX_CACHE_AGE = MSECS_PER_SECOND; static QReadWriteLock _contextMapProtect;
static ContextMap _contextMap;
}; };
#endif // hifi_FileTypeProfile_h #endif // hifi_FileTypeProfile_h

View file

@ -8,7 +8,14 @@
if (NOT APPLE) if (NOT APPLE)
set(TARGET_NAME hifiSdl2) set(TARGET_NAME hifiSdl2)
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 10.0)
# GCC 10 and above sets -fno-common by default, and causes a linking problem here:
# multiple definition of `WAYLAND_wl_proxy_marshal'
#
# Work around it per https://medium.com/@clentfort/using-esy-sdl2-with-gcc-10-91b4fa0c5aa9
link_libraries("-Wl,--allow-multiple-definition")
endif()
setup_hifi_plugin(Qml) setup_hifi_plugin(Qml)
link_hifi_libraries(shared controllers ui plugins input-plugins script-engine) link_hifi_libraries(shared controllers ui plugins input-plugins script-engine)
target_sdl2() target_sdl2()
endif() endif()

View file

@ -402,7 +402,7 @@
"tooltip": "Affects the size of the spotlight beam; the higher the value, the larger the beam." "tooltip": "Affects the size of the spotlight beam; the higher the value, the larger the beam."
}, },
"materialURL": { "materialURL": {
"tooltip": "The URL to an external JSON file or \"materialData\", \"materialData?<material name> to use Material Data." "tooltip": "The URL to an external JSON file or \"materialData\". Append \"?<material name>\" to select a single material if multiple are defined."
}, },
"materialData": { "materialData": {
"tooltip": "Can be used instead of a JSON file when material set to materialData." "tooltip": "Can be used instead of a JSON file when material set to materialData."

View file

@ -736,6 +736,9 @@ var toolBar = (function () {
function handleNewMaterialDialogResult(result) { function handleNewMaterialDialogResult(result) {
if (result) { if (result) {
var materialURL = result.textInput; var materialURL = result.textInput;
if (materialURL === "") {
materialURL = "materialData";
}
//var materialMappingMode; //var materialMappingMode;
//switch (result.comboBox) { //switch (result.comboBox) {
// case MATERIAL_MODE_PROJECTED: // case MATERIAL_MODE_PROJECTED:
@ -2443,8 +2446,8 @@ var PropertiesTool = function (opts) {
Entities.editEntity(entityID, properties); Entities.editEntity(entityID, properties);
}); });
if (properties.name !== undefined || properties.modelURL !== undefined || properties.materialURL !== undefined || if (properties.name !== undefined || properties.modelURL !== undefined || properties.imageURL !== undefined ||
properties.visible !== undefined || properties.locked !== undefined) { properties.materialURL !== undefined || properties.visible !== undefined || properties.locked !== undefined) {
sendListUpdate = true; sendListUpdate = true;
} }

View file

@ -4,6 +4,7 @@
// //
// Created by Sam Gondelman on 1/17/18 // Created by Sam Gondelman on 1/17/18
// Copyright 2018 High Fidelity, Inc. // Copyright 2018 High Fidelity, Inc.
// Copyright 2020 Vircadia contributors
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -54,7 +55,7 @@ Rectangle {
Text { Text {
id: text1 id: text1
text: qsTr("Material URL") text: qsTr("Material URL (Optional)")
color: "#ffffff" color: "#ffffff"
font.pixelSize: 12 font.pixelSize: 12
} }
@ -139,7 +140,7 @@ Rectangle {
Button { Button {
id: button1 id: button1
text: qsTr("Add") text: qsTr("Create")
z: -1 z: -1
onClicked: { onClicked: {
newMaterialDialog.sendToScript({ newMaterialDialog.sendToScript({

View file

@ -4,6 +4,7 @@
// //
// Created by Seth Alves on 2017-2-10 // Created by Seth Alves on 2017-2-10
// Copyright 2017 High Fidelity, Inc. // Copyright 2017 High Fidelity, Inc.
// Copyright 2020 Vircadia contributors
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -208,7 +209,7 @@ Rectangle {
Button { Button {
id: button1 id: button1
text: qsTr("Add") text: qsTr("Create")
z: -1 z: -1
enabled: false enabled: false
onClicked: { onClicked: {