mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 06:58:56 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into hand-controller-pointer
This commit is contained in:
commit
3f3233da66
43 changed files with 619 additions and 370 deletions
|
@ -161,7 +161,6 @@ extern "C" {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static QTimer locationUpdateTimer;
|
static QTimer locationUpdateTimer;
|
||||||
static QTimer balanceUpdateTimer;
|
|
||||||
static QTimer identityPacketTimer;
|
static QTimer identityPacketTimer;
|
||||||
static QTimer pingTimer;
|
static QTimer pingTimer;
|
||||||
|
|
||||||
|
@ -677,6 +676,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain,
|
connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain,
|
||||||
discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
|
discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
|
||||||
|
|
||||||
|
// send a location update immediately
|
||||||
|
discoverabilityManager->updateLocation();
|
||||||
|
|
||||||
connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded);
|
connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded);
|
||||||
connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled);
|
connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled);
|
||||||
connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated);
|
connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated);
|
||||||
|
@ -688,13 +690,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
// connect to appropriate slots on AccountManager
|
// connect to appropriate slots on AccountManager
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
|
||||||
const qint64 BALANCE_UPDATE_INTERVAL_MSECS = 5 * MSECS_PER_SEC;
|
|
||||||
|
|
||||||
connect(&balanceUpdateTimer, &QTimer::timeout, &accountManager, &AccountManager::updateBalance);
|
|
||||||
balanceUpdateTimer.start(BALANCE_UPDATE_INTERVAL_MSECS);
|
|
||||||
|
|
||||||
connect(&accountManager, &AccountManager::balanceChanged, this, &Application::updateWindowTitle);
|
|
||||||
|
|
||||||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||||
connect(&accountManager, &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
|
connect(&accountManager, &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
|
||||||
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
||||||
|
@ -1197,7 +1192,6 @@ void Application::cleanupBeforeQuit() {
|
||||||
// first stop all timers directly or by invokeMethod
|
// first stop all timers directly or by invokeMethod
|
||||||
// depending on what thread they run in
|
// depending on what thread they run in
|
||||||
locationUpdateTimer.stop();
|
locationUpdateTimer.stop();
|
||||||
balanceUpdateTimer.stop();
|
|
||||||
identityPacketTimer.stop();
|
identityPacketTimer.stop();
|
||||||
pingTimer.stop();
|
pingTimer.stop();
|
||||||
QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection);
|
||||||
|
|
|
@ -15,12 +15,13 @@
|
||||||
#include <AddressManager.h>
|
#include <AddressManager.h>
|
||||||
#include <DomainHandler.h>
|
#include <DomainHandler.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
#include <UserActivityLogger.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
|
||||||
#include "DiscoverabilityManager.h"
|
#include "DiscoverabilityManager.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
|
|
||||||
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::All;
|
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::Friends;
|
||||||
|
|
||||||
DiscoverabilityManager::DiscoverabilityManager() :
|
DiscoverabilityManager::DiscoverabilityManager() :
|
||||||
_mode("discoverabilityMode", DEFAULT_DISCOVERABILITY_MODE)
|
_mode("discoverabilityMode", DEFAULT_DISCOVERABILITY_MODE)
|
||||||
|
@ -29,17 +30,17 @@ DiscoverabilityManager::DiscoverabilityManager() :
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString API_USER_LOCATION_PATH = "/api/v1/user/location";
|
const QString API_USER_LOCATION_PATH = "/api/v1/user/location";
|
||||||
|
const QString API_USER_HEARTBEAT_PATH = "/api/v1/user/heartbeat";
|
||||||
|
|
||||||
|
const QString SESSION_ID_KEY = "session_id";
|
||||||
|
|
||||||
void DiscoverabilityManager::updateLocation() {
|
void DiscoverabilityManager::updateLocation() {
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
|
|
||||||
if (_mode.get() != Discoverability::None) {
|
if (_mode.get() != Discoverability::None && accountManager.isLoggedIn()) {
|
||||||
auto addressManager = DependencyManager::get<AddressManager>();
|
auto addressManager = DependencyManager::get<AddressManager>();
|
||||||
DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
|
DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
|
||||||
|
|
||||||
if (accountManager.isLoggedIn() && domainHandler.isConnected()
|
|
||||||
&& (!addressManager->getRootPlaceID().isNull() || !domainHandler.getUUID().isNull())) {
|
|
||||||
|
|
||||||
// construct a QJsonObject given the user's current address information
|
// construct a QJsonObject given the user's current address information
|
||||||
QJsonObject rootObject;
|
QJsonObject rootObject;
|
||||||
|
|
||||||
|
@ -52,30 +53,80 @@ void DiscoverabilityManager::updateLocation() {
|
||||||
const QString PATH_KEY_IN_LOCATION = "path";
|
const QString PATH_KEY_IN_LOCATION = "path";
|
||||||
locationObject.insert(PATH_KEY_IN_LOCATION, pathString);
|
locationObject.insert(PATH_KEY_IN_LOCATION, pathString);
|
||||||
|
|
||||||
|
const QString CONNECTED_KEY_IN_LOCATION = "connected";
|
||||||
|
locationObject.insert(CONNECTED_KEY_IN_LOCATION, domainHandler.isConnected());
|
||||||
|
|
||||||
if (!addressManager->getRootPlaceID().isNull()) {
|
if (!addressManager->getRootPlaceID().isNull()) {
|
||||||
const QString PLACE_ID_KEY_IN_LOCATION = "place_id";
|
const QString PLACE_ID_KEY_IN_LOCATION = "place_id";
|
||||||
locationObject.insert(PLACE_ID_KEY_IN_LOCATION,
|
locationObject.insert(PLACE_ID_KEY_IN_LOCATION,
|
||||||
uuidStringWithoutCurlyBraces(addressManager->getRootPlaceID()));
|
uuidStringWithoutCurlyBraces(addressManager->getRootPlaceID()));
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
if (!domainHandler.getUUID().isNull()) {
|
||||||
const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id";
|
const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id";
|
||||||
locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION,
|
locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION,
|
||||||
uuidStringWithoutCurlyBraces(domainHandler.getUUID()));
|
uuidStringWithoutCurlyBraces(domainHandler.getUUID()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in case the place/domain isn't in the database, we send the network address and port
|
||||||
|
auto& domainSockAddr = domainHandler.getSockAddr();
|
||||||
|
const QString NETWORK_ADRESS_KEY_IN_LOCATION = "network_address";
|
||||||
|
locationObject.insert(NETWORK_ADRESS_KEY_IN_LOCATION, domainSockAddr.getAddress().toString());
|
||||||
|
|
||||||
|
const QString NETWORK_ADDRESS_PORT_IN_LOCATION = "network_port";
|
||||||
|
locationObject.insert(NETWORK_ADDRESS_PORT_IN_LOCATION, domainSockAddr.getPort());
|
||||||
|
|
||||||
const QString FRIENDS_ONLY_KEY_IN_LOCATION = "friends_only";
|
const QString FRIENDS_ONLY_KEY_IN_LOCATION = "friends_only";
|
||||||
locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends));
|
locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends));
|
||||||
|
|
||||||
|
// if we have a session ID add it now, otherwise add a null value
|
||||||
|
rootObject[SESSION_ID_KEY] = _sessionID.isEmpty() ? QJsonValue() : _sessionID;
|
||||||
|
|
||||||
|
JSONCallbackParameters callbackParameters;
|
||||||
|
callbackParameters.jsonCallbackReceiver = this;
|
||||||
|
callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse";
|
||||||
|
|
||||||
|
// figure out if we'll send a fresh location or just a simple heartbeat
|
||||||
|
auto apiPath = API_USER_HEARTBEAT_PATH;
|
||||||
|
|
||||||
|
if (locationObject != _lastLocationObject) {
|
||||||
|
// we have a changed location, send it now
|
||||||
|
_lastLocationObject = locationObject;
|
||||||
|
|
||||||
rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject);
|
rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject);
|
||||||
|
|
||||||
accountManager.sendRequest(API_USER_LOCATION_PATH, AccountManagerAuth::Required,
|
apiPath = API_USER_LOCATION_PATH;
|
||||||
QNetworkAccessManager::PutOperation,
|
|
||||||
JSONCallbackParameters(), QJsonDocument(rootObject).toJson());
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
accountManager.sendRequest(apiPath, AccountManagerAuth::Required,
|
||||||
|
QNetworkAccessManager::PutOperation,
|
||||||
|
callbackParameters, QJsonDocument(rootObject).toJson());
|
||||||
|
|
||||||
|
} else if (UserActivityLogger::getInstance().isEnabled()) {
|
||||||
// we still send a heartbeat to the metaverse server for stats collection
|
// we still send a heartbeat to the metaverse server for stats collection
|
||||||
const QString API_USER_HEARTBEAT_PATH = "/api/v1/user/heartbeat";
|
|
||||||
accountManager.sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Required, QNetworkAccessManager::PutOperation);
|
JSONCallbackParameters callbackParameters;
|
||||||
|
callbackParameters.jsonCallbackReceiver = this;
|
||||||
|
callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse";
|
||||||
|
|
||||||
|
QJsonObject heartbeatObject;
|
||||||
|
if (!_sessionID.isEmpty()) {
|
||||||
|
heartbeatObject[SESSION_ID_KEY] = _sessionID;
|
||||||
|
} else {
|
||||||
|
heartbeatObject[SESSION_ID_KEY] = QJsonValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
accountManager.sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Optional,
|
||||||
|
QNetworkAccessManager::PutOperation, callbackParameters,
|
||||||
|
QJsonDocument(heartbeatObject).toJson());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply) {
|
||||||
|
auto dataObject = AccountManager::dataObjectFromResponse(requestReply);
|
||||||
|
|
||||||
|
if (!dataObject.isEmpty()) {
|
||||||
|
_sessionID = dataObject[SESSION_ID_KEY].toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +144,9 @@ void DiscoverabilityManager::setDiscoverabilityMode(Discoverability::Mode discov
|
||||||
if (static_cast<int>(_mode.get()) == Discoverability::None) {
|
if (static_cast<int>(_mode.get()) == Discoverability::None) {
|
||||||
// if we just got set to no discoverability, make sure that we delete our location in DB
|
// if we just got set to no discoverability, make sure that we delete our location in DB
|
||||||
removeLocation();
|
removeLocation();
|
||||||
|
} else {
|
||||||
|
// we have a discoverability mode that says we should send a location, do that right away
|
||||||
|
updateLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit discoverabilityModeChanged(discoverabilityMode);
|
emit discoverabilityModeChanged(discoverabilityMode);
|
||||||
|
|
|
@ -42,10 +42,15 @@ public slots:
|
||||||
signals:
|
signals:
|
||||||
void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode);
|
void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleHeartbeatResponse(QNetworkReply& requestReply);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DiscoverabilityManager();
|
DiscoverabilityManager();
|
||||||
|
|
||||||
Setting::Handle<int> _mode;
|
Setting::Handle<int> _mode;
|
||||||
|
QString _sessionID;
|
||||||
|
QJsonObject _lastLocationObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_DiscoverabilityManager_h
|
#endif // hifi_DiscoverabilityManager_h
|
|
@ -131,71 +131,102 @@ const glm::vec3 randVector() {
|
||||||
// Do some basic timing tests and report the results
|
// Do some basic timing tests and report the results
|
||||||
void runTimingTests() {
|
void runTimingTests() {
|
||||||
// How long does it take to make a call to get the time?
|
// How long does it take to make a call to get the time?
|
||||||
|
const int numTimingTests = 3;
|
||||||
|
QElapsedTimer startTime;
|
||||||
|
float elapsedNSecs;
|
||||||
|
float elapsedUSecs;
|
||||||
|
|
||||||
|
qCDebug(interfaceapp, "numTimingTests: %d", numTimingTests);
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "QElapsedTimer::nsecElapsed() ns: %f", (double)elapsedNSecs / numTimingTests);
|
||||||
|
|
||||||
|
// Test sleep functions for accuracy
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
QThread::msleep(1);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "QThread::msleep(1) ms: %f", (double)(elapsedNSecs / NSECS_PER_MSEC / numTimingTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
QThread::sleep(1);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "QThread::sleep(1) s: %f", (double)(elapsedNSecs / NSECS_PER_MSEC / MSECS_PER_SECOND / numTimingTests));
|
||||||
|
|
||||||
|
const int numUsecTests = 1000;
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numUsecTests; i++) {
|
||||||
|
usleep(1);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(1) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numUsecTests; i++) {
|
||||||
|
usleep(10);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(10) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numUsecTests; i++) {
|
||||||
|
usleep(100);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(100) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(1000) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
usleep(1001);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(1001) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
for (int i = 0; i < numTimingTests; i++) {
|
||||||
|
usleep(1500);
|
||||||
|
}
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(1500) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
|
||||||
|
|
||||||
|
startTime.start();
|
||||||
|
usleep(15000);
|
||||||
|
elapsedNSecs = (float)startTime.nsecsElapsed();
|
||||||
|
qCDebug(interfaceapp, "usleep(15000) (1x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC));
|
||||||
|
|
||||||
const int numTests = 1000000;
|
const int numTests = 1000000;
|
||||||
int* iResults = (int*)malloc(sizeof(int) * numTests);
|
int* iResults = (int*)malloc(sizeof(int) * numTests);
|
||||||
float fTest = 1.0;
|
float fTest = 1.0;
|
||||||
float* fResults = (float*)malloc(sizeof(float) * numTests);
|
float* fResults = (float*)malloc(sizeof(float) * numTests);
|
||||||
QElapsedTimer startTime;
|
|
||||||
startTime.start();
|
|
||||||
float elapsedUsecs;
|
|
||||||
|
|
||||||
float NSEC_TO_USEC = 1.0f / 1000.0f;
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "QElapsedTimer::nsecElapsed() usecs: %f", (double)elapsedUsecs);
|
|
||||||
|
|
||||||
// Test sleep functions for accuracy
|
|
||||||
startTime.start();
|
|
||||||
QThread::msleep(1);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "QThread::msleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
QThread::sleep(1);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "QThread::sleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(1);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(10);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(10) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(100);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(100) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(1000);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(1000) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
startTime.start();
|
|
||||||
usleep(15000);
|
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
|
||||||
qCDebug(interfaceapp, "usleep(15000) ms: %f", (double)(elapsedUsecs / 1000.0f));
|
|
||||||
|
|
||||||
// Random number generation
|
// Random number generation
|
||||||
startTime.start();
|
startTime.start();
|
||||||
for (int i = 0; i < numTests; i++) {
|
for (int i = 0; i < numTests; i++) {
|
||||||
iResults[i] = rand();
|
iResults[i] = rand();
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "rand() stored in array usecs: %f, first result:%d",
|
qCDebug(interfaceapp, "rand() stored in array usecs: %f, first result:%d",
|
||||||
(double)(elapsedUsecs / numTests), iResults[0]);
|
(double)(elapsedUSecs / numTests), iResults[0]);
|
||||||
|
|
||||||
// Random number generation using randFloat()
|
// Random number generation using randFloat()
|
||||||
startTime.start();
|
startTime.start();
|
||||||
for (int i = 0; i < numTests; i++) {
|
for (int i = 0; i < numTests; i++) {
|
||||||
fResults[i] = randFloat();
|
fResults[i] = randFloat();
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "randFloat() stored in array usecs: %f, first result: %f",
|
qCDebug(interfaceapp, "randFloat() stored in array usecs: %f, first result: %f",
|
||||||
(double)(elapsedUsecs / numTests), (double)(fResults[0]));
|
(double)(elapsedUSecs / numTests), (double)(fResults[0]));
|
||||||
|
|
||||||
free(iResults);
|
free(iResults);
|
||||||
free(fResults);
|
free(fResults);
|
||||||
|
@ -206,8 +237,8 @@ void runTimingTests() {
|
||||||
for (int i = 0; i < numTests; i++) {
|
for (int i = 0; i < numTests; i++) {
|
||||||
fTest = powf(fTest, 0.5f);
|
fTest = powf(fTest, 0.5f);
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "powf(f, 0.5) usecs: %f", (double)(elapsedUsecs / (float) numTests));
|
qCDebug(interfaceapp, "powf(f, 0.5) usecs: %f", (double)(elapsedUSecs / (float) numTests));
|
||||||
|
|
||||||
// Vector Math
|
// Vector Math
|
||||||
float distance;
|
float distance;
|
||||||
|
@ -218,9 +249,9 @@ void runTimingTests() {
|
||||||
//float distanceSquared = glm::dot(temp, temp);
|
//float distanceSquared = glm::dot(temp, temp);
|
||||||
distance = glm::distance(pointA, pointB);
|
distance = glm::distance(pointA, pointB);
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "vector math usecs: %f [%f usecs total for %d tests], last result:%f",
|
qCDebug(interfaceapp, "vector math usecs: %f [%f usecs total for %d tests], last result:%f",
|
||||||
(double)(elapsedUsecs / (float) numTests), (double)elapsedUsecs, numTests, (double)distance);
|
(double)(elapsedUSecs / (float) numTests), (double)elapsedUSecs, numTests, (double)distance);
|
||||||
|
|
||||||
// Vec3 test
|
// Vec3 test
|
||||||
glm::vec3 vecA(randVector()), vecB(randVector());
|
glm::vec3 vecA(randVector()), vecB(randVector());
|
||||||
|
@ -231,9 +262,9 @@ void runTimingTests() {
|
||||||
glm::vec3 temp = vecA-vecB;
|
glm::vec3 temp = vecA-vecB;
|
||||||
result = glm::dot(temp,temp);
|
result = glm::dot(temp,temp);
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp, "vec3 assign and dot() usecs: %f, last result:%f",
|
qCDebug(interfaceapp, "vec3 assign and dot() usecs: %f, last result:%f",
|
||||||
(double)(elapsedUsecs / numTests), (double)result);
|
(double)(elapsedUSecs / numTests), (double)result);
|
||||||
|
|
||||||
|
|
||||||
quint64 BYTE_CODE_MAX_TEST_VALUE = 99999999;
|
quint64 BYTE_CODE_MAX_TEST_VALUE = 99999999;
|
||||||
|
@ -265,9 +296,9 @@ void runTimingTests() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
|
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
|
||||||
qCDebug(interfaceapp) << "ByteCountCoded<quint64> usecs: " << elapsedUsecs
|
qCDebug(interfaceapp) << "ByteCountCoded<quint64> usecs: " << elapsedUSecs
|
||||||
<< "per test:" << (double) (elapsedUsecs / tests)
|
<< "per test:" << (double) (elapsedUSecs / tests)
|
||||||
<< "tests:" << tests
|
<< "tests:" << tests
|
||||||
<< "failed:" << failed;
|
<< "failed:" << failed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,32 +13,16 @@
|
||||||
|
|
||||||
#include "AccountScriptingInterface.h"
|
#include "AccountScriptingInterface.h"
|
||||||
|
|
||||||
AccountScriptingInterface::AccountScriptingInterface() {
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
|
||||||
connect(&accountManager, &AccountManager::balanceChanged, this,
|
|
||||||
&AccountScriptingInterface::updateBalance);
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountScriptingInterface* AccountScriptingInterface::getInstance() {
|
AccountScriptingInterface* AccountScriptingInterface::getInstance() {
|
||||||
static AccountScriptingInterface sharedInstance;
|
static AccountScriptingInterface sharedInstance;
|
||||||
return &sharedInstance;
|
return &sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AccountScriptingInterface::getBalance() {
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
|
||||||
return accountManager.getAccountInfo().getBalanceInSatoshis();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AccountScriptingInterface::isLoggedIn() {
|
bool AccountScriptingInterface::isLoggedIn() {
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
return accountManager.isLoggedIn();
|
return accountManager.isLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountScriptingInterface::updateBalance() {
|
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
|
||||||
emit balanceChanged(accountManager.getAccountInfo().getBalanceInSatoshis());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AccountScriptingInterface::getUsername() {
|
QString AccountScriptingInterface::getUsername() {
|
||||||
AccountManager& accountManager = AccountManager::getInstance();
|
AccountManager& accountManager = AccountManager::getInstance();
|
||||||
if (accountManager.isLoggedIn()) {
|
if (accountManager.isLoggedIn()) {
|
||||||
|
|
|
@ -16,17 +16,11 @@
|
||||||
|
|
||||||
class AccountScriptingInterface : public QObject {
|
class AccountScriptingInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
AccountScriptingInterface();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void balanceChanged(float newBalance);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
static AccountScriptingInterface* getInstance();
|
static AccountScriptingInterface* getInstance();
|
||||||
float getBalance();
|
|
||||||
QString getUsername();
|
QString getUsername();
|
||||||
bool isLoggedIn();
|
bool isLoggedIn();
|
||||||
void updateBalance();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AccountScriptingInterface_h
|
#endif // hifi_AccountScriptingInterface_h
|
||||||
|
|
|
@ -45,7 +45,6 @@ const glm::vec3 DEFAULT_LOCAL_AABOX_CORNER(-0.5f);
|
||||||
const glm::vec3 DEFAULT_LOCAL_AABOX_SCALE(1.0f);
|
const glm::vec3 DEFAULT_LOCAL_AABOX_SCALE(1.0f);
|
||||||
|
|
||||||
const QString AvatarData::FRAME_NAME = "com.highfidelity.recording.AvatarData";
|
const QString AvatarData::FRAME_NAME = "com.highfidelity.recording.AvatarData";
|
||||||
static std::once_flag frameTypeRegistration;
|
|
||||||
|
|
||||||
AvatarData::AvatarData() :
|
AvatarData::AvatarData() :
|
||||||
SpatiallyNestable(NestableType::Avatar, QUuid()),
|
SpatiallyNestable(NestableType::Avatar, QUuid()),
|
||||||
|
@ -1194,10 +1193,15 @@ void AvatarData::sendIdentityPacket() {
|
||||||
|
|
||||||
QByteArray identityData = identityByteArray();
|
QByteArray identityData = identityByteArray();
|
||||||
|
|
||||||
auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, identityData.size());
|
auto packetList = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true);
|
||||||
identityPacket->write(identityData);
|
packetList->write(identityData);
|
||||||
|
nodeList->eachMatchingNode(
|
||||||
nodeList->broadcastToNodes(std::move(identityPacket), NodeSet() << NodeType::AvatarMixer);
|
[&](const SharedNodePointer& node)->bool {
|
||||||
|
return node->getType() == NodeType::AvatarMixer && node->getActiveSocket();
|
||||||
|
},
|
||||||
|
[&](const SharedNodePointer& node) {
|
||||||
|
nodeList->sendPacketList(std::move(packetList), *node);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::sendBillboardPacket() {
|
void AvatarData::sendBillboardPacket() {
|
||||||
|
|
|
@ -655,11 +655,32 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
if (wantTerseEditLogging() && _simulationOwner != newSimOwner) {
|
if (wantTerseEditLogging() && _simulationOwner != newSimOwner) {
|
||||||
qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << newSimOwner;
|
qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << newSimOwner;
|
||||||
}
|
}
|
||||||
if (_simulationOwner.set(newSimOwner)) {
|
if (weOwnSimulation) {
|
||||||
|
if (newSimOwner.getID().isNull() && !_simulationOwner.pendingRelease(lastEditedFromBufferAdjusted)) {
|
||||||
|
// entity-server is trying to clear our ownership (probably at our own request)
|
||||||
|
// but we actually want to own it, therefore we ignore this clear event
|
||||||
|
// and pretend that we own it (we assume we'll recover it soon)
|
||||||
|
} else if (_simulationOwner.set(newSimOwner)) {
|
||||||
_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
|
_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
|
||||||
somethingChanged = true;
|
somethingChanged = true;
|
||||||
// recompute weOwnSimulation so that if this is the packet that tells use we are the owner,
|
// recompute weOwnSimulation for later
|
||||||
// we ignore the physics changes from this packet.
|
weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
|
||||||
|
}
|
||||||
|
} else if (newSimOwner.getID().isNull() && _simulationOwner.pendingTake(lastEditedFromBufferAdjusted)) {
|
||||||
|
// entity-server is trying to clear someone else's ownership
|
||||||
|
// but we want to own it, therefore we ignore this clear event
|
||||||
|
// and pretend that we own it (we assume we'll get it soon)
|
||||||
|
weOwnSimulation = true;
|
||||||
|
if (!_simulationOwner.isNull()) {
|
||||||
|
// someone else really did own it
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
|
||||||
|
somethingChanged = true;
|
||||||
|
_simulationOwner.clearCurrentOwner();
|
||||||
|
}
|
||||||
|
} else if (_simulationOwner.set(newSimOwner)) {
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
|
||||||
|
somethingChanged = true;
|
||||||
|
// recompute weOwnSimulation for later
|
||||||
weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
|
weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1112,6 +1133,30 @@ void EntityItem::getAllTerseUpdateProperties(EntityItemProperties& properties) c
|
||||||
properties._accelerationChanged = true;
|
properties._accelerationChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityItem::pokeSimulationOwnership() {
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_POKE;
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
if (_simulationOwner.matchesValidID(nodeList->getSessionUUID())) {
|
||||||
|
// we already own it
|
||||||
|
_simulationOwner.promotePriority(SCRIPT_POKE_SIMULATION_PRIORITY);
|
||||||
|
} else {
|
||||||
|
// we don't own it yet
|
||||||
|
_simulationOwner.setPendingPriority(SCRIPT_POKE_SIMULATION_PRIORITY, usecTimestampNow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::grabSimulationOwnership() {
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_GRAB;
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
if (_simulationOwner.matchesValidID(nodeList->getSessionUUID())) {
|
||||||
|
// we already own it
|
||||||
|
_simulationOwner.promotePriority(SCRIPT_POKE_SIMULATION_PRIORITY);
|
||||||
|
} else {
|
||||||
|
// we don't own it yet
|
||||||
|
_simulationOwner.setPendingPriority(SCRIPT_GRAB_SIMULATION_PRIORITY, usecTimestampNow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
bool somethingChanged = false;
|
bool somethingChanged = false;
|
||||||
|
|
||||||
|
@ -1646,11 +1691,14 @@ void EntityItem::clearSimulationOwnership() {
|
||||||
|
|
||||||
_simulationOwner.clear();
|
_simulationOwner.clear();
|
||||||
// don't bother setting the DIRTY_SIMULATOR_ID flag because clearSimulationOwnership()
|
// don't bother setting the DIRTY_SIMULATOR_ID flag because clearSimulationOwnership()
|
||||||
// is only ever called entity-server-side and the flags are only used client-side
|
// is only ever called on the entity-server and the flags are only used client-side
|
||||||
//_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
|
//_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityItem::setPendingOwnershipPriority(quint8 priority, const quint64& timestamp) {
|
||||||
|
_simulationOwner.setPendingPriority(priority, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
bool EntityItem::addAction(EntitySimulation* simulation, EntityActionPointer action) {
|
bool EntityItem::addAction(EntitySimulation* simulation, EntityActionPointer action) {
|
||||||
bool result;
|
bool result;
|
||||||
|
|
|
@ -302,6 +302,7 @@ public:
|
||||||
QUuid getSimulatorID() const { return _simulationOwner.getID(); }
|
QUuid getSimulatorID() const { return _simulationOwner.getID(); }
|
||||||
void updateSimulationOwner(const SimulationOwner& owner);
|
void updateSimulationOwner(const SimulationOwner& owner);
|
||||||
void clearSimulationOwnership();
|
void clearSimulationOwnership();
|
||||||
|
void setPendingOwnershipPriority(quint8 priority, const quint64& timestamp);
|
||||||
|
|
||||||
const QString& getMarketplaceID() const { return _marketplaceID; }
|
const QString& getMarketplaceID() const { return _marketplaceID; }
|
||||||
void setMarketplaceID(const QString& value) { _marketplaceID = value; }
|
void setMarketplaceID(const QString& value) { _marketplaceID = value; }
|
||||||
|
@ -373,8 +374,8 @@ public:
|
||||||
|
|
||||||
void getAllTerseUpdateProperties(EntityItemProperties& properties) const;
|
void getAllTerseUpdateProperties(EntityItemProperties& properties) const;
|
||||||
|
|
||||||
void pokeSimulationOwnership() { _dirtyFlags |= Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_POKE; }
|
void pokeSimulationOwnership();
|
||||||
void grabSimulationOwnership() { _dirtyFlags |= Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_GRAB; }
|
void grabSimulationOwnership();
|
||||||
void flagForMotionStateChange() { _dirtyFlags |= Simulation::DIRTY_MOTION_TYPE; }
|
void flagForMotionStateChange() { _dirtyFlags |= Simulation::DIRTY_MOTION_TYPE; }
|
||||||
|
|
||||||
bool addAction(EntitySimulation* simulation, EntityActionPointer action);
|
bool addAction(EntitySimulation* simulation, EntityActionPointer action);
|
||||||
|
|
|
@ -65,7 +65,7 @@ const float ENTITY_ITEM_MAX_RESTITUTION = 0.99f;
|
||||||
const float ENTITY_ITEM_DEFAULT_RESTITUTION = 0.5f;
|
const float ENTITY_ITEM_DEFAULT_RESTITUTION = 0.5f;
|
||||||
|
|
||||||
const float ENTITY_ITEM_MIN_FRICTION = 0.0f;
|
const float ENTITY_ITEM_MIN_FRICTION = 0.0f;
|
||||||
const float ENTITY_ITEM_MAX_FRICTION = 0.99f;
|
const float ENTITY_ITEM_MAX_FRICTION = 10.0f;
|
||||||
const float ENTITY_ITEM_DEFAULT_FRICTION = 0.5f;
|
const float ENTITY_ITEM_DEFAULT_FRICTION = 0.5f;
|
||||||
|
|
||||||
const bool ENTITY_ITEM_DEFAULT_COLLISIONLESS = false;
|
const bool ENTITY_ITEM_DEFAULT_COLLISIONLESS = false;
|
||||||
|
|
|
@ -415,12 +415,12 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityScriptingInterface::setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine) {
|
void EntityScriptingInterface::setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine) {
|
||||||
std::lock_guard<std::mutex> lock(_entitiesScriptEngineLock);
|
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||||
_entitiesScriptEngine = engine;
|
_entitiesScriptEngine = engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityScriptingInterface::callEntityMethod(QUuid id, const QString& method, const QStringList& params) {
|
void EntityScriptingInterface::callEntityMethod(QUuid id, const QString& method, const QStringList& params) {
|
||||||
std::lock_guard<std::mutex> lock(_entitiesScriptEngineLock);
|
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||||
if (_entitiesScriptEngine) {
|
if (_entitiesScriptEngine) {
|
||||||
EntityItemID entityID{ id };
|
EntityItemID entityID{ id };
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params);
|
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params);
|
||||||
|
|
|
@ -215,7 +215,7 @@ private:
|
||||||
|
|
||||||
EntityTreePointer _entityTree;
|
EntityTreePointer _entityTree;
|
||||||
|
|
||||||
std::mutex _entitiesScriptEngineLock;
|
std::recursive_mutex _entitiesScriptEngineLock;
|
||||||
EntitiesScriptEngineProvider* _entitiesScriptEngine { nullptr };
|
EntitiesScriptEngineProvider* _entitiesScriptEngine { nullptr };
|
||||||
|
|
||||||
bool _bidOnSimulationOwnership { false };
|
bool _bidOnSimulationOwnership { false };
|
||||||
|
|
|
@ -16,12 +16,30 @@
|
||||||
|
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
|
||||||
|
const quint8 PENDING_STATE_NOTHING = 0;
|
||||||
|
const quint8 PENDING_STATE_TAKE = 1;
|
||||||
|
const quint8 PENDING_STATE_RELEASE = 2;
|
||||||
|
|
||||||
// static
|
// static
|
||||||
const int SimulationOwner::NUM_BYTES_ENCODED = NUM_BYTES_RFC4122_UUID + 1;
|
const int SimulationOwner::NUM_BYTES_ENCODED = NUM_BYTES_RFC4122_UUID + 1;
|
||||||
|
|
||||||
|
SimulationOwner::SimulationOwner() :
|
||||||
|
_id(),
|
||||||
|
_expiry(0),
|
||||||
|
_pendingTimestamp(0),
|
||||||
|
_priority(0),
|
||||||
|
_pendingPriority(0),
|
||||||
|
_pendingState(PENDING_STATE_NOTHING)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
SimulationOwner::SimulationOwner(const SimulationOwner& other)
|
SimulationOwner::SimulationOwner(const QUuid& id, quint8 priority) :
|
||||||
: _id(other._id), _priority(other._priority), _expiry(other._expiry) {
|
_id(id),
|
||||||
|
_expiry(0),
|
||||||
|
_pendingTimestamp(0),
|
||||||
|
_priority(priority),
|
||||||
|
_pendingPriority(0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray SimulationOwner::toByteArray() const {
|
QByteArray SimulationOwner::toByteArray() const {
|
||||||
|
@ -42,8 +60,11 @@ bool SimulationOwner::fromByteArray(const QByteArray& data) {
|
||||||
|
|
||||||
void SimulationOwner::clear() {
|
void SimulationOwner::clear() {
|
||||||
_id = QUuid();
|
_id = QUuid();
|
||||||
_priority = 0;
|
|
||||||
_expiry = 0;
|
_expiry = 0;
|
||||||
|
_pendingTimestamp = 0;
|
||||||
|
_priority = 0;
|
||||||
|
_pendingPriority = 0;
|
||||||
|
_pendingState = PENDING_STATE_NOTHING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimulationOwner::setPriority(quint8 priority) {
|
void SimulationOwner::setPriority(quint8 priority) {
|
||||||
|
@ -53,7 +74,6 @@ void SimulationOwner::setPriority(quint8 priority) {
|
||||||
void SimulationOwner::promotePriority(quint8 priority) {
|
void SimulationOwner::promotePriority(quint8 priority) {
|
||||||
if (priority > _priority) {
|
if (priority > _priority) {
|
||||||
_priority = priority;
|
_priority = priority;
|
||||||
updateExpiry();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,11 +101,31 @@ bool SimulationOwner::set(const SimulationOwner& owner) {
|
||||||
return setID(owner._id) || oldPriority != _priority;
|
return setID(owner._id) || oldPriority != _priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SimulationOwner::setPendingPriority(quint8 priority, const quint64& timestamp) {
|
||||||
|
_pendingPriority = priority;
|
||||||
|
_pendingTimestamp = timestamp;
|
||||||
|
_pendingState = (_pendingPriority == 0) ? PENDING_STATE_RELEASE : PENDING_STATE_TAKE;
|
||||||
|
}
|
||||||
|
|
||||||
void SimulationOwner::updateExpiry() {
|
void SimulationOwner::updateExpiry() {
|
||||||
const quint64 OWNERSHIP_LOCKOUT_EXPIRY = USECS_PER_SECOND / 5;
|
const quint64 OWNERSHIP_LOCKOUT_EXPIRY = USECS_PER_SECOND / 5;
|
||||||
_expiry = usecTimestampNow() + OWNERSHIP_LOCKOUT_EXPIRY;
|
_expiry = usecTimestampNow() + OWNERSHIP_LOCKOUT_EXPIRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SimulationOwner::pendingRelease(const quint64& timestamp) {
|
||||||
|
return _pendingPriority == 0 && _pendingState == PENDING_STATE_RELEASE && _pendingTimestamp >= timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimulationOwner::pendingTake(const quint64& timestamp) {
|
||||||
|
return _pendingPriority > 0 && _pendingState == PENDING_STATE_TAKE && _pendingTimestamp >= timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationOwner::clearCurrentOwner() {
|
||||||
|
_id = QUuid();
|
||||||
|
_expiry = 0;
|
||||||
|
_priority = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: eventually this code will be moved into unit tests
|
// NOTE: eventually this code will be moved into unit tests
|
||||||
// static debug
|
// static debug
|
||||||
void SimulationOwner::test() {
|
void SimulationOwner::test() {
|
||||||
|
|
|
@ -37,13 +37,12 @@ class SimulationOwner {
|
||||||
public:
|
public:
|
||||||
static const int NUM_BYTES_ENCODED;
|
static const int NUM_BYTES_ENCODED;
|
||||||
|
|
||||||
SimulationOwner() : _id(), _priority(0), _expiry(0) {}
|
SimulationOwner();
|
||||||
SimulationOwner(const QUuid& id, quint8 priority) : _id(id), _priority(priority), _expiry(0) {}
|
SimulationOwner(const QUuid& id, quint8 priority);
|
||||||
SimulationOwner(const SimulationOwner& other);
|
|
||||||
|
|
||||||
const QUuid& getID() const { return _id; }
|
const QUuid& getID() const { return _id; }
|
||||||
quint8 getPriority() const { return _priority; }
|
|
||||||
const quint64& getExpiry() const { return _expiry; }
|
const quint64& getExpiry() const { return _expiry; }
|
||||||
|
quint8 getPriority() const { return _priority; }
|
||||||
|
|
||||||
QByteArray toByteArray() const;
|
QByteArray toByteArray() const;
|
||||||
bool fromByteArray(const QByteArray& data);
|
bool fromByteArray(const QByteArray& data);
|
||||||
|
@ -57,6 +56,7 @@ public:
|
||||||
bool setID(const QUuid& id);
|
bool setID(const QUuid& id);
|
||||||
bool set(const QUuid& id, quint8 priority);
|
bool set(const QUuid& id, quint8 priority);
|
||||||
bool set(const SimulationOwner& owner);
|
bool set(const SimulationOwner& owner);
|
||||||
|
void setPendingPriority(quint8 priority, const quint64& timestamp);
|
||||||
|
|
||||||
bool isNull() const { return _id.isNull(); }
|
bool isNull() const { return _id.isNull(); }
|
||||||
bool matchesValidID(const QUuid& id) const { return _id == id && !_id.isNull(); }
|
bool matchesValidID(const QUuid& id) const { return _id == id && !_id.isNull(); }
|
||||||
|
@ -65,6 +65,10 @@ public:
|
||||||
|
|
||||||
bool hasExpired() const { return usecTimestampNow() > _expiry; }
|
bool hasExpired() const { return usecTimestampNow() > _expiry; }
|
||||||
|
|
||||||
|
bool pendingRelease(const quint64& timestamp); // return true if valid pending RELEASE
|
||||||
|
bool pendingTake(const quint64& timestamp); // return true if valid pending TAKE
|
||||||
|
void clearCurrentOwner();
|
||||||
|
|
||||||
bool operator>=(quint8 priority) const { return _priority >= priority; }
|
bool operator>=(quint8 priority) const { return _priority >= priority; }
|
||||||
bool operator==(const SimulationOwner& other) { return (_id == other._id && _priority == other._priority); }
|
bool operator==(const SimulationOwner& other) { return (_id == other._id && _priority == other._priority); }
|
||||||
|
|
||||||
|
@ -77,9 +81,12 @@ public:
|
||||||
static void test();
|
static void test();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUuid _id;
|
QUuid _id; // owner
|
||||||
quint8 _priority;
|
quint64 _expiry; // time when ownership can transition at equal priority
|
||||||
quint64 _expiry;
|
quint64 _pendingTimestamp; // time when pending update was set
|
||||||
|
quint8 _priority; // priority of current owner
|
||||||
|
quint8 _pendingPriority; // priority of pendingTake
|
||||||
|
quint8 _pendingState; // NOTHING, TAKE, or RELEASE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -334,7 +334,7 @@ public:
|
||||||
|
|
||||||
/// Returns the instructions for rendering of faces
|
/// Returns the instructions for rendering of faces
|
||||||
DrawingInstructions Instructions(PrimitiveType primitive) const {
|
DrawingInstructions Instructions(PrimitiveType primitive) const {
|
||||||
DrawingInstructions instr = this->MakeInstructions();
|
DrawingInstructions instr = MakeInstructions();
|
||||||
DrawOperation operation;
|
DrawOperation operation;
|
||||||
operation.method = DrawOperation::Method::DrawElements;
|
operation.method = DrawOperation::Method::DrawElements;
|
||||||
operation.mode = primitive;
|
operation.mode = primitive;
|
||||||
|
@ -342,8 +342,8 @@ public:
|
||||||
operation.count = _prim_count * 3;
|
operation.count = _prim_count * 3;
|
||||||
operation.restart_index = DrawOperation::NoRestartIndex();
|
operation.restart_index = DrawOperation::NoRestartIndex();
|
||||||
operation.phase = 0;
|
operation.phase = 0;
|
||||||
this->AddInstruction(instr, operation);
|
AddInstruction(instr, operation);
|
||||||
return std::move(instr);
|
return instr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the instructions for rendering of faces
|
/// Returns the instructions for rendering of faces
|
||||||
|
|
|
@ -28,7 +28,11 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning( disable : 4068 )
|
#pragma warning( disable : 4068 )
|
||||||
|
#elif defined(Q_OS_MAC)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wpessimizing-move"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <oglplus/gl.hpp>
|
#include <oglplus/gl.hpp>
|
||||||
|
|
||||||
#include <oglplus/all.hpp>
|
#include <oglplus/all.hpp>
|
||||||
|
@ -40,6 +44,8 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
#elif defined(Q_OS_MAC)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "NumericalConstants.h"
|
#include "NumericalConstants.h"
|
||||||
|
|
|
@ -394,10 +394,20 @@ const QString& NetworkMaterial::getTextureName(MapChannel channel) {
|
||||||
return NO_TEXTURE;
|
return NO_TEXTURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl NetworkMaterial::getTextureUrl(const QUrl& url, const FBXTexture& texture) {
|
QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const FBXTexture& texture) {
|
||||||
// If content is inline, cache it under the fbx file, not its url
|
if (texture.content.isEmpty()) {
|
||||||
const auto baseUrl = texture.content.isEmpty() ? url : QUrl(url.url() + "/");
|
// External file: search relative to the baseUrl, in case filename is relative
|
||||||
return baseUrl.resolved(QUrl(texture.filename));
|
return baseUrl.resolved(QUrl(texture.filename));
|
||||||
|
} else {
|
||||||
|
// Inlined file: cache under the fbx file to avoid namespace clashes
|
||||||
|
// NOTE: We cannot resolve the path because filename may be an absolute path
|
||||||
|
assert(texture.filename.size() > 0);
|
||||||
|
if (texture.filename.at(0) == '/') {
|
||||||
|
return baseUrl.toString() + texture.filename;
|
||||||
|
} else {
|
||||||
|
return baseUrl.toString() + '/' + texture.filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture,
|
model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture,
|
||||||
|
|
|
@ -66,6 +66,19 @@ JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, co
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject AccountManager::dataObjectFromResponse(QNetworkReply &requestReply) {
|
||||||
|
QJsonObject jsonObject = QJsonDocument::fromJson(requestReply.readAll()).object();
|
||||||
|
|
||||||
|
static const QString STATUS_KEY = "status";
|
||||||
|
static const QString DATA_KEY = "data";
|
||||||
|
|
||||||
|
if (jsonObject.contains(STATUS_KEY) && jsonObject[STATUS_KEY] == "success" && jsonObject.contains(DATA_KEY)) {
|
||||||
|
return jsonObject[DATA_KEY].toObject();
|
||||||
|
} else {
|
||||||
|
return QJsonObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AccountManager::AccountManager() :
|
AccountManager::AccountManager() :
|
||||||
_authURL(),
|
_authURL(),
|
||||||
_pendingCallbackMap()
|
_pendingCallbackMap()
|
||||||
|
@ -82,8 +95,6 @@ AccountManager::AccountManager() :
|
||||||
qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*");
|
qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*");
|
||||||
|
|
||||||
qRegisterMetaType<AccountManagerAuth::Type>();
|
qRegisterMetaType<AccountManagerAuth::Type>();
|
||||||
|
|
||||||
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash";
|
const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash";
|
||||||
|
@ -92,9 +103,6 @@ void AccountManager::logout() {
|
||||||
// a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file
|
// a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file
|
||||||
_accountInfo = DataServerAccountInfo();
|
_accountInfo = DataServerAccountInfo();
|
||||||
|
|
||||||
emit balanceChanged(0);
|
|
||||||
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
|
||||||
|
|
||||||
// remove this account from the account settings file
|
// remove this account from the account settings file
|
||||||
removeAccountFromFile();
|
removeAccountFromFile();
|
||||||
|
|
||||||
|
@ -103,21 +111,6 @@ void AccountManager::logout() {
|
||||||
emit usernameChanged(QString());
|
emit usernameChanged(QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountManager::updateBalance() {
|
|
||||||
if (hasValidAccessToken()) {
|
|
||||||
// ask our auth endpoint for our balance
|
|
||||||
JSONCallbackParameters callbackParameters;
|
|
||||||
callbackParameters.jsonCallbackReceiver = &_accountInfo;
|
|
||||||
callbackParameters.jsonCallbackMethod = "setBalanceFromJSON";
|
|
||||||
|
|
||||||
sendRequest("/api/v1/wallets/mine", AccountManagerAuth::Required, QNetworkAccessManager::GetOperation, callbackParameters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AccountManager::accountInfoBalanceChanged(qint64 newBalance) {
|
|
||||||
emit balanceChanged(newBalance);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString accountFileDir() {
|
QString accountFileDir() {
|
||||||
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ public:
|
||||||
|
|
||||||
DataServerAccountInfo& getAccountInfo() { return _accountInfo; }
|
DataServerAccountInfo& getAccountInfo() { return _accountInfo; }
|
||||||
|
|
||||||
|
static QJsonObject dataObjectFromResponse(QNetworkReply& requestReply);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void requestAccessToken(const QString& login, const QString& password);
|
void requestAccessToken(const QString& login, const QString& password);
|
||||||
|
|
||||||
|
@ -85,8 +87,6 @@ public slots:
|
||||||
void requestAccessTokenError(QNetworkReply::NetworkError error);
|
void requestAccessTokenError(QNetworkReply::NetworkError error);
|
||||||
void requestProfileError(QNetworkReply::NetworkError error);
|
void requestProfileError(QNetworkReply::NetworkError error);
|
||||||
void logout();
|
void logout();
|
||||||
void updateBalance();
|
|
||||||
void accountInfoBalanceChanged(qint64 newBalance);
|
|
||||||
void generateNewUserKeypair() { generateNewKeypair(); }
|
void generateNewUserKeypair() { generateNewKeypair(); }
|
||||||
void generateNewDomainKeypair(const QUuid& domainID) { generateNewKeypair(false, domainID); }
|
void generateNewDomainKeypair(const QUuid& domainID) { generateNewKeypair(false, domainID); }
|
||||||
|
|
||||||
|
@ -98,7 +98,6 @@ signals:
|
||||||
void loginComplete(const QUrl& authURL);
|
void loginComplete(const QUrl& authURL);
|
||||||
void loginFailed();
|
void loginFailed();
|
||||||
void logoutComplete();
|
void logoutComplete();
|
||||||
void balanceChanged(qint64 newBalance);
|
|
||||||
void newKeypair();
|
void newKeypair();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -31,8 +31,6 @@ DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherI
|
||||||
_xmppPassword = otherInfo._xmppPassword;
|
_xmppPassword = otherInfo._xmppPassword;
|
||||||
_discourseApiKey = otherInfo._discourseApiKey;
|
_discourseApiKey = otherInfo._discourseApiKey;
|
||||||
_walletID = otherInfo._walletID;
|
_walletID = otherInfo._walletID;
|
||||||
_balance = otherInfo._balance;
|
|
||||||
_hasBalance = otherInfo._hasBalance;
|
|
||||||
_privateKey = otherInfo._privateKey;
|
_privateKey = otherInfo._privateKey;
|
||||||
_domainID = otherInfo._domainID;
|
_domainID = otherInfo._domainID;
|
||||||
}
|
}
|
||||||
|
@ -51,8 +49,6 @@ void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) {
|
||||||
swap(_xmppPassword, otherInfo._xmppPassword);
|
swap(_xmppPassword, otherInfo._xmppPassword);
|
||||||
swap(_discourseApiKey, otherInfo._discourseApiKey);
|
swap(_discourseApiKey, otherInfo._discourseApiKey);
|
||||||
swap(_walletID, otherInfo._walletID);
|
swap(_walletID, otherInfo._walletID);
|
||||||
swap(_balance, otherInfo._balance);
|
|
||||||
swap(_hasBalance, otherInfo._hasBalance);
|
|
||||||
swap(_privateKey, otherInfo._privateKey);
|
swap(_privateKey, otherInfo._privateKey);
|
||||||
swap(_domainID, otherInfo._domainID);
|
swap(_domainID, otherInfo._domainID);
|
||||||
}
|
}
|
||||||
|
@ -87,23 +83,6 @@ void DataServerAccountInfo::setWalletID(const QUuid& walletID) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataServerAccountInfo::setBalance(qint64 balance) {
|
|
||||||
if (!_hasBalance || _balance != balance) {
|
|
||||||
_balance = balance;
|
|
||||||
_hasBalance = true;
|
|
||||||
|
|
||||||
emit balanceChanged(_balance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataServerAccountInfo::setBalanceFromJSON(QNetworkReply& requestReply) {
|
|
||||||
QJsonObject jsonObject = QJsonDocument::fromJson(requestReply.readAll()).object();
|
|
||||||
if (jsonObject["status"].toString() == "success") {
|
|
||||||
qint64 balanceInSatoshis = jsonObject["data"].toObject()["wallet"].toObject()["balance"].toDouble();
|
|
||||||
setBalance(balanceInSatoshis);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DataServerAccountInfo::hasProfile() const {
|
bool DataServerAccountInfo::hasProfile() const {
|
||||||
return _username.length() > 0;
|
return _username.length() > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,13 +43,6 @@ public:
|
||||||
const QUuid& getWalletID() const { return _walletID; }
|
const QUuid& getWalletID() const { return _walletID; }
|
||||||
void setWalletID(const QUuid& walletID);
|
void setWalletID(const QUuid& walletID);
|
||||||
|
|
||||||
qint64 getBalance() const { return _balance; }
|
|
||||||
float getBalanceInSatoshis() const { return _balance / SATOSHIS_PER_CREDIT; }
|
|
||||||
void setBalance(qint64 balance);
|
|
||||||
bool hasBalance() const { return _hasBalance; }
|
|
||||||
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
|
|
||||||
Q_INVOKABLE void setBalanceFromJSON(QNetworkReply& requestReply);
|
|
||||||
|
|
||||||
QByteArray getUsernameSignature(const QUuid& connectionToken);
|
QByteArray getUsernameSignature(const QUuid& connectionToken);
|
||||||
bool hasPrivateKey() const { return !_privateKey.isEmpty(); }
|
bool hasPrivateKey() const { return !_privateKey.isEmpty(); }
|
||||||
void setPrivateKey(const QByteArray& privateKey) { _privateKey = privateKey; }
|
void setPrivateKey(const QByteArray& privateKey) { _privateKey = privateKey; }
|
||||||
|
@ -65,8 +58,7 @@ public:
|
||||||
|
|
||||||
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
|
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
|
||||||
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
|
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
|
||||||
signals:
|
|
||||||
qint64 balanceChanged(qint64 newBalance);
|
|
||||||
private:
|
private:
|
||||||
void swap(DataServerAccountInfo& otherInfo);
|
void swap(DataServerAccountInfo& otherInfo);
|
||||||
|
|
||||||
|
@ -75,8 +67,6 @@ private:
|
||||||
QString _xmppPassword;
|
QString _xmppPassword;
|
||||||
QString _discourseApiKey;
|
QString _discourseApiKey;
|
||||||
QUuid _walletID;
|
QUuid _walletID;
|
||||||
qint64 _balance { 0 };
|
|
||||||
bool _hasBalance { false };
|
|
||||||
QUuid _domainID; // if this holds account info for a domain, this holds the ID of that domain
|
QUuid _domainID; // if this holds account info for a domain, this holds the ID of that domain
|
||||||
QByteArray _privateKey;
|
QByteArray _privateKey;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ public:
|
||||||
static UserActivityLogger& getInstance();
|
static UserActivityLogger& getInstance();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
bool isEnabled() { return !_disabled.get(); }
|
||||||
|
|
||||||
void disable(bool disable);
|
void disable(bool disable);
|
||||||
void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters());
|
void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters());
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,11 @@ Socket::Socket(QObject* parent) :
|
||||||
|
|
||||||
// start our timer for the synchronization time interval
|
// start our timer for the synchronization time interval
|
||||||
_synTimer->start(_synInterval);
|
_synTimer->start(_synInterval);
|
||||||
|
|
||||||
|
// make sure we hear about errors and state changes from the underlying socket
|
||||||
|
connect(&_udpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||||
|
this, SLOT(handleSocketError(QAbstractSocket::SocketError)));
|
||||||
|
connect(&_udpSocket, &QAbstractSocket::stateChanged, this, &Socket::handleStateChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Socket::bind(const QHostAddress& address, quint16 port) {
|
void Socket::bind(const QHostAddress& address, quint16 port) {
|
||||||
|
@ -406,3 +411,13 @@ std::vector<HifiSockAddr> Socket::getConnectionSockAddrs() {
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Socket::handleSocketError(QAbstractSocket::SocketError socketError) {
|
||||||
|
qCWarning(networking) << "udt::Socket error -" << socketError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) {
|
||||||
|
if (socketState != QAbstractSocket::BoundState) {
|
||||||
|
qCWarning(networking) << "udt::Socket state changed - state is now" << socketState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -87,6 +87,9 @@ private slots:
|
||||||
void readPendingDatagrams();
|
void readPendingDatagrams();
|
||||||
void rateControlSync();
|
void rateControlSync();
|
||||||
|
|
||||||
|
void handleSocketError(QAbstractSocket::SocketError socketError);
|
||||||
|
void handleStateChanged(QAbstractSocket::SocketState socketState);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setSystemBufferSizes();
|
void setSystemBufferSizes();
|
||||||
Connection& findOrCreateConnection(const HifiSockAddr& sockAddr);
|
Connection& findOrCreateConnection(const HifiSockAddr& sockAddr);
|
||||||
|
|
|
@ -519,12 +519,16 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
// but we remember we do still own it... and rely on the server to tell us we don't
|
// but we remember we do still own it... and rely on the server to tell us we don't
|
||||||
properties.clearSimulationOwner();
|
properties.clearSimulationOwner();
|
||||||
_outgoingPriority = 0;
|
_outgoingPriority = 0;
|
||||||
|
_entity->setPendingOwnershipPriority(_outgoingPriority, now);
|
||||||
} else if (Physics::getSessionUUID() != _entity->getSimulatorID()) {
|
} else if (Physics::getSessionUUID() != _entity->getSimulatorID()) {
|
||||||
// we don't own the simulation for this entity yet, but we're sending a bid for it
|
// we don't own the simulation for this entity yet, but we're sending a bid for it
|
||||||
properties.setSimulationOwner(Physics::getSessionUUID(),
|
quint8 bidPriority = glm::max<uint8_t>(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY);
|
||||||
glm::max<uint8_t>(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY));
|
properties.setSimulationOwner(Physics::getSessionUUID(), bidPriority);
|
||||||
_nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS;
|
_nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS;
|
||||||
_outgoingPriority = 0; // reset outgoing priority whenever we bid
|
// copy _outgoingPriority into pendingPriority...
|
||||||
|
_entity->setPendingOwnershipPriority(_outgoingPriority, now);
|
||||||
|
// ...then reset _outgoingPriority in preparation for the next frame
|
||||||
|
_outgoingPriority = 0;
|
||||||
} else if (_outgoingPriority != _entity->getSimulationPriority()) {
|
} else if (_outgoingPriority != _entity->getSimulationPriority()) {
|
||||||
// we own the simulation but our desired priority has changed
|
// we own the simulation but our desired priority has changed
|
||||||
if (_outgoingPriority == 0) {
|
if (_outgoingPriority == 0) {
|
||||||
|
@ -534,6 +538,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
// we just need to change the priority
|
// we just need to change the priority
|
||||||
properties.setSimulationOwner(Physics::getSessionUUID(), _outgoingPriority);
|
properties.setSimulationOwner(Physics::getSessionUUID(), _outgoingPriority);
|
||||||
}
|
}
|
||||||
|
_entity->setPendingOwnershipPriority(_outgoingPriority, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemID id(_entity->getID());
|
EntityItemID id(_entity->getID());
|
||||||
|
|
|
@ -225,9 +225,7 @@ void PhysicsEngine::removeContacts(ObjectMotionState* motionState) {
|
||||||
ContactMap::iterator contactItr = _contactMap.begin();
|
ContactMap::iterator contactItr = _contactMap.begin();
|
||||||
while (contactItr != _contactMap.end()) {
|
while (contactItr != _contactMap.end()) {
|
||||||
if (contactItr->first._a == motionState || contactItr->first._b == motionState) {
|
if (contactItr->first._a == motionState || contactItr->first._b == motionState) {
|
||||||
ContactMap::iterator iterToDelete = contactItr;
|
contactItr = _contactMap.erase(contactItr);
|
||||||
++contactItr;
|
|
||||||
_contactMap.erase(iterToDelete);
|
|
||||||
} else {
|
} else {
|
||||||
++contactItr;
|
++contactItr;
|
||||||
}
|
}
|
||||||
|
@ -386,9 +384,7 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == CONTACT_EVENT_TYPE_END) {
|
if (type == CONTACT_EVENT_TYPE_END) {
|
||||||
ContactMap::iterator iterToDelete = contactItr;
|
contactItr = _contactMap.erase(contactItr);
|
||||||
++contactItr;
|
|
||||||
_contactMap.erase(iterToDelete);
|
|
||||||
} else {
|
} else {
|
||||||
++contactItr;
|
++contactItr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons
|
||||||
} else if (key.hasOwnPipeline()) {
|
} else if (key.hasOwnPipeline()) {
|
||||||
item.render(args);
|
item.render(args);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Item could not be rendered: invalid key ?" << key;
|
qDebug() << "Item could not be rendered with invalid key" << key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ void render::renderStateSortShapes(const SceneContextPointer& sceneContext, cons
|
||||||
} else if (key.hasOwnPipeline()) {
|
} else if (key.hasOwnPipeline()) {
|
||||||
ownPipelineBucket.push_back(item);
|
ownPipelineBucket.push_back(item);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Item could not be rendered: invalid key ?" << key;
|
qDebug() << "Item could not be rendered with invalid key" << key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,11 @@ const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Ke
|
||||||
|
|
||||||
const auto& pipelineIterator = _pipelineMap.find(key);
|
const auto& pipelineIterator = _pipelineMap.find(key);
|
||||||
if (pipelineIterator == _pipelineMap.end()) {
|
if (pipelineIterator == _pipelineMap.end()) {
|
||||||
qDebug() << "Couldn't find a pipeline from ShapeKey ?" << key;
|
// The first time we can't find a pipeline, we should log it
|
||||||
|
if (_missingKeys.find(key) == _missingKeys.end()) {
|
||||||
|
_missingKeys.insert(key);
|
||||||
|
qDebug() << "Couldn't find a pipeline for" << key;
|
||||||
|
}
|
||||||
return PipelinePointer(nullptr);
|
return PipelinePointer(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef hifi_render_ShapePipeline_h
|
#ifndef hifi_render_ShapePipeline_h
|
||||||
#define hifi_render_ShapePipeline_h
|
#define hifi_render_ShapePipeline_h
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
#include <RenderArgs.h>
|
#include <RenderArgs.h>
|
||||||
|
|
||||||
|
@ -147,7 +149,7 @@ public:
|
||||||
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
|
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
|
||||||
bool isValid() const { return !_flags[INVALID]; }
|
bool isValid() const { return !_flags[INVALID]; }
|
||||||
|
|
||||||
// Hasher for use in unordered_maps
|
// Comparator for use in stl containers
|
||||||
class Hash {
|
class Hash {
|
||||||
public:
|
public:
|
||||||
size_t operator() (const ShapeKey& key) const {
|
size_t operator() (const ShapeKey& key) const {
|
||||||
|
@ -155,7 +157,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Comparator for use in unordered_maps
|
// Comparator for use in stl containers
|
||||||
class KeyEqual {
|
class KeyEqual {
|
||||||
public:
|
public:
|
||||||
bool operator()(const ShapeKey& lhs, const ShapeKey& rhs) const { return lhs._flags == rhs._flags; }
|
bool operator()(const ShapeKey& lhs, const ShapeKey& rhs) const { return lhs._flags == rhs._flags; }
|
||||||
|
@ -271,7 +273,11 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void addPipelineHelper(const Filter& filter, Key key, int bit, const PipelinePointer& pipeline);
|
void addPipelineHelper(const Filter& filter, Key key, int bit, const PipelinePointer& pipeline);
|
||||||
PipelineMap _pipelineMap;
|
PipelineMap _pipelineMap;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable std::unordered_set<Key, Key::Hash, Key::KeyEqual> _missingKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ShapePlumberPointer = std::shared_ptr<ShapePlumber>;
|
using ShapePlumberPointer = std::shared_ptr<ShapePlumber>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,12 +146,15 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
|
||||||
|
|
||||||
ScriptEngine::~ScriptEngine() {
|
ScriptEngine::~ScriptEngine() {
|
||||||
qCDebug(scriptengine) << "Script Engine shutting down (destructor) for script:" << getFilename();
|
qCDebug(scriptengine) << "Script Engine shutting down (destructor) for script:" << getFilename();
|
||||||
|
|
||||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||||
if (scriptEngines) {
|
if (scriptEngines) {
|
||||||
scriptEngines->removeScriptEngine(this);
|
scriptEngines->removeScriptEngine(this);
|
||||||
} else {
|
} else {
|
||||||
qCWarning(scriptengine) << "Script destroyed after ScriptEngines!";
|
qCWarning(scriptengine) << "Script destroyed after ScriptEngines!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitTillDoneRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::disconnectNonEssentialSignals() {
|
void ScriptEngine::disconnectNonEssentialSignals() {
|
||||||
|
@ -172,7 +175,7 @@ void ScriptEngine::runInThread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_isThreaded = true;
|
_isThreaded = true;
|
||||||
QThread* workerThread = new QThread(this); // thread is not owned, so we need to manage the delete
|
QThread* workerThread = new QThread();
|
||||||
QString scriptEngineName = QString("Script Thread:") + getFilename();
|
QString scriptEngineName = QString("Script Thread:") + getFilename();
|
||||||
workerThread->setObjectName(scriptEngineName);
|
workerThread->setObjectName(scriptEngineName);
|
||||||
|
|
||||||
|
@ -194,35 +197,35 @@ void ScriptEngine::runInThread() {
|
||||||
|
|
||||||
void ScriptEngine::waitTillDoneRunning() {
|
void ScriptEngine::waitTillDoneRunning() {
|
||||||
// If the script never started running or finished running before we got here, we don't need to wait for it
|
// If the script never started running or finished running before we got here, we don't need to wait for it
|
||||||
if (_isRunning && _isThreaded) {
|
auto workerThread = thread();
|
||||||
|
if (_isThreaded && workerThread) {
|
||||||
// NOTE: waitTillDoneRunning() will be called on the main Application thread, inside of stopAllScripts()
|
|
||||||
// we want the application thread to continue to process events, because the scripts will likely need to
|
|
||||||
// marshall messages across to the main thread. For example if they access Settings or Menu in any of their
|
|
||||||
// shutdown code.
|
|
||||||
QString scriptName = getFilename();
|
QString scriptName = getFilename();
|
||||||
|
|
||||||
auto startedWaiting = usecTimestampNow();
|
auto startedWaiting = usecTimestampNow();
|
||||||
while (thread()->isRunning()) {
|
|
||||||
// process events for the main application thread, allowing invokeMethod calls to pass between threads
|
|
||||||
QCoreApplication::processEvents();
|
|
||||||
auto stillWaiting = usecTimestampNow();
|
|
||||||
auto elapsedUsecs = stillWaiting - startedWaiting;
|
|
||||||
|
|
||||||
// if we've been waiting a second or more, then tell the script engine to stop evaluating
|
while (workerThread->isRunning()) {
|
||||||
|
// NOTE: This will be called on the main application thread from stopAllScripts.
|
||||||
|
// The application thread will need to continue to process events, because
|
||||||
|
// the scripts will likely need to marshall messages across to the main thread, e.g.
|
||||||
|
// if they access Settings or Menu in any of their shutdown code. So:
|
||||||
|
// Process events for the main application thread, allowing invokeMethod calls to pass between threads.
|
||||||
|
QCoreApplication::processEvents(); // thread-safe :)
|
||||||
|
|
||||||
|
// If we've been waiting a second or more, then tell the script engine to stop evaluating
|
||||||
static const auto MAX_SCRIPT_EVALUATION_TIME = USECS_PER_SECOND;
|
static const auto MAX_SCRIPT_EVALUATION_TIME = USECS_PER_SECOND;
|
||||||
static const auto WAITING_TOO_LONG = MAX_SCRIPT_EVALUATION_TIME * 5;
|
auto elapsedUsecs = usecTimestampNow() - startedWaiting;
|
||||||
|
if (elapsedUsecs > MAX_SCRIPT_EVALUATION_TIME) {
|
||||||
// if we've been waiting for more than 5 seconds then we should be more aggessive about stopping
|
qCDebug(scriptengine) <<
|
||||||
if (elapsedUsecs > WAITING_TOO_LONG) {
|
"Script " << scriptName << " has been running too long [" << elapsedUsecs << " usecs] quitting.";
|
||||||
qCDebug(scriptengine) << "Script " << scriptName << " has been running too long [" << elapsedUsecs << " usecs] quitting.";
|
abortEvaluation(); // to allow the thread to quit
|
||||||
thread()->quit();
|
workerThread->quit();
|
||||||
break;
|
break;
|
||||||
} else if (elapsedUsecs > MAX_SCRIPT_EVALUATION_TIME) {
|
|
||||||
qCDebug(scriptengine) << "Script " << scriptName << " has been running too long [" << elapsedUsecs << " usecs] aborting evaluation.";
|
|
||||||
QMetaObject::invokeMethod(this, "abortEvaluation");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid a pure busy wait
|
||||||
|
QThread::yieldCurrentThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workerThread->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ const float METERS_PER_CENTIMETER = 0.01f;
|
||||||
const float METERS_PER_MILLIMETER = 0.001f;
|
const float METERS_PER_MILLIMETER = 0.001f;
|
||||||
const float MILLIMETERS_PER_METER = 1000.0f;
|
const float MILLIMETERS_PER_METER = 1000.0f;
|
||||||
const quint64 NSECS_PER_USEC = 1000;
|
const quint64 NSECS_PER_USEC = 1000;
|
||||||
|
const quint64 NSECS_PER_MSEC = 1000000;
|
||||||
const quint64 USECS_PER_MSEC = 1000;
|
const quint64 USECS_PER_MSEC = 1000;
|
||||||
const quint64 MSECS_PER_SECOND = 1000;
|
const quint64 MSECS_PER_SECOND = 1000;
|
||||||
const quint64 USECS_PER_SECOND = USECS_PER_MSEC * MSECS_PER_SECOND;
|
const quint64 USECS_PER_SECOND = USECS_PER_MSEC * MSECS_PER_SECOND;
|
||||||
|
|
|
@ -456,16 +456,41 @@ void printVoxelCode(unsigned char* voxelCode) {
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void usleep(int waitTime) {
|
void usleep(int waitTime) {
|
||||||
const quint64 BUSY_LOOP_USECS = 2000;
|
// Use QueryPerformanceCounter for least overhead
|
||||||
quint64 compTime = waitTime + usecTimestampNow();
|
LARGE_INTEGER now; // ticks
|
||||||
quint64 compTimeSleep = compTime - BUSY_LOOP_USECS;
|
QueryPerformanceCounter(&now);
|
||||||
while (true) {
|
|
||||||
if (usecTimestampNow() < compTimeSleep) {
|
static int64_t ticksPerSec = 0;
|
||||||
QThread::msleep(1);
|
if (ticksPerSec == 0) {
|
||||||
|
LARGE_INTEGER frequency;
|
||||||
|
QueryPerformanceFrequency(&frequency);
|
||||||
|
ticksPerSec = frequency.QuadPart;
|
||||||
}
|
}
|
||||||
if (usecTimestampNow() >= compTime) {
|
|
||||||
|
// order ops to avoid loss in precision
|
||||||
|
int64_t waitTicks = (ticksPerSec * waitTime) / USECS_PER_SECOND;
|
||||||
|
int64_t sleepTicks = now.QuadPart + waitTicks;
|
||||||
|
|
||||||
|
// Busy wait with sleep/yield where possible
|
||||||
|
while (true) {
|
||||||
|
QueryPerformanceCounter(&now);
|
||||||
|
if (now.QuadPart >= sleepTicks) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sleep if we have at least 1ms to spare
|
||||||
|
const int64_t MIN_SLEEP_USECS = 1000;
|
||||||
|
// msleep is allowed to overshoot, so give it a 100us berth
|
||||||
|
const int64_t MIN_SLEEP_USECS_BERTH = 100;
|
||||||
|
// order ops to avoid loss in precision
|
||||||
|
int64_t sleepFor = ((sleepTicks - now.QuadPart) * USECS_PER_SECOND) / ticksPerSec - MIN_SLEEP_USECS_BERTH;
|
||||||
|
if (sleepFor > MIN_SLEEP_USECS) {
|
||||||
|
Sleep((DWORD)(sleepFor / USECS_PER_MSEC));
|
||||||
|
// Yield otherwise
|
||||||
|
} else {
|
||||||
|
// Use Qt to delegate, as SwitchToThread is only supported starting with XP
|
||||||
|
QThread::yieldCurrentThread();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
// 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
|
||||||
//
|
//
|
||||||
|
|
||||||
Script.load("system/away.js");
|
|
||||||
Script.load("system/progress.js");
|
Script.load("system/progress.js");
|
||||||
Script.load("system/edit.js");
|
Script.load("system/away.js");
|
||||||
|
Script.load("system/users.js");
|
||||||
Script.load("system/examples.js");
|
Script.load("system/examples.js");
|
||||||
|
Script.load("system/edit.js");
|
||||||
Script.load("system/selectAudioDevice.js");
|
Script.load("system/selectAudioDevice.js");
|
||||||
Script.load("system/notifications.js");
|
Script.load("system/notifications.js");
|
||||||
Script.load("system/controllers/handControllerGrab.js");
|
Script.load("system/controllers/handControllerGrab.js");
|
||||||
|
|
|
@ -222,7 +222,7 @@ var usersWindow = (function() {
|
||||||
|
|
||||||
var baseURL = Script.resolvePath("assets/images/tools/");
|
var baseURL = Script.resolvePath("assets/images/tools/");
|
||||||
|
|
||||||
var WINDOW_WIDTH = 160,
|
var WINDOW_WIDTH = 260,
|
||||||
WINDOW_MARGIN = 12,
|
WINDOW_MARGIN = 12,
|
||||||
WINDOW_BASE_MARGIN = 6, // A little less is needed in order look correct
|
WINDOW_BASE_MARGIN = 6, // A little less is needed in order look correct
|
||||||
WINDOW_FONT = {
|
WINDOW_FONT = {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var version = 12;
|
var version = 13;
|
||||||
|
|
||||||
var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/";
|
var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/";
|
||||||
var button;
|
var button;
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
var buttonPadding = 10;
|
var buttonPadding = 10;
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
var buttonPositionX = (offset + 1) * (buttonWidth + buttonPadding) + (windowDimensions.x / 2) - (buttonWidth * 3 + buttonPadding * 2.5);
|
var buttonPositionX = (offset + 1) * (buttonWidth + buttonPadding) + (windowDimensions.x / 2) - (buttonWidth * 3 + buttonPadding * 2.5);
|
||||||
var buttonPositionY = (windowDimensions.y - buttonHeight) - 50;
|
var buttonPositionY = (windowDimensions.y - buttonHeight) - 150;
|
||||||
button = Overlays.addOverlay("image", {
|
button = Overlays.addOverlay("image", {
|
||||||
x: buttonPositionX,
|
x: buttonPositionX,
|
||||||
y: buttonPositionY,
|
y: buttonPositionY,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var version = 12;
|
var version = 13;
|
||||||
|
|
||||||
var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/";
|
var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/";
|
||||||
var button;
|
var button;
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
var buttonPadding = 10;
|
var buttonPadding = 10;
|
||||||
var offset = 3;
|
var offset = 3;
|
||||||
var buttonPositionX = (offset + 1) * (buttonWidth + buttonPadding) + (windowDimensions.x / 2) - (buttonWidth * 3 + buttonPadding * 2.5);
|
var buttonPositionX = (offset + 1) * (buttonWidth + buttonPadding) + (windowDimensions.x / 2) - (buttonWidth * 3 + buttonPadding * 2.5);
|
||||||
var buttonPositionY = (windowDimensions.y - buttonHeight) - 50;
|
var buttonPositionY = (windowDimensions.y - buttonHeight) - 150;
|
||||||
button = Overlays.addOverlay("image", {
|
button = Overlays.addOverlay("image", {
|
||||||
x: buttonPositionX,
|
x: buttonPositionX,
|
||||||
y: buttonPositionY,
|
y: buttonPositionY,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var version = 12;
|
var version = 13;
|
||||||
|
|
||||||
var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/";
|
var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/";
|
||||||
var button;
|
var button;
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
var buttonPadding = 10;
|
var buttonPadding = 10;
|
||||||
var offset = 1;
|
var offset = 1;
|
||||||
var buttonPositionX = (offset + 1) * (buttonWidth + buttonPadding) + (windowDimensions.x / 2) - (buttonWidth * 3 + buttonPadding * 2.5);
|
var buttonPositionX = (offset + 1) * (buttonWidth + buttonPadding) + (windowDimensions.x / 2) - (buttonWidth * 3 + buttonPadding * 2.5);
|
||||||
var buttonPositionY = (windowDimensions.y - buttonHeight) - 50;
|
var buttonPositionY = (windowDimensions.y - buttonHeight) - 150;
|
||||||
button = Overlays.addOverlay("image", {
|
button = Overlays.addOverlay("image", {
|
||||||
x: buttonPositionX,
|
x: buttonPositionX,
|
||||||
y: buttonPositionY,
|
y: buttonPositionY,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//
|
//
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var version = 12;
|
var version = 13;
|
||||||
|
|
||||||
var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/";
|
var baseURL = "https://hifi-production.s3.amazonaws.com/DomainContent/CellScience/";
|
||||||
var button;
|
var button;
|
||||||
|
@ -26,9 +26,9 @@
|
||||||
z: 3000
|
z: 3000
|
||||||
},
|
},
|
||||||
target: {
|
target: {
|
||||||
x: 3276.6,
|
x: 13500,
|
||||||
y: 13703.3,
|
y: 3000,
|
||||||
z: 4405.6
|
z: 3000
|
||||||
},
|
},
|
||||||
preload: function(entityId) {
|
preload: function(entityId) {
|
||||||
print('CELL PRELOAD RIBOSOME 1')
|
print('CELL PRELOAD RIBOSOME 1')
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
var buttonPadding = 10;
|
var buttonPadding = 10;
|
||||||
var offset = 2;
|
var offset = 2;
|
||||||
var buttonPositionX = (offset + 1) * (buttonWidth + buttonPadding) + (windowDimensions.x / 2) - (buttonWidth * 3 + buttonPadding * 2.5);
|
var buttonPositionX = (offset + 1) * (buttonWidth + buttonPadding) + (windowDimensions.x / 2) - (buttonWidth * 3 + buttonPadding * 2.5);
|
||||||
var buttonPositionY = (windowDimensions.y - buttonHeight) - 50;
|
var buttonPositionY = (windowDimensions.y - buttonHeight) - 150;
|
||||||
button = Overlays.addOverlay("image", {
|
button = Overlays.addOverlay("image", {
|
||||||
x: buttonPositionX,
|
x: buttonPositionX,
|
||||||
y: buttonPositionY,
|
y: buttonPositionY,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// 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
|
||||||
//
|
//
|
||||||
|
|
||||||
var version = 1217;
|
var version = 1219;
|
||||||
|
|
||||||
var WORLD_OFFSET = {
|
var WORLD_OFFSET = {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
|
|
@ -25,26 +25,41 @@
|
||||||
x: 1.8838,
|
x: 1.8838,
|
||||||
y: 1.7865,
|
y: 1.7865,
|
||||||
z: 0.2955
|
z: 0.2955
|
||||||
}
|
};
|
||||||
|
|
||||||
var ROBOT_DIMENSIONS = {
|
var ROBOT_DIMENSIONS = {
|
||||||
//robot
|
//robot
|
||||||
x: 1.4439,
|
x: 1.4439,
|
||||||
y: 0.6224,
|
y: 0.6224,
|
||||||
z: 0.4998
|
z: 0.4998
|
||||||
}
|
};
|
||||||
|
|
||||||
var WILL_DIMENSIONS = {
|
var WILL_DIMENSIONS = {
|
||||||
x: 1.6326,
|
x: 1.6326,
|
||||||
y: 1.6764,
|
y: 1.6764,
|
||||||
z: 0.2606
|
z: 0.2606
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var PRISCILLA_DIMENSIONS = {
|
||||||
|
//priscilla
|
||||||
|
x: 1.6448,
|
||||||
|
y: 1.6657,
|
||||||
|
z: 0.3078
|
||||||
|
};
|
||||||
|
|
||||||
|
var MATTHEW_DIMENSIONS = {
|
||||||
|
//matthew
|
||||||
|
x: 1.8722,
|
||||||
|
y: 1.8197,
|
||||||
|
z: 0.3666
|
||||||
|
};
|
||||||
|
|
||||||
var _this;
|
var _this;
|
||||||
|
|
||||||
function Transformer() {
|
function Transformer() {
|
||||||
_this = this;
|
_this = this;
|
||||||
return this;
|
return this;
|
||||||
}
|
};
|
||||||
|
|
||||||
Transformer.prototype = {
|
Transformer.prototype = {
|
||||||
locked: false,
|
locked: false,
|
||||||
|
@ -54,33 +69,45 @@
|
||||||
print('PRELOAD TRANSFORMER SCRIPT')
|
print('PRELOAD TRANSFORMER SCRIPT')
|
||||||
this.entityID = entityID;
|
this.entityID = entityID;
|
||||||
this.initialProperties = Entities.getEntityProperties(entityID);
|
this.initialProperties = Entities.getEntityProperties(entityID);
|
||||||
// this.transformationSound = SoundCache.getSound(TRANSFORMATION_SOUND_URL);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
collisionWithEntity: function(myID, otherID, collisionInfo) {
|
collisionWithEntity: function(myID, otherID, collisionInfo) {
|
||||||
var otherProps = Entities.getEntityProperties(otherID);
|
var otherProps = Entities.getEntityProperties(otherID);
|
||||||
|
|
||||||
if (otherProps.name === "hifi-home-dressing-room-transformer-collider" && _this.locked === false) {
|
if (otherProps.name === "hifi-home-dressing-room-transformer-collider" && _this.locked === false) {
|
||||||
print('UNLOCKED TRANSFORMER COLLIDED WITH BASE!! THE AVATAR WHO SIMULATED THIS COLLISION IS:: ' + MyAvatar.sessionUUID);
|
|
||||||
_this.locked = true;
|
_this.locked = true;
|
||||||
_this.findRotatorBlock();
|
_this.findRotatorBlock();
|
||||||
} else {
|
} else {
|
||||||
|
var transformerProps = Entities.getEntityProperties(_this.entityID, ["rotation", "position"]);
|
||||||
|
|
||||||
|
var eulerRotation = Quat.safeEulerAngles(transformerProps.rotation);
|
||||||
|
eulerRotation.x = 0;
|
||||||
|
eulerRotation.z = 0;
|
||||||
|
var newRotation = Quat.fromVec3Degrees(eulerRotation);
|
||||||
|
|
||||||
|
//we zero out the velocity and angular velocity so the cow doesn't change position or spin
|
||||||
|
Entities.editEntity(_this.entityID, {
|
||||||
|
rotation: newRotation,
|
||||||
|
velocity: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
angularVelocity: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// playTransformationSound: function(position) {
|
|
||||||
// print('transformer should play a sound')
|
|
||||||
// Audio.playSound(_this.transformationSound, {
|
|
||||||
// position: position,
|
|
||||||
// volume: 0.5
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
|
|
||||||
findRotatorBlock: function() {
|
findRotatorBlock: function() {
|
||||||
print('transformer should find rotator block')
|
|
||||||
var myProps = Entities.getEntityProperties(_this.entityID);
|
var myProps = Entities.getEntityProperties(_this.entityID);
|
||||||
var results = Entities.findEntities(myProps.position, 10);
|
var results = Entities.findEntities(myProps.position, 10);
|
||||||
|
|
||||||
results.forEach(function(result) {
|
results.forEach(function(result) {
|
||||||
var resultProps = Entities.getEntityProperties(result);
|
var resultProps = Entities.getEntityProperties(result);
|
||||||
if (resultProps.name === "hifi-home-dressing-room-rotator-block") {
|
if (resultProps.name === "hifi-home-dressing-room-rotator-block") {
|
||||||
|
@ -89,14 +116,13 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
removeCurrentBigVersion: function(rotatorBlock) {
|
removeCurrentBigVersion: function(rotatorBlock) {
|
||||||
print('transformer should remove big version')
|
|
||||||
var blacklistKey = 'Hifi-Hand-RayPick-Blacklist';
|
var blacklistKey = 'Hifi-Hand-RayPick-Blacklist';
|
||||||
var myProps = Entities.getEntityProperties(_this.entityID);
|
var myProps = Entities.getEntityProperties(_this.entityID);
|
||||||
var results = Entities.findEntities(myProps.position, 10);
|
var results = Entities.findEntities(myProps.position, 10);
|
||||||
|
|
||||||
results.forEach(function(result) {
|
results.forEach(function(result) {
|
||||||
var resultProps = Entities.getEntityProperties(result);
|
var resultProps = Entities.getEntityProperties(result);
|
||||||
if (resultProps.name === "hifi-home-dressing-room-big-transformer") {
|
if (resultProps.name === "hifi-home-dressing-room-big-transformer") {
|
||||||
|
@ -110,31 +136,35 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_this.createBigVersion();
|
_this.createBigVersion();
|
||||||
},
|
},
|
||||||
|
|
||||||
createBigVersion: function() {
|
createBigVersion: function() {
|
||||||
var smallProps = Entities.getEntityProperties(_this.entityID);
|
var smallProps = Entities.getEntityProperties(_this.entityID);
|
||||||
print('transformer should create big version!!' + smallProps.modelURL);
|
|
||||||
print('transformer has rotatorBlock??' + _this.rotatorBlock);
|
|
||||||
var rotatorProps = Entities.getEntityProperties(_this.rotatorBlock);
|
var rotatorProps = Entities.getEntityProperties(_this.rotatorBlock);
|
||||||
|
|
||||||
var dimensions;
|
var dimensions;
|
||||||
if (smallProps.modelURL.indexOf('will') > -1) {
|
if (smallProps.modelURL.indexOf('will') > -1) {
|
||||||
print('TRANSFORMER IS WILL')
|
// print('TRANSFORMER IS WILL');
|
||||||
dimensions = WILL_DIMENSIONS;
|
dimensions = WILL_DIMENSIONS;
|
||||||
} else if (smallProps.modelURL.indexOf('being_of_light') > -1) {
|
} else if (smallProps.modelURL.indexOf('being_of_light') > -1) {
|
||||||
print('TRANSFORMER IS BEING OF LIGHT')
|
// print('TRANSFORMER IS BEING OF LIGHT');
|
||||||
|
|
||||||
dimensions = BEING_OF_LIGHT_DIMENSIONS;
|
dimensions = BEING_OF_LIGHT_DIMENSIONS;
|
||||||
} else if (smallProps.modelURL.indexOf('stylized_female') > -1) {
|
} else if (smallProps.modelURL.indexOf('stylized_female') > -1) {
|
||||||
print('TRANSFORMER IS ARTEMIS')
|
// print('TRANSFORMER IS ARTEMIS');
|
||||||
dimensions = STYLIZED_FEMALE_DIMENSIONS;
|
dimensions = STYLIZED_FEMALE_DIMENSIONS;
|
||||||
} else if (smallProps.modelURL.indexOf('simple_robot') > -1) {
|
} else if (smallProps.modelURL.indexOf('simple_robot') > -1) {
|
||||||
print('TRANSFORMER IS A ROBOT')
|
// print('TRANSFORMER IS A ROBOT');
|
||||||
dimensions = ROBOT_DIMENSIONS;
|
dimensions = ROBOT_DIMENSIONS;
|
||||||
|
} else if (smallProps.modelURL.indexOf('priscilla') > -1) {
|
||||||
|
// print('TRANSFORMER IS PRISCILLA');
|
||||||
|
dimensions = PRISCILLA_DIMENSIONS;
|
||||||
|
} else if (smallProps.modelURL.indexOf('matthew') > -1) {
|
||||||
|
// print('TRANSFORMER IS MATTHEW');
|
||||||
|
dimensions = MATTHEW_DIMENSIONS;
|
||||||
} else {
|
} else {
|
||||||
print('TRANSFORMER IS SOME OTHER');
|
// print('TRANSFORMER IS SOME OTHER');
|
||||||
dimensions = smallProps.naturalDimensions;
|
dimensions = smallProps.naturalDimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,14 +184,13 @@
|
||||||
'reset': true
|
'reset': true
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
}
|
};
|
||||||
|
|
||||||
if (bigVersionProps.modelURL.indexOf('simple_robot') > -1) {
|
if (bigVersionProps.modelURL.indexOf('simple_robot') > -1) {
|
||||||
bigVersionProps.position.y += 0.5;
|
bigVersionProps.position.y += 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bigVersion = Entities.addEntity(bigVersionProps);
|
var bigVersion = Entities.addEntity(bigVersionProps);
|
||||||
print('transformer created big version: ' + bigVersion);
|
|
||||||
|
|
||||||
var blacklistKey = 'Hifi-Hand-RayPick-Blacklist';
|
var blacklistKey = 'Hifi-Hand-RayPick-Blacklist';
|
||||||
Messages.sendMessage(blacklistKey, JSON.stringify({
|
Messages.sendMessage(blacklistKey, JSON.stringify({
|
||||||
|
@ -173,12 +202,10 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
putTransformerOnRotatorBlock: function(blockPosition) {
|
putTransformerOnRotatorBlock: function(blockPosition) {
|
||||||
print('transformer should get set on rotator block')
|
return blockPosition;
|
||||||
return blockPosition
|
|
||||||
},
|
},
|
||||||
|
|
||||||
putNewVersionOnShelf: function() {
|
putNewVersionOnShelf: function() {
|
||||||
print('transformer should out a new version of itself on the shelf')
|
|
||||||
var littleVersionProps = Entities.getEntityProperties(_this.entityID);
|
var littleVersionProps = Entities.getEntityProperties(_this.entityID);
|
||||||
delete littleVersionProps.id;
|
delete littleVersionProps.id;
|
||||||
delete littleVersionProps.created;
|
delete littleVersionProps.created;
|
||||||
|
@ -189,23 +216,24 @@
|
||||||
delete littleVersionProps.localPosition;
|
delete littleVersionProps.localPosition;
|
||||||
delete littleVersionProps.localRotation;
|
delete littleVersionProps.localRotation;
|
||||||
delete littleVersionProps.naturalPosition;
|
delete littleVersionProps.naturalPosition;
|
||||||
// delete littleVersionProps.script;
|
|
||||||
littleVersionProps.gravity = {
|
littleVersionProps.gravity = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: -10,
|
y: -10,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
var userData = JSON.parse(littleVersionProps.userData);
|
var userData = JSON.parse(littleVersionProps.userData);
|
||||||
|
|
||||||
var basePosition = userData["hifiHomeTransformerKey"].basePosition;
|
var basePosition = userData["hifiHomeTransformerKey"].basePosition;
|
||||||
var baseRotation = userData["hifiHomeTransformerKey"].baseRotation;
|
var baseRotation = userData["hifiHomeTransformerKey"].baseRotation;
|
||||||
|
|
||||||
littleVersionProps.position = basePosition;
|
littleVersionProps.position = basePosition;
|
||||||
littleVersionProps.rotation = baseRotation;
|
littleVersionProps.rotation = baseRotation;
|
||||||
var littleTransformer = Entities.addEntity(littleVersionProps);
|
var littleTransformer = Entities.addEntity(littleVersionProps);
|
||||||
|
|
||||||
_this.removeSelf();
|
_this.removeSelf();
|
||||||
},
|
},
|
||||||
|
|
||||||
removeSelf: function() {
|
removeSelf: function() {
|
||||||
print('transformer should remove itself')
|
|
||||||
var success = Entities.deleteEntity(_this.entityID);
|
var success = Entities.deleteEntity(_this.entityID);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,10 +11,11 @@
|
||||||
|
|
||||||
var TRANSFORMER_SCRIPT = Script.resolvePath('transformer.js');
|
var TRANSFORMER_SCRIPT = Script.resolvePath('transformer.js');
|
||||||
|
|
||||||
var AVATAR_COLLISION_HULL = 'atp:/dressingRoom/Avatar-Hull-4.obj';
|
var AVATAR_COLLISION_HULL = 'atp:/dressingRoom/Avatar-Hull-6.obj';
|
||||||
|
var ROBOT_COLLISION_HULL = 'atp:/dressingRoom/robot_hull.obj';
|
||||||
|
|
||||||
TransformerDoll = function(modelURL, spawnPosition, spawnRotation, dimensions) {
|
TransformerDoll = function(modelURL, spawnPosition, spawnRotation, dimensions) {
|
||||||
print('SCRIPT REF AT TRANSFORMER CREATE::' + TRANSFORMER_SCRIPT);
|
|
||||||
var transformerProps = {
|
var transformerProps = {
|
||||||
name: 'hifi-home-dressing-room-little-transformer',
|
name: 'hifi-home-dressing-room-little-transformer',
|
||||||
type: 'Model',
|
type: 'Model',
|
||||||
|
@ -30,8 +31,9 @@
|
||||||
z: 0
|
z: 0
|
||||||
},
|
},
|
||||||
visible: true,
|
visible: true,
|
||||||
damping: 0.8,
|
restitution: 0.1,
|
||||||
angularDamping: 0.8,
|
damping: 0.9,
|
||||||
|
angularDamping: 0.9,
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
'grabbableKey': {
|
'grabbableKey': {
|
||||||
'grabbable': true
|
'grabbable': true
|
||||||
|
@ -44,13 +46,16 @@
|
||||||
'reset': true
|
'reset': true
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
density: 5000,
|
density: 7500,
|
||||||
dimensions: dimensions,
|
dimensions: dimensions,
|
||||||
script: TRANSFORMER_SCRIPT
|
script: TRANSFORMER_SCRIPT
|
||||||
}
|
};
|
||||||
var transformer = Entities.addEntity(transformerProps);
|
|
||||||
|
|
||||||
print('CREATED TRANSFORMER' + transformer);
|
if (modelURL.indexOf('robot') > -1) {
|
||||||
|
transformerProps.compoundShapeURL = ROBOT_COLLISION_HULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
var transformer = Entities.addEntity(transformerProps);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
|
@ -68,9 +68,9 @@
|
||||||
|
|
||||||
var TRANSFORMER_URL_STYLIZED_FEMALE = 'atp:/dressingRoom/stylized_female.fbx';
|
var TRANSFORMER_URL_STYLIZED_FEMALE = 'atp:/dressingRoom/stylized_female.fbx';
|
||||||
|
|
||||||
var TRANSFORMER_URL_REALISTIC_MALE = '';
|
var TRANSFORMER_URL_PRISCILLA = 'atp:/dressingRoom/priscilla.fbx';
|
||||||
|
|
||||||
var TRANSFORMER_URL_REALISTIC_FEMALE = '';
|
var TRANSFORMER_URL_MATTHEW = 'atp:/dressingRoom/matthew.fbx';
|
||||||
|
|
||||||
Reset.prototype = {
|
Reset.prototype = {
|
||||||
tidying: false,
|
tidying: false,
|
||||||
|
@ -414,14 +414,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var dais = Entities.addEntity(daisProperties);
|
var dais = Entities.addEntity(daisProperties);
|
||||||
print('HOME created dais : ' + dais)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
createTransformers: function() {
|
createTransformers: function() {
|
||||||
var firstDollPosition = {
|
var firstDollPosition = {
|
||||||
x: 1107.61,
|
x: 1107.6,
|
||||||
y: 460.6,
|
y: 460.575,
|
||||||
z: -77.34
|
z: -77.37
|
||||||
}
|
}
|
||||||
|
|
||||||
var dollRotation = {
|
var dollRotation = {
|
||||||
|
@ -433,18 +432,15 @@
|
||||||
var rotationAsQuat = Quat.fromPitchYawRollDegrees(dollRotation.x, dollRotation.y, dollRotation.z);
|
var rotationAsQuat = Quat.fromPitchYawRollDegrees(dollRotation.x, dollRotation.y, dollRotation.z);
|
||||||
|
|
||||||
var dolls = [
|
var dolls = [
|
||||||
TRANSFORMER_URL_STYLIZED_FEMALE,
|
|
||||||
TRANSFORMER_URL_ROBOT,
|
TRANSFORMER_URL_ROBOT,
|
||||||
TRANSFORMER_URL_BEING_OF_LIGHT,
|
TRANSFORMER_URL_BEING_OF_LIGHT,
|
||||||
TRANSFORMER_URL_WILL
|
TRANSFORMER_URL_STYLIZED_FEMALE,
|
||||||
|
TRANSFORMER_URL_WILL,
|
||||||
|
TRANSFORMER_URL_PRISCILLA,
|
||||||
|
TRANSFORMER_URL_MATTHEW
|
||||||
];
|
];
|
||||||
|
|
||||||
var dollDimensions = [{
|
var dollDimensions = [{
|
||||||
//stylized female artemis
|
|
||||||
x: 1.6323,
|
|
||||||
y: 1.7705,
|
|
||||||
z: 0.2851
|
|
||||||
}, {
|
|
||||||
//robot
|
//robot
|
||||||
x: 1.4439,
|
x: 1.4439,
|
||||||
y: 0.6224,
|
y: 0.6224,
|
||||||
|
@ -454,11 +450,26 @@
|
||||||
x: 1.8838,
|
x: 1.8838,
|
||||||
y: 1.7865,
|
y: 1.7865,
|
||||||
z: 0.2955
|
z: 0.2955
|
||||||
|
}, {
|
||||||
|
//stylized female artemis
|
||||||
|
x: 1.6323,
|
||||||
|
y: 1.7705,
|
||||||
|
z: 0.2851
|
||||||
}, {
|
}, {
|
||||||
//will
|
//will
|
||||||
x: 1.6326,
|
x: 1.6326,
|
||||||
y: 1.6764,
|
y: 1.6764,
|
||||||
z: 0.2606
|
z: 0.2606
|
||||||
|
}, {
|
||||||
|
//priscilla
|
||||||
|
x: 1.6448,
|
||||||
|
y: 1.6657,
|
||||||
|
z: 0.3078
|
||||||
|
}, {
|
||||||
|
//matthew
|
||||||
|
x: 1.8722,
|
||||||
|
y: 1.8197,
|
||||||
|
z: 0.3666
|
||||||
}];
|
}];
|
||||||
|
|
||||||
var TRANSFORMER_SCALE = 0.25;
|
var TRANSFORMER_SCALE = 0.25;
|
||||||
|
@ -474,7 +485,11 @@
|
||||||
var separation = index * dollLateralSeparation;
|
var separation = index * dollLateralSeparation;
|
||||||
var left = Quat.getRight(rotationAsQuat);
|
var left = Quat.getRight(rotationAsQuat);
|
||||||
var distanceToLeft = Vec3.multiply(separation, left);
|
var distanceToLeft = Vec3.multiply(separation, left);
|
||||||
var dollPosition = Vec3.sum(firstDollPosition, distanceToLeft)
|
var dollPosition = Vec3.sum(firstDollPosition, distanceToLeft);
|
||||||
|
if (index === 0) {
|
||||||
|
//special case for robot
|
||||||
|
dollPosition.y += 0.15;
|
||||||
|
}
|
||||||
var transformer = new TransformerDoll(doll, dollPosition, dollRotation,
|
var transformer = new TransformerDoll(doll, dollPosition, dollRotation,
|
||||||
dollDimensions[index]);
|
dollDimensions[index]);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue