mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 03:50:40 +02:00
Merge branch 'master' into 21070
This commit is contained in:
commit
49709b42d7
19 changed files with 209 additions and 47 deletions
|
@ -1278,6 +1278,13 @@ void DomainServer::handleMetaverseHeartbeatError(QNetworkReply& requestReply) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::sendICEServerAddressToMetaverseAPI() {
|
void DomainServer::sendICEServerAddressToMetaverseAPI() {
|
||||||
|
if (_sendICEServerAddressToMetaverseAPIInProgress) {
|
||||||
|
// don't have more than one of these in-flight at a time. set a flag to indicate that once the current one
|
||||||
|
// is done, we need to do update metaverse again.
|
||||||
|
_sendICEServerAddressToMetaverseAPIRedo = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_sendICEServerAddressToMetaverseAPIInProgress = true;
|
||||||
const QString ICE_SERVER_ADDRESS = "ice_server_address";
|
const QString ICE_SERVER_ADDRESS = "ice_server_address";
|
||||||
|
|
||||||
QJsonObject domainObject;
|
QJsonObject domainObject;
|
||||||
|
@ -1302,6 +1309,8 @@ void DomainServer::sendICEServerAddressToMetaverseAPI() {
|
||||||
JSONCallbackParameters callbackParameters;
|
JSONCallbackParameters callbackParameters;
|
||||||
callbackParameters.errorCallbackReceiver = this;
|
callbackParameters.errorCallbackReceiver = this;
|
||||||
callbackParameters.errorCallbackMethod = "handleFailedICEServerAddressUpdate";
|
callbackParameters.errorCallbackMethod = "handleFailedICEServerAddressUpdate";
|
||||||
|
callbackParameters.jsonCallbackReceiver = this;
|
||||||
|
callbackParameters.jsonCallbackMethod = "handleSuccessfulICEServerAddressUpdate";
|
||||||
|
|
||||||
static QString repeatedMessage = LogHandler::getInstance().addOnlyOnceMessageRegex
|
static QString repeatedMessage = LogHandler::getInstance().addOnlyOnceMessageRegex
|
||||||
("Updating ice-server address in High Fidelity Metaverse API to [^ \n]+");
|
("Updating ice-server address in High Fidelity Metaverse API to [^ \n]+");
|
||||||
|
@ -1317,13 +1326,32 @@ void DomainServer::sendICEServerAddressToMetaverseAPI() {
|
||||||
domainUpdateJSON.toUtf8());
|
domainUpdateJSON.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DomainServer::handleSuccessfulICEServerAddressUpdate(QNetworkReply& requestReply) {
|
||||||
|
_sendICEServerAddressToMetaverseAPIInProgress = false;
|
||||||
|
if (_sendICEServerAddressToMetaverseAPIRedo) {
|
||||||
|
qDebug() << "ice-server address updated with metaverse, but has since changed. redoing update...";
|
||||||
|
_sendICEServerAddressToMetaverseAPIRedo = false;
|
||||||
|
sendICEServerAddressToMetaverseAPI();
|
||||||
|
} else {
|
||||||
|
qDebug() << "ice-server address updated with metaverse.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DomainServer::handleFailedICEServerAddressUpdate(QNetworkReply& requestReply) {
|
void DomainServer::handleFailedICEServerAddressUpdate(QNetworkReply& requestReply) {
|
||||||
const int ICE_SERVER_UPDATE_RETRY_MS = 2 * 1000;
|
_sendICEServerAddressToMetaverseAPIInProgress = false;
|
||||||
|
if (_sendICEServerAddressToMetaverseAPIRedo) {
|
||||||
|
// if we have new data, retry right away, even though the previous attempt didn't go well.
|
||||||
|
_sendICEServerAddressToMetaverseAPIRedo = false;
|
||||||
|
sendICEServerAddressToMetaverseAPI();
|
||||||
|
} else {
|
||||||
|
const int ICE_SERVER_UPDATE_RETRY_MS = 2 * 1000;
|
||||||
|
|
||||||
qWarning() << "Failed to update ice-server address with High Fidelity Metaverse - error was" << requestReply.errorString();
|
qWarning() << "Failed to update ice-server address with High Fidelity Metaverse - error was"
|
||||||
qWarning() << "\tRe-attempting in" << ICE_SERVER_UPDATE_RETRY_MS / 1000 << "seconds";
|
<< requestReply.errorString();
|
||||||
|
qWarning() << "\tRe-attempting in" << ICE_SERVER_UPDATE_RETRY_MS / 1000 << "seconds";
|
||||||
|
|
||||||
QTimer::singleShot(ICE_SERVER_UPDATE_RETRY_MS, this, SLOT(sendICEServerAddressToMetaverseAPI()));
|
QTimer::singleShot(ICE_SERVER_UPDATE_RETRY_MS, this, SLOT(sendICEServerAddressToMetaverseAPI()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::sendHeartbeatToIceServer() {
|
void DomainServer::sendHeartbeatToIceServer() {
|
||||||
|
|
|
@ -96,6 +96,7 @@ private slots:
|
||||||
void handleICEHostInfo(const QHostInfo& hostInfo);
|
void handleICEHostInfo(const QHostInfo& hostInfo);
|
||||||
|
|
||||||
void sendICEServerAddressToMetaverseAPI();
|
void sendICEServerAddressToMetaverseAPI();
|
||||||
|
void handleSuccessfulICEServerAddressUpdate(QNetworkReply& requestReply);
|
||||||
void handleFailedICEServerAddressUpdate(QNetworkReply& requestReply);
|
void handleFailedICEServerAddressUpdate(QNetworkReply& requestReply);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -211,6 +212,9 @@ private:
|
||||||
int _iceServerPort;
|
int _iceServerPort;
|
||||||
bool _overrideDomainID { false }; // should we override the domain-id from settings?
|
bool _overrideDomainID { false }; // should we override the domain-id from settings?
|
||||||
QUuid _overridingDomainID { QUuid() }; // what should we override it with?
|
QUuid _overridingDomainID { QUuid() }; // what should we override it with?
|
||||||
|
|
||||||
|
bool _sendICEServerAddressToMetaverseAPIInProgress { false };
|
||||||
|
bool _sendICEServerAddressToMetaverseAPIRedo { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,7 @@ Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onActiveFocusChanged: {
|
onActiveFocusChanged: {
|
||||||
cursorVisible = isCursorVisible;
|
cursorVisible = isCursorVisible && focus;
|
||||||
}
|
}
|
||||||
MouseArea {
|
MouseArea {
|
||||||
// If user clicks in address bar show cursor to indicate ability to enter address.
|
// If user clicks in address bar show cursor to indicate ability to enter address.
|
||||||
|
@ -233,6 +233,7 @@ Window {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
isCursorVisible = true;
|
isCursorVisible = true;
|
||||||
parent.cursorVisible = true;
|
parent.cursorVisible = true;
|
||||||
|
parent.forceActiveFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@ Item {
|
||||||
loginDialog.login(usernameField.text, passwordField.text)
|
loginDialog.login(usernameField.text, passwordField.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property bool keyboardRaised: false
|
||||||
|
property bool punctuationMode: false
|
||||||
|
|
||||||
|
onKeyboardRaisedChanged: d.resize();
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
readonly property int minWidth: 480
|
readonly property int minWidth: 480
|
||||||
|
@ -35,13 +40,13 @@ Item {
|
||||||
readonly property int maxHeight: 720
|
readonly property int maxHeight: 720
|
||||||
|
|
||||||
function resize() {
|
function resize() {
|
||||||
var targetWidth = Math.max(titleWidth, form.contentWidth)
|
var targetWidth = Math.max(titleWidth, form.contentWidth);
|
||||||
var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height +
|
var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height
|
||||||
4 * hifi.dimensions.contentSpacing.y + form.height +
|
+ 4 * hifi.dimensions.contentSpacing.y + form.height + hifi.dimensions.contentSpacing.y + buttons.height;
|
||||||
4 * hifi.dimensions.contentSpacing.y + buttons.height
|
|
||||||
|
|
||||||
root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth))
|
root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth));
|
||||||
root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight))
|
root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight))
|
||||||
|
+ (linkAccountBody.keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : hifi.dimensions.contentSpacing.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,13 +135,39 @@ Item {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override ScrollingWindow's keyboard that would be at very bottom of dialog.
|
||||||
|
Keyboard {
|
||||||
|
y: parent.keyboardRaised ? parent.height : 0
|
||||||
|
height: parent.keyboardRaised ? 200 : 0
|
||||||
|
visible: parent.keyboardRaised && !parent.punctuationMode
|
||||||
|
enabled: parent.keyboardRaised && !parent.punctuationMode
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: buttons.top
|
||||||
|
bottomMargin: parent.keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardPunctuation {
|
||||||
|
y: parent.keyboardRaised ? parent.height : 0
|
||||||
|
height: parent.keyboardRaised ? 200 : 0
|
||||||
|
visible: parent.keyboardRaised && parent.punctuationMode
|
||||||
|
enabled: parent.keyboardRaised && parent.punctuationMode
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: buttons.top
|
||||||
|
bottomMargin: parent.keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: buttons
|
id: buttons
|
||||||
anchors {
|
anchors {
|
||||||
top: form.bottom
|
|
||||||
right: parent.right
|
right: parent.right
|
||||||
margins: 0
|
bottom: parent.bottom
|
||||||
topMargin: 3 * hifi.dimensions.contentSpacing.y
|
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||||
}
|
}
|
||||||
spacing: hifi.dimensions.contentSpacing.x
|
spacing: hifi.dimensions.contentSpacing.x
|
||||||
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
onHeightChanged: d.resize(); onWidthChanged: d.resize();
|
||||||
|
|
|
@ -4625,11 +4625,15 @@ void Application::resetSensors(bool andReload) {
|
||||||
|
|
||||||
void Application::updateWindowTitle() const {
|
void Application::updateWindowTitle() const {
|
||||||
|
|
||||||
QString buildVersion = " (build " + applicationVersion() + ")";
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
|
||||||
QString connectionStatus = nodeList->getDomainHandler().isConnected() ? "" : " (NOT CONNECTED) ";
|
QString buildVersion = " (build " + applicationVersion() + ")";
|
||||||
QString username = DependencyManager::get<AccountManager>()->getAccountInfo().getUsername();
|
|
||||||
|
QString loginStatus = accountManager->isLoggedIn() ? "" : " (NOT LOGGED IN)";
|
||||||
|
|
||||||
|
QString connectionStatus = nodeList->getDomainHandler().isConnected() ? "" : " (NOT CONNECTED)";
|
||||||
|
QString username = accountManager->getAccountInfo().getUsername();
|
||||||
QString currentPlaceName = DependencyManager::get<AddressManager>()->getHost();
|
QString currentPlaceName = DependencyManager::get<AddressManager>()->getHost();
|
||||||
|
|
||||||
if (currentPlaceName.isEmpty()) {
|
if (currentPlaceName.isEmpty()) {
|
||||||
|
@ -4637,7 +4641,7 @@ void Application::updateWindowTitle() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString title = QString() + (!username.isEmpty() ? username + " @ " : QString())
|
QString title = QString() + (!username.isEmpty() ? username + " @ " : QString())
|
||||||
+ currentPlaceName + connectionStatus + buildVersion;
|
+ currentPlaceName + connectionStatus + loginStatus + buildVersion;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
// crashes with vs2013/win32
|
// crashes with vs2013/win32
|
||||||
|
|
|
@ -124,7 +124,6 @@ void HmdDisplayPlugin::uncustomizeContext() {
|
||||||
batch.setFramebuffer(_compositeFramebuffer);
|
batch.setFramebuffer(_compositeFramebuffer);
|
||||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
|
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
|
||||||
});
|
});
|
||||||
internalPresent();
|
|
||||||
_overlayRenderer = OverlayRenderer();
|
_overlayRenderer = OverlayRenderer();
|
||||||
Parent::uncustomizeContext();
|
Parent::uncustomizeContext();
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,7 +478,8 @@ bool EntityTreeRenderer::applySkyboxAndHasAmbient() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_pendingSkyboxTexture && !_skyboxTexture) {
|
if (_pendingSkyboxTexture &&
|
||||||
|
(!_skyboxTexture || (_skyboxTexture->getURL() != _skyboxTextureURL))) {
|
||||||
_skyboxTexture = textureCache->getTexture(_skyboxTextureURL, NetworkTexture::CUBE_TEXTURE);
|
_skyboxTexture = textureCache->getTexture(_skyboxTextureURL, NetworkTexture::CUBE_TEXTURE);
|
||||||
}
|
}
|
||||||
if (_skyboxTexture && _skyboxTexture->isLoaded()) {
|
if (_skyboxTexture && _skyboxTexture->isLoaded()) {
|
||||||
|
|
|
@ -83,6 +83,9 @@ bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
|
||||||
++_currentWebCount;
|
++_currentWebCount;
|
||||||
// Save the original GL context, because creating a QML surface will create a new context
|
// Save the original GL context, because creating a QML surface will create a new context
|
||||||
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
||||||
|
if (!currentContext) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
QSurface * currentSurface = currentContext->surface();
|
QSurface * currentSurface = currentContext->surface();
|
||||||
|
|
||||||
auto deleter = [](OffscreenQmlSurface* webSurface) {
|
auto deleter = [](OffscreenQmlSurface* webSurface) {
|
||||||
|
|
|
@ -127,7 +127,7 @@ const gpu::TexturePointer& TextureCache::getGrayTexture() {
|
||||||
if (!_grayTexture) {
|
if (!_grayTexture) {
|
||||||
_grayTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1));
|
_grayTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1));
|
||||||
_grayTexture->setSource("TextureCache::_grayTexture");
|
_grayTexture->setSource("TextureCache::_grayTexture");
|
||||||
_grayTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_GRAY);
|
_grayTexture->assignStoredMip(0, _grayTexture->getTexelFormat(), sizeof(OPAQUE_GRAY), OPAQUE_GRAY);
|
||||||
}
|
}
|
||||||
return _grayTexture;
|
return _grayTexture;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ const gpu::TexturePointer& TextureCache::getBlackTexture() {
|
||||||
if (!_blackTexture) {
|
if (!_blackTexture) {
|
||||||
_blackTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1));
|
_blackTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1));
|
||||||
_blackTexture->setSource("TextureCache::_blackTexture");
|
_blackTexture->setSource("TextureCache::_blackTexture");
|
||||||
_blackTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_BLACK), OPAQUE_BLACK);
|
_blackTexture->assignStoredMip(0, _blackTexture->getTexelFormat(), sizeof(OPAQUE_BLACK), OPAQUE_BLACK);
|
||||||
}
|
}
|
||||||
return _blackTexture;
|
return _blackTexture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,11 @@ void OculusBaseDisplayPlugin::customizeContext() {
|
||||||
Parent::customizeContext();
|
Parent::customizeContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OculusBaseDisplayPlugin::uncustomizeContext() {
|
||||||
|
Parent::uncustomizeContext();
|
||||||
|
internalPresent();
|
||||||
|
}
|
||||||
|
|
||||||
bool OculusBaseDisplayPlugin::internalActivate() {
|
bool OculusBaseDisplayPlugin::internalActivate() {
|
||||||
_session = acquireOculusSession();
|
_session = acquireOculusSession();
|
||||||
if (!_session) {
|
if (!_session) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void customizeContext() override;
|
void customizeContext() override;
|
||||||
|
void uncustomizeContext() override;
|
||||||
bool internalActivate() override;
|
bool internalActivate() override;
|
||||||
void internalDeactivate() override;
|
void internalDeactivate() override;
|
||||||
void updatePresentPose() override;
|
void updatePresentPose() override;
|
||||||
|
|
|
@ -39,6 +39,10 @@ const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; // this probab
|
||||||
PoseData _nextRenderPoseData;
|
PoseData _nextRenderPoseData;
|
||||||
PoseData _nextSimPoseData;
|
PoseData _nextSimPoseData;
|
||||||
|
|
||||||
|
#define MIN_CORES_FOR_NORMAL_RENDER 5
|
||||||
|
bool forceInterleavedReprojection = (QThread::idealThreadCount() < MIN_CORES_FOR_NORMAL_RENDER);
|
||||||
|
|
||||||
|
|
||||||
static std::array<vr::Hmd_Eye, 2> VR_EYES { { vr::Eye_Left, vr::Eye_Right } };
|
static std::array<vr::Hmd_Eye, 2> VR_EYES { { vr::Eye_Left, vr::Eye_Right } };
|
||||||
bool _openVrDisplayActive { false };
|
bool _openVrDisplayActive { false };
|
||||||
// Flip y-axis since GL UV coords are backwards.
|
// Flip y-axis since GL UV coords are backwards.
|
||||||
|
@ -399,7 +403,10 @@ bool OpenVrDisplayPlugin::internalActivate() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// enable async time warp
|
// enable async time warp
|
||||||
//vr::VRCompositor()->ForceInterleavedReprojectionOn(true);
|
if (forceInterleavedReprojection) {
|
||||||
|
vr::VRCompositor()->ForceInterleavedReprojectionOn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// set up default sensor space such that the UI overlay will align with the front of the room.
|
// set up default sensor space such that the UI overlay will align with the front of the room.
|
||||||
auto chaperone = vr::VRChaperone();
|
auto chaperone = vr::VRChaperone();
|
||||||
|
|
|
@ -103,6 +103,15 @@ void releaseOpenVrSystem() {
|
||||||
#if DEV_BUILD
|
#if DEV_BUILD
|
||||||
qCDebug(displayplugins) << "OpenVR: zero refcount, deallocate VR system";
|
qCDebug(displayplugins) << "OpenVR: zero refcount, deallocate VR system";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// HACK: workaround openvr crash, call submit with an invalid texture, right before VR_Shutdown.
|
||||||
|
const GLuint INVALID_GL_TEXTURE_HANDLE = -1;
|
||||||
|
vr::Texture_t vrTexture{ (void*)INVALID_GL_TEXTURE_HANDLE, vr::API_OpenGL, vr::ColorSpace_Auto };
|
||||||
|
static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_LEFT{ 0, 0, 0.5f, 1 };
|
||||||
|
static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_RIGHT{ 0.5f, 0, 1, 1 };
|
||||||
|
vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT);
|
||||||
|
vr::VRCompositor()->Submit(vr::Eye_Right, &vrTexture, &OPENVR_TEXTURE_BOUNDS_RIGHT);
|
||||||
|
|
||||||
vr::VR_Shutdown();
|
vr::VR_Shutdown();
|
||||||
_openVrQuitRequested = false;
|
_openVrQuitRequested = false;
|
||||||
activeHmd = nullptr;
|
activeHmd = nullptr;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
||||||
|
|
||||||
print('crowd-agent version 1');
|
print('crowd-agent version 2');
|
||||||
|
|
||||||
/* Observations:
|
/* Observations:
|
||||||
- File urls for AC scripts silently fail. Use a local server (e.g., python SimpleHTTPServer) for development.
|
- File urls for AC scripts silently fail. Use a local server (e.g., python SimpleHTTPServer) for development.
|
||||||
|
@ -24,9 +24,26 @@ print('crowd-agent version 1');
|
||||||
- JSON.stringify(Avatar) silently fails (even when Agent.isAvatar)
|
- JSON.stringify(Avatar) silently fails (even when Agent.isAvatar)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function messageSend(message) {
|
||||||
|
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSound(data, callback) { // callback(sound) when downloaded (which may be immediate).
|
||||||
|
var sound = SoundCache.getSound(data.url);
|
||||||
|
if (sound.downloaded) {
|
||||||
|
return callback(sound);
|
||||||
|
}
|
||||||
|
sound.ready.connect(function () { callback(sound); });
|
||||||
|
}
|
||||||
|
function onFinishedPlaying() {
|
||||||
|
messageSend({key: 'finishedSound'});
|
||||||
|
}
|
||||||
|
|
||||||
|
var MILLISECONDS_IN_SECOND = 1000;
|
||||||
function startAgent(parameters) { // Can also be used to update.
|
function startAgent(parameters) { // Can also be used to update.
|
||||||
print('crowd-agent starting params', JSON.stringify(parameters), JSON.stringify(Agent));
|
print('crowd-agent starting params', JSON.stringify(parameters), JSON.stringify(Agent));
|
||||||
Agent.isAvatar = true;
|
Agent.isAvatar = true;
|
||||||
|
Agent.isListeningToAudioStream = true; // Send silence when not chattering.
|
||||||
if (parameters.position) {
|
if (parameters.position) {
|
||||||
Avatar.position = parameters.position;
|
Avatar.position = parameters.position;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +53,12 @@ function startAgent(parameters) { // Can also be used to update.
|
||||||
if (parameters.skeletonModelURL) {
|
if (parameters.skeletonModelURL) {
|
||||||
Avatar.skeletonModelURL = parameters.skeletonModelURL;
|
Avatar.skeletonModelURL = parameters.skeletonModelURL;
|
||||||
}
|
}
|
||||||
|
if (parameters.soundData) {
|
||||||
|
getSound(parameters.soundData, function (sound) {
|
||||||
|
Script.setTimeout(onFinishedPlaying, sound.duration * MILLISECONDS_IN_SECOND);
|
||||||
|
Agent.playAvatarSound(sound);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (parameters.animationData) {
|
if (parameters.animationData) {
|
||||||
data = parameters.animationData;
|
data = parameters.animationData;
|
||||||
Avatar.startAnimation(data.url, data.fps || 30, 1.0, (data.loopFlag === undefined) ? true : data.loopFlag, false, data.startFrame || 0, data.endFrame);
|
Avatar.startAnimation(data.url, data.fps || 30, 1.0, (data.loopFlag === undefined) ? true : data.loopFlag, false, data.startFrame || 0, data.endFrame);
|
||||||
|
@ -47,9 +70,6 @@ function stopAgent(parameters) {
|
||||||
print('crowd-agent stopped', JSON.stringify(parameters), JSON.stringify(Agent));
|
print('crowd-agent stopped', JSON.stringify(parameters), JSON.stringify(Agent));
|
||||||
}
|
}
|
||||||
|
|
||||||
function messageSend(message) {
|
|
||||||
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
|
||||||
}
|
|
||||||
function messageHandler(channel, messageString, senderID) {
|
function messageHandler(channel, messageString, senderID) {
|
||||||
if (channel !== MESSAGE_CHANNEL) {
|
if (channel !== MESSAGE_CHANNEL) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -18,15 +18,25 @@ var label = "summon";
|
||||||
function debug() {
|
function debug() {
|
||||||
print.apply(null, [].concat.apply([label, version], [].map.call(arguments, JSON.stringify)));
|
print.apply(null, [].concat.apply([label, version], [].map.call(arguments, JSON.stringify)));
|
||||||
}
|
}
|
||||||
var MINIMUM_AVATARS = 25;
|
var MINIMUM_AVATARS = 25; // We will summon agents to produce this many total. (Of course, there might not be enough agents.)
|
||||||
var DENSITY = 0.3; // square meters per person. Some say 10 sq ft is arm's length (0.9m^2), 4.5 is crowd (0.4m^2), 2.5 is mosh pit (0.2m^2).
|
var DENSITY = 0.3; // square meters per person. Some say 10 sq ft is arm's length (0.9m^2), 4.5 is crowd (0.4m^2), 2.5 is mosh pit (0.2m^2).
|
||||||
|
var SOUND_DATA = {url: "http://howard-stearns.github.io/models/sounds/piano1.wav"};
|
||||||
|
var AVATARS_CHATTERING_AT_ONCE = 4; // How many of the agents should we request to play SOUND at once.
|
||||||
|
var NEXT_SOUND_SPREAD = 500; // millisecond range of how long to wait after one sound finishes, before playing the next
|
||||||
|
|
||||||
var spread = Math.sqrt(MINIMUM_AVATARS * DENSITY); // meters
|
var spread = Math.sqrt(MINIMUM_AVATARS * DENSITY); // meters
|
||||||
var turnSpread = 90; // How many degrees should turn from front range over.
|
var turnSpread = 90; // How many degrees should turn from front range over.
|
||||||
|
|
||||||
function coord() { return (Math.random() * spread) - (spread / 2); } // randomly distribute a coordinate zero += spread/2.
|
function coord() { return (Math.random() * spread) - (spread / 2); } // randomly distribute a coordinate zero += spread/2.
|
||||||
|
function contains(array, item) { return array.indexOf(item) >= 0; }
|
||||||
|
function without(array, itemsToRemove) { return array.filter(function (item) { return !contains(itemsToRemove, item); }); }
|
||||||
|
function nextAfter(array, id) { // Wrapping next element in array after id.
|
||||||
|
var index = array.indexOf(id) + 1;
|
||||||
|
return array[(index >= array.length) ? 0 : index];
|
||||||
|
}
|
||||||
|
|
||||||
var summonedAgents = [];
|
var summonedAgents = [];
|
||||||
|
var chattering = [];
|
||||||
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
||||||
function messageSend(message) {
|
function messageSend(message) {
|
||||||
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
||||||
|
@ -48,15 +58,20 @@ function messageHandler(channel, messageString, senderID) {
|
||||||
switch (message.key) {
|
switch (message.key) {
|
||||||
case "hello":
|
case "hello":
|
||||||
// There can be avatars we've summoned that do not yet appear in the AvatarList.
|
// There can be avatars we've summoned that do not yet appear in the AvatarList.
|
||||||
avatarIdentifiers = AvatarList.getAvatarIdentifiers().filter(function (id) { return summonedAgents.indexOf(id) === -1; });
|
avatarIdentifiers = without(AvatarList.getAvatarIdentifiers(), summonedAgents);
|
||||||
debug('present', avatarIdentifiers, summonedAgents);
|
debug('present', avatarIdentifiers, summonedAgents);
|
||||||
if ((summonedAgents.length + avatarIdentifiers.length) < MINIMUM_AVATARS ) {
|
if ((summonedAgents.length + avatarIdentifiers.length) < MINIMUM_AVATARS ) {
|
||||||
|
var chatter = chattering.length < AVATARS_CHATTERING_AT_ONCE;
|
||||||
|
if (chatter) {
|
||||||
|
chattering.push(senderID);
|
||||||
|
}
|
||||||
summonedAgents.push(senderID);
|
summonedAgents.push(senderID);
|
||||||
messageSend({
|
messageSend({
|
||||||
key: 'SUMMON',
|
key: 'SUMMON',
|
||||||
rcpt: senderID,
|
rcpt: senderID,
|
||||||
position: Vec3.sum(MyAvatar.position, {x: coord(), y: 0, z: coord()}),
|
position: Vec3.sum(MyAvatar.position, {x: coord(), y: 0, z: coord()}),
|
||||||
orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0)/*,
|
orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0),
|
||||||
|
soundData: chatter && SOUND_DATA/*
|
||||||
// No need to specify skeletonModelURL
|
// No need to specify skeletonModelURL
|
||||||
//skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/being_of_light/being_of_light.fbx",
|
//skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/being_of_light/being_of_light.fbx",
|
||||||
//skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/defaultAvatar_full.fst"/,
|
//skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/defaultAvatar_full.fst"/,
|
||||||
|
@ -71,6 +86,16 @@ function messageHandler(channel, messageString, senderID) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "finishedSound": // Give someone else a chance.
|
||||||
|
chattering = without(chattering, [senderID]);
|
||||||
|
Script.setTimeout(function () {
|
||||||
|
messageSend({
|
||||||
|
key: 'SUMMON',
|
||||||
|
rcpt: nextAfter(without(summonedAgents, chattering), senderID),
|
||||||
|
soundData: SOUND_DATA
|
||||||
|
});
|
||||||
|
}, Math.random() * NEXT_SOUND_SPREAD);
|
||||||
|
break;
|
||||||
case "HELO":
|
case "HELO":
|
||||||
Window.alert("Someone else is summoning avatars.");
|
Window.alert("Someone else is summoning avatars.");
|
||||||
break;
|
break;
|
||||||
|
@ -93,11 +118,12 @@ Script.scriptEnding.connect(function () {
|
||||||
|
|
||||||
messageSend({key: 'HELO'}); // Ask agents to report in now.
|
messageSend({key: 'HELO'}); // Ask agents to report in now.
|
||||||
Script.setTimeout(function () {
|
Script.setTimeout(function () {
|
||||||
|
var total = AvatarList.getAvatarIdentifiers().length;
|
||||||
if (0 === summonedAgents.length) {
|
if (0 === summonedAgents.length) {
|
||||||
Window.alert("No agents reported.\n\Please run " + MINIMUM_AVATARS + " instances of\n\
|
Window.alert("No agents reported.\n\Please run " + MINIMUM_AVATARS + " instances of\n\
|
||||||
http://cdn.highfidelity.com/davidkelly/production/scripts/tests/performance/crowd-agent.js\n\
|
http://cdn.highfidelity.com/davidkelly/production/scripts/tests/performance/crowd-agent.js\n\
|
||||||
on your domain server.");
|
on your domain server.");
|
||||||
} else if (summonedAgents.length < MINIMUM_AVATARS) {
|
} else if (total < MINIMUM_AVATARS) {
|
||||||
Window.alert("Only " + summonedAgents.length + " of the expected " + MINIMUM_AVATARS + " agents reported in.");
|
Window.alert("Only " + summonedAgents.length + " of the expected " + (MINIMUM_AVATARS - total) + " agents reported in.");
|
||||||
}
|
}
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
|
@ -308,6 +308,17 @@ function hudReticleDistance() { // 3d distance from camera to the reticle positi
|
||||||
var reticlePositionOnHUD = HMD.worldPointFromOverlay(Reticle.position);
|
var reticlePositionOnHUD = HMD.worldPointFromOverlay(Reticle.position);
|
||||||
return Vec3.distance(reticlePositionOnHUD, HMD.position);
|
return Vec3.distance(reticlePositionOnHUD, HMD.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function maybeAdjustReticleDepth() {
|
||||||
|
if (HMD.active) { // set depth
|
||||||
|
if (isPointingAtOverlay()) {
|
||||||
|
Reticle.depth = hudReticleDistance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var ADJUST_RETICLE_DEPTH_INTERVAL = 50; // 20hz
|
||||||
|
Script.setInterval(maybeAdjustReticleDepth,ADJUST_RETICLE_DEPTH_INTERVAL);
|
||||||
|
|
||||||
function onMouseMove() {
|
function onMouseMove() {
|
||||||
// Display cursor at correct depth (as in depthReticle.js), and updateMouseActivity.
|
// Display cursor at correct depth (as in depthReticle.js), and updateMouseActivity.
|
||||||
if (ignoreMouseActivity()) {
|
if (ignoreMouseActivity()) {
|
||||||
|
|
|
@ -39,6 +39,7 @@ function shouldShowWebTablet() {
|
||||||
|
|
||||||
function showMarketplace(marketplaceID) {
|
function showMarketplace(marketplaceID) {
|
||||||
if (shouldShowWebTablet()) {
|
if (shouldShowWebTablet()) {
|
||||||
|
updateButtonState(true);
|
||||||
marketplaceWebTablet = new WebTablet("https://metaverse.highfidelity.com/marketplace");
|
marketplaceWebTablet = new WebTablet("https://metaverse.highfidelity.com/marketplace");
|
||||||
} else {
|
} else {
|
||||||
var url = MARKETPLACE_URL;
|
var url = MARKETPLACE_URL;
|
||||||
|
@ -58,6 +59,7 @@ function hideMarketplace() {
|
||||||
marketplaceWindow.setVisible(false);
|
marketplaceWindow.setVisible(false);
|
||||||
marketplaceWindow.setURL("about:blank");
|
marketplaceWindow.setURL("about:blank");
|
||||||
} else if (marketplaceWebTablet) {
|
} else if (marketplaceWebTablet) {
|
||||||
|
updateButtonState(false);
|
||||||
marketplaceWebTablet.destroy();
|
marketplaceWebTablet.destroy();
|
||||||
marketplaceWebTablet = null;
|
marketplaceWebTablet = null;
|
||||||
}
|
}
|
||||||
|
@ -83,10 +85,13 @@ var browseExamplesButton = toolBar.addButton({
|
||||||
alpha: 0.9
|
alpha: 0.9
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateButtonState(visible) {
|
||||||
|
browseExamplesButton.writeProperty('buttonState', visible ? 0 : 1);
|
||||||
|
browseExamplesButton.writeProperty('defaultState', visible ? 0 : 1);
|
||||||
|
browseExamplesButton.writeProperty('hoverState', visible ? 2 : 3);
|
||||||
|
}
|
||||||
function onMarketplaceWindowVisibilityChanged() {
|
function onMarketplaceWindowVisibilityChanged() {
|
||||||
browseExamplesButton.writeProperty('buttonState', marketplaceWindow.visible ? 0 : 1);
|
updateButtonState(marketplaceWindow.visible);
|
||||||
browseExamplesButton.writeProperty('defaultState', marketplaceWindow.visible ? 0 : 1);
|
|
||||||
browseExamplesButton.writeProperty('hoverState', marketplaceWindow.visible ? 2 : 3);
|
|
||||||
marketplaceVisible = marketplaceWindow.visible;
|
marketplaceVisible = marketplaceWindow.visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click');
|
||||||
function controllerComputePickRay(hand) {
|
function controllerComputePickRay(hand) {
|
||||||
var controllerPose = getControllerWorldLocation(hand, true);
|
var controllerPose = getControllerWorldLocation(hand, true);
|
||||||
if (controllerPose.valid) {
|
if (controllerPose.valid) {
|
||||||
return { origin: controllerPose.position, direction: controllerPose.orientation };
|
return { origin: controllerPose.position, direction: Quat.getUp(controllerPose.orientation) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -469,7 +469,7 @@ var usersWindow = (function () {
|
||||||
|
|
||||||
Overlays.editOverlay(minimizeButton, {
|
Overlays.editOverlay(minimizeButton, {
|
||||||
x: windowLeft + WINDOW_WIDTH - WINDOW_MARGIN / 2 - MIN_MAX_BUTTON_WIDTH,
|
x: windowLeft + WINDOW_WIDTH - WINDOW_MARGIN / 2 - MIN_MAX_BUTTON_WIDTH,
|
||||||
y: windowTop + WINDOW_MARGIN / 2
|
y: windowTop + WINDOW_MARGIN
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollbarBackgroundPosition.x = windowLeft + WINDOW_WIDTH - 0.5 * WINDOW_MARGIN - SCROLLBAR_BACKGROUND_WIDTH;
|
scrollbarBackgroundPosition.x = windowLeft + WINDOW_WIDTH - 0.5 * WINDOW_MARGIN - SCROLLBAR_BACKGROUND_WIDTH;
|
||||||
|
@ -559,34 +559,34 @@ var usersWindow = (function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
Overlays.editOverlay(windowHeading, {
|
Overlays.editOverlay(windowHeading, {
|
||||||
text: linesOfUsers.length > 0 ? "Users online" : "No users online"
|
text: isLoggedIn ? (linesOfUsers.length > 0 ? "Users online" : "No users online") : "Users online - log in to view"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateOverlayVisibility() {
|
function updateOverlayVisibility() {
|
||||||
Overlays.editOverlay(windowBorder, {
|
Overlays.editOverlay(windowBorder, {
|
||||||
visible: isLoggedIn && isVisible && isBorderVisible
|
visible: isVisible && isBorderVisible
|
||||||
});
|
});
|
||||||
Overlays.editOverlay(windowPane, {
|
Overlays.editOverlay(windowPane, {
|
||||||
visible: isLoggedIn && isVisible
|
visible: isVisible
|
||||||
});
|
});
|
||||||
Overlays.editOverlay(windowHeading, {
|
Overlays.editOverlay(windowHeading, {
|
||||||
visible: isLoggedIn && isVisible
|
visible: isVisible
|
||||||
});
|
});
|
||||||
Overlays.editOverlay(minimizeButton, {
|
Overlays.editOverlay(minimizeButton, {
|
||||||
visible: isLoggedIn && isVisible
|
visible: isLoggedIn && isVisible
|
||||||
});
|
});
|
||||||
Overlays.editOverlay(scrollbarBackground, {
|
Overlays.editOverlay(scrollbarBackground, {
|
||||||
visible: isLoggedIn && isVisible && isUsingScrollbars && !isMinimized
|
visible: isVisible && isUsingScrollbars && !isMinimized
|
||||||
});
|
});
|
||||||
Overlays.editOverlay(scrollbarBar, {
|
Overlays.editOverlay(scrollbarBar, {
|
||||||
visible: isLoggedIn && isVisible && isUsingScrollbars && !isMinimized
|
visible: isVisible && isUsingScrollbars && !isMinimized
|
||||||
});
|
});
|
||||||
Overlays.editOverlay(friendsButton, {
|
Overlays.editOverlay(friendsButton, {
|
||||||
visible: isLoggedIn && isVisible && !isMinimized
|
visible: isVisible && !isMinimized
|
||||||
});
|
});
|
||||||
displayControl.setVisible(isLoggedIn && isVisible && !isMinimized);
|
displayControl.setVisible(isVisible && !isMinimized);
|
||||||
visibilityControl.setVisible(isLoggedIn && isVisible && !isMinimized);
|
visibilityControl.setVisible(isVisible && !isMinimized);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkLoggedIn() {
|
function checkLoggedIn() {
|
||||||
|
@ -594,6 +594,13 @@ var usersWindow = (function () {
|
||||||
|
|
||||||
isLoggedIn = Account.isLoggedIn();
|
isLoggedIn = Account.isLoggedIn();
|
||||||
if (isLoggedIn !== wasLoggedIn) {
|
if (isLoggedIn !== wasLoggedIn) {
|
||||||
|
if (wasLoggedIn) {
|
||||||
|
setMinimized(true);
|
||||||
|
calculateWindowHeight();
|
||||||
|
updateOverlayPositions();
|
||||||
|
updateUsersDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
updateOverlayVisibility();
|
updateOverlayVisibility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1021,7 +1028,7 @@ var usersWindow = (function () {
|
||||||
color: WINDOW_HEADING_COLOR,
|
color: WINDOW_HEADING_COLOR,
|
||||||
alpha: WINDOW_HEADING_ALPHA,
|
alpha: WINDOW_HEADING_ALPHA,
|
||||||
backgroundAlpha: 0.0,
|
backgroundAlpha: 0.0,
|
||||||
text: "No users online",
|
text: "Users online",
|
||||||
font: WINDOW_FONT,
|
font: WINDOW_FONT,
|
||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue