Merge remote-tracking branch 'upstream/master' into 21856-d

# Conflicts:
#	interface/src/LODManager.h
This commit is contained in:
David Rowe 2018-05-02 07:50:55 +12:00
commit 1aa28b7f54
25 changed files with 405 additions and 77 deletions

View file

@ -41,6 +41,9 @@ if (APPLE)
elseif (WIN32)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/quazip5.lib CACHE FILEPATH "Location of QuaZip release library")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/quazip5d.lib CACHE FILEPATH "Location of QuaZip release library")
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/libquazip5d.so CACHE FILEPATH "Location of QuaZip release library")
else ()
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")

View file

@ -254,7 +254,7 @@ ModalWindow {
text: root.warning;
wrapMode: Text.WordWrap;
font.italic: true;
maximumLineCount: 2;
maximumLineCount: 3;
}
HiFiGlyphs {

View file

@ -254,7 +254,7 @@ ModalWindow {
text: root.warning;
wrapMode: Text.WordWrap;
font.italic: true;
maximumLineCount: 2;
maximumLineCount: 3;
}
HiFiGlyphs {

View file

@ -282,7 +282,7 @@ TabletModalWindow {
text: root.warning;
wrapMode: Text.WordWrap;
font.italic: true;
maximumLineCount: 2;
maximumLineCount: 3;
}
HiFiGlyphs {

View file

@ -124,6 +124,14 @@ Rectangle {
root.numUpdatesAvailable = result.data.updates.length;
}
}
onAppInstalled: {
root.installedApps = Commerce.getInstalledApps();
}
onAppUninstalled: {
root.installedApps = Commerce.getInstalledApps();
}
}
Timer {
@ -249,6 +257,145 @@ Rectangle {
Commerce.getWalletStatus();
}
}
Item {
id: installedAppsContainer;
z: 998;
visible: false;
anchors.top: titleBarContainer.bottom;
anchors.topMargin: -titleBarContainer.additionalDropdownHeight;
anchors.left: parent.left;
anchors.bottom: parent.bottom;
width: parent.width;
RalewayRegular {
id: installedAppsHeader;
anchors.top: parent.top;
anchors.topMargin: 10;
anchors.left: parent.left;
anchors.leftMargin: 12;
height: 80;
width: paintedWidth;
text: "All Installed Marketplace Apps";
color: hifi.colors.black;
size: 22;
}
ListView {
id: installedAppsList;
clip: true;
model: installedAppsModel;
snapMode: ListView.SnapToItem;
// Anchors
anchors.top: installedAppsHeader.bottom;
anchors.left: parent.left;
anchors.bottom: sideloadAppButton.top;
width: parent.width;
delegate: Item {
width: parent.width;
height: 40;
RalewayRegular {
text: model.appUrl;
// Text size
size: 16;
// Anchors
anchors.left: parent.left;
anchors.leftMargin: 12;
height: parent.height;
anchors.right: sideloadAppOpenButton.left;
anchors.rightMargin: 8;
elide: Text.ElideRight;
// Style
color: hifi.colors.black;
// Alignment
verticalAlignment: Text.AlignVCenter;
MouseArea {
anchors.fill: parent;
onClicked: {
Window.copyToClipboard((model.appUrl).slice(0, -9));
}
}
}
HifiControlsUit.Button {
id: sideloadAppOpenButton;
text: "OPEN";
color: hifi.buttons.blue;
colorScheme: hifi.colorSchemes.dark;
anchors.top: parent.top;
anchors.topMargin: 2;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 2;
anchors.right: uninstallGlyph.left;
anchors.rightMargin: 8;
width: 80;
onClicked: {
Commerce.openApp(model.appUrl);
}
}
HiFiGlyphs {
id: uninstallGlyph;
text: hifi.glyphs.close;
color: hifi.colors.black;
size: 22;
anchors.top: parent.top;
anchors.right: parent.right;
anchors.rightMargin: 6;
width: 35;
height: parent.height;
horizontalAlignment: Text.AlignHCenter;
MouseArea {
anchors.fill: parent;
hoverEnabled: true;
onEntered: {
parent.text = hifi.glyphs.closeInverted;
}
onExited: {
parent.text = hifi.glyphs.close;
}
onClicked: {
Commerce.uninstallApp(model.appUrl);
}
}
}
}
}
HifiControlsUit.Button {
id: sideloadAppButton;
color: hifi.buttons.blue;
colorScheme: hifi.colorSchemes.dark;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 8;
anchors.left: parent.left;
anchors.leftMargin: 8;
anchors.right: closeAppListButton.left;
anchors.rightMargin: 8;
height: 40;
text: "SIDELOAD APP FROM LOCAL DISK";
onClicked: {
Window.browseChanged.connect(onFileOpenChanged);
Window.browseAsync("Locate your app's .app.json file", "", "*.app.json");
}
}
HifiControlsUit.Button {
id: closeAppListButton;
color: hifi.buttons.white;
colorScheme: hifi.colorSchemes.dark;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 8;
anchors.right: parent.right;
anchors.rightMargin: 8;
width: 100;
height: 40;
text: "BACK";
onClicked: {
installedAppsContainer.visible = false;
}
}
}
HifiWallet.NeedsLogIn {
id: needsLogIn;
@ -317,7 +464,7 @@ Rectangle {
//
Item {
id: purchasesContentsContainer;
visible: root.activeView === "purchasesMain";
visible: root.activeView === "purchasesMain" && !installedAppsList.visible;
// Anchors
anchors.left: parent.left;
anchors.right: parent.right;
@ -959,6 +1106,39 @@ Rectangle {
}
}
Keys.onPressed: {
if ((event.key == Qt.Key_F) && (event.modifiers & Qt.ControlModifier)) {
installedAppsContainer.visible = !installedAppsContainer.visible;
console.log("User changed visibility of installedAppsContainer to " + installedAppsContainer.visible);
}
}
function onFileOpenChanged(filename) {
// disconnect the event, otherwise the requests will stack up
try { // Not all calls to onFileOpenChanged() connect an event.
Window.browseChanged.disconnect(onFileOpenChanged);
} catch (e) {
console.log('Purchases.qml ignoring', e);
}
if (filename) {
Commerce.installApp(filename);
}
}
ListModel {
id: installedAppsModel;
}
onInstalledAppsChanged: {
installedAppsModel.clear();
var installedAppsArray = root.installedApps.split(",");
var installedAppsObject = [];
// "- 1" because the last app string ends with ","
for (var i = 0; i < installedAppsArray.length - 1; i++) {
installedAppsObject[i] = {
"appUrl": installedAppsArray[i]
}
}
installedAppsModel.append(installedAppsObject);
}
//
// Function Name: fromScript()
//

View file

@ -1070,6 +1070,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
if (steamClient) {
qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID();
}
setCrashAnnotation("steam", property(hifi::properties::STEAM).toBool() ? "1" : "0");
qCDebug(interfaceapp) << "[VERSION] Build sequence:" << qPrintable(applicationVersion());
qCDebug(interfaceapp) << "[VERSION] MODIFIED_ORGANIZATION:" << BuildInfo::MODIFIED_ORGANIZATION;
qCDebug(interfaceapp) << "[VERSION] VERSION:" << BuildInfo::VERSION;
@ -1155,6 +1157,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
const DomainHandler& domainHandler = nodeList->getDomainHandler();
connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainURLChanged(QUrl)));
connect(&domainHandler, &DomainHandler::domainURLChanged, [](QUrl domainURL){
setCrashAnnotation("domain", domainURL.toString().toStdString());
});
connect(&domainHandler, SIGNAL(resetting()), SLOT(resettingDomain()));
connect(&domainHandler, SIGNAL(connectedToDomain(QUrl)), SLOT(updateWindowTitle()));
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
@ -1200,6 +1205,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
auto dialogsManager = DependencyManager::get<DialogsManager>();
connect(accountManager.data(), &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
connect(accountManager.data(), &AccountManager::usernameChanged, [](QString username){
setCrashAnnotation("username", username.toStdString());
});
// set the account manager's root URL and trigger a login request if we don't have the access token
accountManager->setIsAgent(true);
@ -1217,6 +1225,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateThreadPoolCount);
connect(this, &Application::activeDisplayPluginChanged, this, [](){
qApp->setProperty(hifi::properties::HMD, qApp->isHMDMode());
auto displayPlugin = qApp->getActiveDisplayPlugin();
setCrashAnnotation("display_plugin", displayPlugin->getName().toStdString());
setCrashAnnotation("hmd", displayPlugin->isHmd() ? "1" : "0");
});
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateSystemTabletMode);
@ -1224,6 +1235,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(myAvatar.get(), &MyAvatar::positionGoneTo,
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
connect(myAvatar.get(), &MyAvatar::skeletonModelURLChanged, [](){
QUrl avatarURL = qApp->getMyAvatar()->getSkeletonModelURL();
setCrashAnnotation("avatar", avatarURL.toString().toStdString());
});
// Inititalize sample before registering
_sampleSound = DependencyManager::get<SoundCache>()->getSound(PathUtils::resourcesUrl("sounds/sample.wav"));
@ -1388,6 +1405,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
userActivityLogger.disable(false);
}
QString machineFingerPrint = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint());
if (userActivityLogger.isEnabled()) {
// sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
// The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
@ -1437,11 +1456,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
properties["first_run"] = firstRun.get();
// add the user's machine ID to the launch event
properties["machine_fingerprint"] = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint());
properties["machine_fingerprint"] = machineFingerPrint;
userActivityLogger.logAction("launch", properties);
}
setCrashAnnotation("machine_fingerprint", machineFingerPrint.toStdString());
_entityEditSender.setMyAvatar(myAvatar.get());
// The entity octree will have to know about MyAvatar for the parentJointName import

View file

@ -15,6 +15,8 @@
#if HAS_CRASHPAD
#include <mutex>
#include <QStandardPaths>
#include <QDir>
@ -23,8 +25,8 @@
#include <client/crashpad_client.h>
#include <client/crash_report_database.h>
#include <client/settings.h>
// #include <client/annotation_list.h>
// #include <client/crashpad_info.h>
#include <client/annotation_list.h>
#include <client/crashpad_info.h>
using namespace crashpad;
@ -35,7 +37,8 @@ static std::wstring gIPCPipe;
extern QString qAppFileName();
// crashpad::AnnotationList* crashpadAnnotations { nullptr };
std::mutex annotationMutex;
crashpad::SimpleStringDictionary* crashpadAnnotations { nullptr };
#include <Windows.h>
@ -102,12 +105,14 @@ bool startCrashHandler() {
}
void setCrashAnnotation(std::string name, std::string value) {
// if (!crashpadAnnotations) {
// crashpadAnnotations = new crashpad::AnnotationList(); // don't free this, let it leak
// crashpad::CrashpadInfo* crashpad_info = crashpad::GetCrashpadInfo();
// crashpad_info->set_simple_annotations(crashpadAnnotations);
// }
// crashpadAnnotations->SetKeyValue(name, value);
std::lock_guard<std::mutex> guard(annotationMutex);
if (!crashpadAnnotations) {
crashpadAnnotations = new crashpad::SimpleStringDictionary(); // don't free this, let it leak
crashpad::CrashpadInfo* crashpad_info = crashpad::CrashpadInfo::GetCrashpadInfo();
crashpad_info->set_simple_annotations(crashpadAnnotations);
}
std::replace(value.begin(), value.end(), ',', ';');
crashpadAnnotations->SetKeyValue(name, value);
}
#else

View file

@ -20,6 +20,7 @@
#include <UserActivityLogger.h>
#include <UUID.h>
#include "Crashpad.h"
#include "DiscoverabilityManager.h"
#include "Menu.h"
@ -127,10 +128,12 @@ void DiscoverabilityManager::updateLocation() {
QNetworkAccessManager::PutOperation, callbackParameters);
}
// Update Steam
// Update Steam and crash logger
QUrl currentAddress = addressManager->currentFacingPublicAddress();
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
steamClient->updateLocation(domainHandler.getHostname(), addressManager->currentFacingPublicAddress());
steamClient->updateLocation(domainHandler.getHostname(), currentAddress);
}
setCrashAnnotation("address", currentAddress.toString().toStdString());
}
void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply) {

View file

@ -9,14 +9,6 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
/**jsdoc
* The LODManager API manages your Level of Detail functions within interface.
* @namespace LODManager
*
* @hifi-interface
* @hifi-client-entity
*/
#ifndef hifi_LODManager_h
#define hifi_LODManager_h
@ -42,10 +34,36 @@ const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.04f;
class AABox;
/**jsdoc
* The LOD class manages your Level of Detail functions within Interface.
* @namespace LODManager
*
* @hifi-interface
* @hifi-client-entity
*
* @property {number} presentTime <em>Read-only.</em>
* @property {number} engineRunTime <em>Read-only.</em>
* @property {number} gpuTime <em>Read-only.</em>
* @property {number} avgRenderTime <em>Read-only.</em>
* @property {number} fps <em>Read-only.</em>
* @property {number} lodLevel <em>Read-only.</em>
* @property {number} lodDecreaseFPS <em>Read-only.</em>
* @property {number} lodIncreaseFPS <em>Read-only.</em>
*/
class LODManager : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
Q_PROPERTY(float presentTime READ getPresentTime)
Q_PROPERTY(float engineRunTime READ getEngineRunTime)
Q_PROPERTY(float gpuTime READ getGPUTime)
Q_PROPERTY(float avgRenderTime READ getAverageRenderTime)
Q_PROPERTY(float fps READ getMaxTheoreticalFPS)
Q_PROPERTY(float lodLevel READ getLODLevel)
Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS)
Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS)
public:
/**jsdoc
@ -141,28 +159,6 @@ public:
*/
Q_INVOKABLE float getLODIncreaseFPS() const;
/**jsdoc
* @namespace LODManager
* @property {number} presentTime <em>Read-only.</em>
* @property {number} engineRunTime <em>Read-only.</em>
* @property {number} gpuTime <em>Read-only.</em>
* @property {number} avgRenderTime <em>Read-only.</em>
* @property {number} fps <em>Read-only.</em>
* @property {number} lodLevel <em>Read-only.</em>
* @property {number} lodDecreaseFPS <em>Read-only.</em>
* @property {number} lodIncreaseFPS <em>Read-only.</em>
*/
Q_PROPERTY(float presentTime READ getPresentTime)
Q_PROPERTY(float engineRunTime READ getEngineRunTime)
Q_PROPERTY(float gpuTime READ getGPUTime)
Q_PROPERTY(float avgRenderTime READ getAverageRenderTime)
Q_PROPERTY(float fps READ getMaxTheoreticalFPS)
Q_PROPERTY(float lodLevel READ getLODLevel)
Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS)
Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS)
float getPresentTime() const { return _presentTime; }
float getEngineRunTime() const { return _engineRunTime; }
float getGPUTime() const { return _gpuTime; }

View file

@ -615,9 +615,15 @@ void Wallet::updateImageProvider() {
securityImageProvider->setSecurityImage(_securityImage);
// inform tablet security image provider
QQmlEngine* tabletEngine = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system")->getTabletSurface()->getSurfaceContext()->engine();
securityImageProvider = reinterpret_cast<SecurityImageProvider*>(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
securityImageProvider->setSecurityImage(_securityImage);
TabletProxy* tablet = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
if (tablet) {
OffscreenQmlSurface* tabletSurface = tablet->getTabletSurface();
if (tabletSurface) {
QQmlEngine* tabletEngine = tabletSurface->getSurfaceContext()->engine();
securityImageProvider = reinterpret_cast<SecurityImageProvider*>(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
securityImageProvider->setSecurityImage(_securityImage);
}
}
}
void Wallet::chooseSecurityImage(const QString& filename) {

View file

@ -28,7 +28,7 @@ class ScriptEngine;
/**jsdoc
* The Controller API provides facilities to interact with computer and controller hardware.
*
* <h5>Functions:</h5>
* <h5>Functions</h5>
*
* <p>Properties</p>
* <ul>
@ -143,6 +143,61 @@ class ScriptEngine;
* <li>{@link Controller.stopInputPlayback|stopInputPlayback}</li>
* </ul>
*
* <h5>Entity Methods:</h5>
*
* <p>The default scripts implement hand controller actions that use {@link Entities.callEntityMethod} to call entity script
* methods, if present in the entity being interacted with.</p>
*
* <table>
* <thead>
* <tr><th>Method Name</th><th>Description</th><th>Example</th></tr>
* </thead>
* <tbody>
* <tr>
* <td><code>startFarTrigger</code><br /><code>continueFarTrigger</code><br /><code>stopFarTrigger</code></td>
* <td>These methods are called when a user is more than 0.3m away from the entity, the entity is triggerable, and the
* user starts, continues, or stops squeezing the trigger.</td>
* </td>
* <td>A light switch that can be toggled on and off from a distance.</td>
* </tr>
* <tr>
* <td><code>startNearTrigger</code><br /><code>continueNearTrigger</code><br /><code>stopNearTrigger</code></td>
* <td>These methods are called when a user is less than 0.3m away from the entity, the entity is triggerable, and the
* user starts, continues, or stops squeezing the trigger.</td>
* <td>A doorbell that can be rung when a user is near.</td>
* </tr>
* <tr>
* <td><code>startDistanceGrab</code><br /><code>continueDistanceGrab</code><br /></td>
* <td>These methods are called when a user is more than 0.3m away from the entity, the entity is either cloneable, or
* grabbable and not locked, and the user starts or continues to squeeze the trigger.</td>
* <td>A comet that emits icy particle trails when a user is dragging it through the sky.</td>
* </tr>
* <tr>
* <td><code>startNearGrab</code><br /><code>continueNearGrab</code><br /></td>
* <td>These methods are called when a user is less than 0.3m away from the entity, the entity is either cloneable, or
* grabbable and not locked, and the user starts or continues to squeeze the trigger.</td>
* <td>A ball that glows when it's being held close.</td>
* </tr>
* <tr>
* <td><code>releaseGrab</code></td>
* <td>This method is called when a user releases the trigger when having been either distance or near grabbing an
* entity.</td>
* <td>Turn off the ball glow or comet trail with the user finishes grabbing it.</td>
* </tr>
* <tr>
* <td><code>startEquip</code><br /><code>continueEquip</code><br /><code>releaseEquip</code></td>
* <td>These methods are called when a user starts, continues, or stops equipping an entity.</td>
* <td>A glass that stays in the user's hand after the trigger is clicked.</td>
* </tr>
* </tbody>
* </table>
* <p>All the entity methods are called with the following two arguments:</p>
* <ul>
* <li>The entity ID.</li>
* <li>A string, <code>"hand,userID"</code> &mdash; where "hand" is <code>"left"</code> or <code>"right"</code>, and "userID"
* is the user's {@link MyAvatar|MyAvatar.sessionUUID}.</li>
* </ul>
*
* @namespace Controller
*
* @hifi-interface

View file

@ -588,6 +588,7 @@ void AnimExpression::evalUnaryMinus(const AnimVariantMap& map, std::stack<OpCode
PUSH(false);
break;
}
break;
}
case OpCode::Int:
PUSH(-rhs.intVal);

View file

@ -10,6 +10,7 @@
// Inline functions to implement audio dynamics processing
//
#include <stddef.h>
#include <math.h>
#include <stdint.h>

View file

@ -39,7 +39,9 @@ class UserInputMapper;
* methods.</li>
* <li>Use {@link Controller.parseMapping} or {@link Controller.loadMapping} to load a {@link Controller.MappingJSON}.</li>
* </ul>
* <p>Enable the mapping using {@link MappingObject#enable|enable} or {@link Controller.enableMapping} for it to take effect.
*
* <p>Enable the mapping using {@link MappingObject#enable|enable} or {@link Controller.enableMapping} for it to take
* effect.</p>
*
* <p>Mappings and their routes are applied according to the following rules:</p>
* <ul>

View file

@ -29,7 +29,8 @@ class ScriptingInterface;
* <p>A route in a {@link MappingObject} used by the {@link Controller} API.</p>
*
* <p>Create a route using {@link MappingObject} methods and apply this object's methods to process it, terminating with
* {@link RouteObject#to} to apply it to a <code>Standard</code> control, action, or script function.</p>
* {@link RouteObject#to} to apply it to a <code>Standard</code> control, action, or script function. Note: Loops are not
* permitted.</p>
*
* <p>Some methods apply to routes with number data, some apply routes with {@link Pose} data, and some apply to both route
* types.<p>

View file

@ -396,17 +396,18 @@ public slots:
/**jsdoc
* Find all entities of a particular name that intersect a sphere defined by a center point and radius.
* @function Entities.findEntitiesByName
* @param {Entities.EntityType} entityName - The name of the entity to search for.
* @param {string} entityName - The name of the entity to search for.
* @param {Vec3} center - The point about which to search.
* @param {number} radius - The radius within which to search.
* @param {boolean} caseSensitiveSearch - Choose whether to to return case sensitive results back.
* @returns {Uuid[]} An array of entity IDs of the specified type that intersect the search sphere. The array is empty if
* no entities could be found.
* @example <caption>Get back a list of entities</caption>
* @param {boolean} [caseSensitive=false] - If <code>true</code> then the search is case-sensitive.
* @returns {Uuid[]} An array of entity IDs that have the specified name and intersect the search sphere. The array is empty
* if no entities could be found.
* @example <caption>Report the number of entities with the name, "Light-Target".</caption>
* var entityIDs = Entities.findEntitiesByName("Light-Target", MyAvatar.position, 10, false);
* print("Number of Entities with the name Light-Target " + entityIDs.length);
* print("Number of entities with the name "Light-Target": " + entityIDs.length);
*/
Q_INVOKABLE QVector<QUuid> findEntitiesByName(const QString entityName, const glm::vec3& center, float radius, bool caseSensitiveSearch = false ) const;
Q_INVOKABLE QVector<QUuid> findEntitiesByName(const QString entityName, const glm::vec3& center, float radius,
bool caseSensitiveSearch = false ) const;
/**jsdoc
* Find the first entity intersected by a {@link PickRay}. <code>Light</code> and <code>Zone</code> entities are not

View file

@ -333,12 +333,14 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
return false;
}
static const QString LOCALHOST = "localhost";
bool isPossiblePlaceName(QString possiblePlaceName) {
bool result { false };
int length = possiblePlaceName.length();
static const int MINIMUM_PLACENAME_LENGTH = 1;
static const int MAXIMUM_PLACENAME_LENGTH = 64;
if (possiblePlaceName.toLower() != "localhost" &&
if (possiblePlaceName.toLower() != LOCALHOST &&
length >= MINIMUM_PLACENAME_LENGTH && length <= MAXIMUM_PLACENAME_LENGTH) {
const QRegExp PLACE_NAME_REGEX = QRegExp("^[0-9A-Za-z](([0-9A-Za-z]|-(?!-))*[^\\W_]$|$)");
result = PLACE_NAME_REGEX.indexIn(possiblePlaceName) == 0;
@ -358,7 +360,7 @@ void AddressManager::handleLookupString(const QString& lookupString, bool fromSu
sanitizedString = sanitizedString.remove(HIFI_SCHEME_REGEX);
lookupURL = QUrl(sanitizedString);
if (lookupURL.scheme().isEmpty()) {
if (lookupURL.scheme().isEmpty() || lookupURL.scheme().toLower() == LOCALHOST) {
lookupURL = QUrl("hifi://" + sanitizedString);
}
} else {
@ -607,7 +609,7 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri
if (ipAddressRegex.indexIn(lookupString) != -1) {
QString domainIPString = ipAddressRegex.cap(1);
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
quint16 domainPort = 0;
if (!ipAddressRegex.cap(2).isEmpty()) {
domainPort = (quint16) ipAddressRegex.cap(2).toInt();
}
@ -629,7 +631,7 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri
if (hostnameRegex.indexIn(lookupString) != -1) {
QString domainHostname = hostnameRegex.cap(1);
quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
quint16 domainPort = 0;
if (!hostnameRegex.cap(2).isEmpty()) {
domainPort = (quint16)hostnameRegex.cap(2).toInt();

View file

@ -166,7 +166,12 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
}
}
if (_domainURL != domainURL || _sockAddr.getPort() != domainURL.port()) {
auto domainPort = domainURL.port();
if (domainPort == -1) {
domainPort = DEFAULT_DOMAIN_SERVER_PORT;
}
if (_domainURL != domainURL || _sockAddr.getPort() != domainPort) {
// re-set the domain info so that auth information is reloaded
hardReset();
@ -192,12 +197,10 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
emit domainURLChanged(_domainURL);
if (_sockAddr.getPort() != domainURL.port()) {
qCDebug(networking) << "Updated domain port to" << domainURL.port();
if (_sockAddr.getPort() != domainPort) {
qCDebug(networking) << "Updated domain port to" << domainPort;
_sockAddr.setPort(domainPort);
}
// grab the port by reading the string after the colon
_sockAddr.setPort(domainURL.port());
}
}

View file

@ -153,6 +153,8 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
// remove the objects (aka MotionStates) from physics
_physicsEngine->removeSetOfObjects(_physicalObjects);
clearOwnershipData();
// delete the MotionStates
for (auto stateItr : _physicalObjects) {
EntityMotionState* motionState = static_cast<EntityMotionState*>(&(*stateItr));
@ -165,7 +167,6 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
_physicalObjects.clear();
// clear all other lists specific to this derived class
clearOwnershipData();
_entitiesToRemoveFromPhysics.clear();
_entitiesToAddToPhysics.clear();
_incomingChanges.clear();

View file

@ -16,6 +16,7 @@
#include "AbstractViewStateInterface.h"
#include "RenderUtilsLogging.h"
#include "DebugDraw.h"
#include "StencilMaskPass.h"
#include "animdebugdraw_vert.h"
#include "animdebugdraw_frag.h"
@ -70,7 +71,7 @@ public:
typedef render::Payload<AnimDebugDrawData> AnimDebugDrawPayload;
namespace render {
template <> const ItemKey payloadGetKey(const AnimDebugDrawData::Pointer& data) { return (data->_isVisible ? ItemKey::Builder::opaqueShape() : ItemKey::Builder::opaqueShape().withInvisible()).withTagBits(ItemKey::TAG_BITS_ALL); }
template <> const ItemKey payloadGetKey(const AnimDebugDrawData::Pointer& data) { return (data->_isVisible ? ItemKey::Builder::transparentShape() : ItemKey::Builder::transparentShape().withInvisible()).withTagBits(ItemKey::TAG_BITS_ALL); }
template <> const Item::Bound payloadGetBound(const AnimDebugDrawData::Pointer& data) { return data->_bound; }
template <> void payloadRender(const AnimDebugDrawData::Pointer& data, RenderArgs* args) {
data->render(args);
@ -104,6 +105,7 @@ AnimDebugDraw::AnimDebugDraw() :
state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD,
gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA,
gpu::State::BLEND_OP_ADD, gpu::State::ONE);
PrepareStencil::testMaskDrawShape(*state.get());
auto vertShader = animdebugdraw_vert::getShader();
auto fragShader = animdebugdraw_frag::getShader();
auto program = gpu::Shader::createProgram(vertShader, fragShader);

View file

@ -2161,6 +2161,32 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString&
}, forceRedownload);
}
/**jsdoc
* Triggered when the script starts for a user.
* <p>Note: Can only be connected to via <code>this.preload = function (...) { ... }</code> in the entity script.</p>
* <table><tr><th>Available in:</th><td>Client Entity Scripts</td><td>Server Entity Scripts</td></tr></table>
* @function Entities.preload
* @param {Uuid} entityID - The ID of the entity that the script is running in.
* @returns {Signal}
* @example <caption>Get the ID of the entity that a client entity script is running in.</caption>
* var entityScript = (function () {
* this.entityID = Uuid.NULL;
*
* this.preload = function (entityID) {
* this.entityID = entityID;
* print("Entity ID: " + this.entityID);
* };
* );
*
* var entityID = Entities.addEntity({
* type: "Box",
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
* dimensions: { x: 0.5, y: 0.5, z: 0.5 },
* color: { red: 255, green: 0, blue: 0 },
* script: "(" + entityScript + ")", // Could host the script on a Web server instead.
* lifetime: 300 // Delete after 5 minutes.
* });
*/
// since all of these operations can be asynch we will always do the actual work in the response handler
// for the download
void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success , const QString& status) {
@ -2345,6 +2371,13 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
processDeferredEntityLoads(entityScript, entityID);
}
/**jsdoc
* Triggered when the script terminates for a user.
* <p>Note: Can only be connected to via <code>this.unoad = function () { ... }</code> in the entity script.</p>
* <table><tr><th>Available in:</th><td>Client Entity Scripts</td><td>Server Entity Scripts</td></tr></table>
* @function Entities.unload
* @returns {Signal}
*/
void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap) {
if (QThread::currentThread() != thread()) {
#ifdef THREAD_DEBUGGING

View file

@ -213,7 +213,7 @@ void setOctalCodeSectionValue(unsigned char* octalCode, int section, char sectio
int byteForSection = (BITS_IN_OCTAL * section / BITS_IN_BYTE);
unsigned char* byteAt = octalCode + 1 + byteForSection;
char bitInByte = (BITS_IN_OCTAL * section) % BITS_IN_BYTE;
char shiftBy = BITS_IN_BYTE - bitInByte - BITS_IN_OCTAL;
int8_t shiftBy = BITS_IN_BYTE - bitInByte - BITS_IN_OCTAL;
const unsigned char UNSHIFTED_MASK = 0x07;
unsigned char shiftedMask;
unsigned char shiftedValue;

View file

@ -321,7 +321,8 @@
{
id: "alpha",
name: "Alpha",
type: "SliderFloat"
type: "SliderFloat",
max: 1.0
},
{
type: "Row"
@ -329,7 +330,8 @@
{
id: "alphaSpread",
name: "Alpha Spread",
type: "SliderFloat"
type: "SliderFloat",
max: 1.0
},
{
type: "Row"
@ -337,7 +339,8 @@
{
id: "alphaStart",
name: "Alpha Start",
type: "SliderFloat"
type: "SliderFloat",
max: 1.0
},
{
type: "Row"
@ -345,7 +348,8 @@
{
id: "alphaFinish",
name: "Alpha Finish",
type: "SliderFloat"
type: "SliderFloat",
max: 1.0
},
{
type: "Row"

View file

@ -23,5 +23,9 @@ if (WIN32)
add_dependency_external_projects(wasapi)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
target_link_libraries(${TARGET_NAME} atomic)
endif()
package_libraries_for_deployment()
endif()
endif()

View file

@ -27,6 +27,10 @@ if (WIN32)
add_dependency_external_projects(wasapi)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
target_link_libraries(${TARGET_NAME} atomic)
endif()
package_libraries_for_deployment()