Merge remote-tracking branch 'upstream/master' into android

This commit is contained in:
Brad Davis 2018-01-19 10:37:41 -08:00
commit d6f7b23b2d
4 changed files with 70 additions and 27 deletions

View file

@ -1,5 +1,7 @@
# this guide is specific to Ubuntu 16.04. ## This guide is specific to Ubuntu 16.04.
# deb packages of High Fidelity domain server and assignment client are stored on debian.highfidelity.com Deb packages of High Fidelity domain server and assignment client are stored on debian.highfidelity.com
```
sudo su - sudo su -
apt-get -y update apt-get -y update
apt-get install -y software-properties-common apt-get install -y software-properties-common
@ -8,20 +10,27 @@ add-apt-repository "deb http://debian.highfidelity.com stable main"
apt-get -y update apt-get -y update
apt-get install -y hifi-domain-server apt-get install -y hifi-domain-server
apt-get install -y hifi-assignment-client apt-get install -y hifi-assignment-client
```
# When installing master/dev builds, the packages are slightly different and you just need to change the last 2 steps to: When installing master/dev builds, the packages are slightly different and you just need to change the last 2 steps to:
```
apt-get install -y hifi-dev-domain-server apt-get install -y hifi-dev-domain-server
apt-get install -y hifi-dev-assignment-client apt-get install -y hifi-dev-assignment-client
```
# domain server and assignment clients should already be running. The processes are controlled via: Domain server and assignment clients should already be running. The processes are controlled via:
```
systemctl start hifi-domain-server systemctl start hifi-domain-server
systemctl stop hifi-domain-server systemctl stop hifi-domain-server
```
# Once the machine is setup and processes are running you should ensure that your firewall exposes port 40100 on TCP and all UDP ports. This will get your domain up and running and you could connect to it (for now) by using High Fidelity Interface and typing in the IP for the place name. (further customizations can be done via http://IPAddress:40100). Once the machine is setup and processes are running, you should ensure that your firewall exposes port 40100 on TCP and all UDP ports. This will get your domain up and running and you could connect to it (for now) by using High Fidelity Interface and typing in the IP for the place name. (Further customizations can be done via http://IPAddress:40100).
# The server always depends on both hifi-domain-server and hifi-assignment-client running at the same time. The server always depends on both hifi-domain-server and hifi-assignment-client running at the same time.
# As an additional step, you should ensure that your packages are automatically updated when a new version goes out. You could, for example, set the automatic update checks to happen every hour (though this could potentially result in the domain being unreachable for a whole hour by new clients when they are released - adjust the update checks accordingly). As an additional step, you should ensure that your packages are automatically updated when a new version goes out. You could, for example, set the automatic update checks to happen every hour (though this could potentially result in the domain being unreachable for a whole hour by new clients when they are released - adjust the update checks accordingly).
To do this you can modify /etc/crontab by adding the following lines To do this you can modify /etc/crontab by adding the following lines
```
0 */1 * * * root apt-get update 0 */1 * * * root apt-get update
1 */1 * * * root apt-get install --only-upgrade -y hifi-domain-server 1 */1 * * * root apt-get install --only-upgrade -y hifi-domain-server
2 */1 * * * root apt-get install --only-upgrade -y hifi-assignment-client 2 */1 * * * root apt-get install --only-upgrade -y hifi-assignment-client
```

View file

@ -791,10 +791,19 @@ bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const {
// virtual // virtual
void Avatar::simulateAttachments(float deltaTime) { void Avatar::simulateAttachments(float deltaTime) {
assert(_attachmentModels.size() == _attachmentModelsTexturesLoaded.size());
PerformanceTimer perfTimer("attachments"); PerformanceTimer perfTimer("attachments");
for (int i = 0; i < (int)_attachmentModels.size(); i++) { for (int i = 0; i < (int)_attachmentModels.size(); i++) {
const AttachmentData& attachment = _attachmentData.at(i); const AttachmentData& attachment = _attachmentData.at(i);
auto& model = _attachmentModels.at(i); auto& model = _attachmentModels.at(i);
bool texturesLoaded = _attachmentModelsTexturesLoaded.at(i);
// Watch for texture loading
if (!texturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) {
_attachmentModelsTexturesLoaded[i] = true;
model->updateRenderItems();
}
int jointIndex = getJointIndex(attachment.jointName); int jointIndex = getJointIndex(attachment.jointName);
glm::vec3 jointPosition; glm::vec3 jointPosition;
glm::quat jointRotation; glm::quat jointRotation;
@ -1319,6 +1328,7 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
while ((int)_attachmentModels.size() > attachmentData.size()) { while ((int)_attachmentModels.size() > attachmentData.size()) {
auto attachmentModel = _attachmentModels.back(); auto attachmentModel = _attachmentModels.back();
_attachmentModels.pop_back(); _attachmentModels.pop_back();
_attachmentModelsTexturesLoaded.pop_back();
_attachmentsToRemove.push_back(attachmentModel); _attachmentsToRemove.push_back(attachmentModel);
} }
@ -1326,11 +1336,16 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
if (i == (int)_attachmentModels.size()) { if (i == (int)_attachmentModels.size()) {
// if number of attachments has been increased, we need to allocate a new model // if number of attachments has been increased, we need to allocate a new model
_attachmentModels.push_back(allocateAttachmentModel(attachmentData[i].isSoft, _skeletonModel->getRig(), isMyAvatar())); _attachmentModels.push_back(allocateAttachmentModel(attachmentData[i].isSoft, _skeletonModel->getRig(), isMyAvatar()));
} _attachmentModelsTexturesLoaded.push_back(false);
else if (i < oldAttachmentData.size() && oldAttachmentData[i].isSoft != attachmentData[i].isSoft) { } else if (i < oldAttachmentData.size() && oldAttachmentData[i].isSoft != attachmentData[i].isSoft) {
// if the attachment has changed type, we need to re-allocate a new one. // if the attachment has changed type, we need to re-allocate a new one.
_attachmentsToRemove.push_back(_attachmentModels[i]); _attachmentsToRemove.push_back(_attachmentModels[i]);
_attachmentModels[i] = allocateAttachmentModel(attachmentData[i].isSoft, _skeletonModel->getRig(), isMyAvatar()); _attachmentModels[i] = allocateAttachmentModel(attachmentData[i].isSoft, _skeletonModel->getRig(), isMyAvatar());
_attachmentModelsTexturesLoaded[i] = false;
}
// If the model URL has changd, we need to wait for the textures to load
if (_attachmentModels[i]->getURL() != attachmentData[i].modelURL) {
_attachmentModelsTexturesLoaded[i] = false;
} }
_attachmentModels[i]->setURL(attachmentData[i].modelURL); _attachmentModels[i]->setURL(attachmentData[i].modelURL);
} }

View file

@ -306,6 +306,7 @@ protected:
glm::vec3 _skeletonOffset; glm::vec3 _skeletonOffset;
std::vector<std::shared_ptr<Model>> _attachmentModels; std::vector<std::shared_ptr<Model>> _attachmentModels;
std::vector<bool> _attachmentModelsTexturesLoaded;
std::vector<std::shared_ptr<Model>> _attachmentsToRemove; std::vector<std::shared_ptr<Model>> _attachmentsToRemove;
std::vector<std::shared_ptr<Model>> _attachmentsToDelete; std::vector<std::shared_ptr<Model>> _attachmentsToDelete;

View file

@ -16,10 +16,10 @@
var button; var button;
// Used for animating and disappearing the bubble // Used for animating and disappearing the bubble
var bubbleOverlayTimestamp; var bubbleOverlayTimestamp;
// Used for rate limiting the bubble sound
var lastBubbleSoundTimestamp = 0;
// Used for flashing the HUD button upon activation // Used for flashing the HUD button upon activation
var bubbleButtonFlashState = false; var bubbleButtonFlashState = false;
// Used for flashing the HUD button upon activation
var bubbleButtonTimestamp;
// Affects bubble height // Affects bubble height
var BUBBLE_HEIGHT_SCALE = 0.15; var BUBBLE_HEIGHT_SCALE = 0.15;
// The bubble model itself // The bubble model itself
@ -36,9 +36,11 @@
var bubbleActivateSound = SoundCache.getSound(Script.resolvePath("assets/sounds/bubble.wav")); var bubbleActivateSound = SoundCache.getSound(Script.resolvePath("assets/sounds/bubble.wav"));
// Is the update() function connected? // Is the update() function connected?
var updateConnected = false; var updateConnected = false;
var bubbleFlashTimer = false;
var BUBBLE_VISIBLE_DURATION_MS = 3000; var BUBBLE_VISIBLE_DURATION_MS = 3000;
var BUBBLE_RAISE_ANIMATION_DURATION_MS = 750; var BUBBLE_RAISE_ANIMATION_DURATION_MS = 750;
var BUBBLE_SOUND_RATE_LIMIT_MS = 15000;
// Hides the bubble model overlay and resets the button flash state // Hides the bubble model overlay and resets the button flash state
function hideOverlays() { function hideOverlays() {
@ -50,11 +52,15 @@
// Make the bubble overlay visible, set its position, and play the sound // Make the bubble overlay visible, set its position, and play the sound
function createOverlays() { function createOverlays() {
Audio.playSound(bubbleActivateSound, { var nowTimestamp = Date.now();
position: { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z }, if (nowTimestamp - lastBubbleSoundTimestamp >= BUBBLE_SOUND_RATE_LIMIT_MS) {
localOnly: true, Audio.playSound(bubbleActivateSound, {
volume: 0.2 position: { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z },
}); localOnly: true,
volume: 0.2
});
lastBubbleSoundTimestamp = nowTimestamp;
}
hideOverlays(); hideOverlays();
if (updateConnected === true) { if (updateConnected === true) {
updateConnected = false; updateConnected = false;
@ -80,10 +86,17 @@
}, },
visible: true visible: true
}); });
bubbleOverlayTimestamp = Date.now(); bubbleOverlayTimestamp = nowTimestamp;
bubbleButtonTimestamp = bubbleOverlayTimestamp;
Script.update.connect(update); Script.update.connect(update);
updateConnected = true; updateConnected = true;
// Flash button
if (!bubbleFlashTimer) {
bubbleFlashTimer = Script.setInterval(function () {
writeButtonProperties(bubbleButtonFlashState);
bubbleButtonFlashState = !bubbleButtonFlashState;
}, 500);
}
} }
// Called from the C++ scripting interface to show the bubble overlay // Called from the C++ scripting interface to show the bubble overlay
@ -103,12 +116,6 @@
var delay = (timestamp - bubbleOverlayTimestamp); var delay = (timestamp - bubbleOverlayTimestamp);
var overlayAlpha = 1.0 - (delay / BUBBLE_VISIBLE_DURATION_MS); var overlayAlpha = 1.0 - (delay / BUBBLE_VISIBLE_DURATION_MS);
if (overlayAlpha > 0) { if (overlayAlpha > 0) {
// Flash button
if ((timestamp - bubbleButtonTimestamp) >= BUBBLE_VISIBLE_DURATION_MS) {
writeButtonProperties(bubbleButtonFlashState);
bubbleButtonTimestamp = timestamp;
bubbleButtonFlashState = !bubbleButtonFlashState;
}
if (delay < BUBBLE_RAISE_ANIMATION_DURATION_MS) { if (delay < BUBBLE_RAISE_ANIMATION_DURATION_MS) {
Overlays.editOverlay(bubbleOverlay, { Overlays.editOverlay(bubbleOverlay, {
@ -157,8 +164,11 @@
Script.update.disconnect(update); Script.update.disconnect(update);
updateConnected = false; updateConnected = false;
} }
var bubbleActive = Users.getIgnoreRadiusEnabled(); if (bubbleFlashTimer) {
writeButtonProperties(bubbleActive); Script.clearTimeout(bubbleFlashTimer);
bubbleFlashTimer = false;
}
writeButtonProperties(Users.getIgnoreRadiusEnabled());
} }
} }
@ -166,6 +176,10 @@
// NOTE: the c++ calls this with just the first param -- we added a second // NOTE: the c++ calls this with just the first param -- we added a second
// just for not logging the initial state of the bubble when we startup. // just for not logging the initial state of the bubble when we startup.
function onBubbleToggled(enabled, doNotLog) { function onBubbleToggled(enabled, doNotLog) {
if (bubbleFlashTimer) {
Script.clearTimeout(bubbleFlashTimer);
bubbleFlashTimer = false;
}
writeButtonProperties(enabled); writeButtonProperties(enabled);
if (doNotLog !== true) { if (doNotLog !== true) {
UserActivityLogger.bubbleToggled(enabled); UserActivityLogger.bubbleToggled(enabled);
@ -200,6 +214,10 @@
// Cleanup the tablet button and overlays when script is stopped // Cleanup the tablet button and overlays when script is stopped
Script.scriptEnding.connect(function () { Script.scriptEnding.connect(function () {
button.clicked.disconnect(Users.toggleIgnoreRadius); button.clicked.disconnect(Users.toggleIgnoreRadius);
if (bubbleFlashTimer) {
Script.clearTimeout(bubbleFlashTimer);
bubbleFlashTimer = false;
}
if (tablet) { if (tablet) {
tablet.removeButton(button); tablet.removeButton(button);
} }