mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 09:29:02 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into forget-you
This commit is contained in:
commit
9b61e8c4ad
16 changed files with 176 additions and 55 deletions
|
@ -335,7 +335,8 @@ Item {
|
||||||
upgradeUrl: root.upgradeUrl,
|
upgradeUrl: root.upgradeUrl,
|
||||||
itemHref: root.itemHref,
|
itemHref: root.itemHref,
|
||||||
itemType: root.itemType,
|
itemType: root.itemType,
|
||||||
isInstalled: root.isInstalled
|
isInstalled: root.isInstalled,
|
||||||
|
wornEntityID: root.wornEntityID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -707,6 +707,12 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (msg.method === "updateItemClicked") {
|
} else if (msg.method === "updateItemClicked") {
|
||||||
|
// These three cases are very similar to the conditionals below, under
|
||||||
|
// "if msg.method === "giftAsset". They differ in their popup's wording
|
||||||
|
// and the actions to take when continuing.
|
||||||
|
// I could see an argument for DRYing up this code, but I think the
|
||||||
|
// actions are different enough now and potentially moving forward such that I'm
|
||||||
|
// OK with "somewhat repeating myself".
|
||||||
if (msg.itemType === "app" && msg.isInstalled) {
|
if (msg.itemType === "app" && msg.isInstalled) {
|
||||||
lightboxPopup.titleText = "Uninstall App";
|
lightboxPopup.titleText = "Uninstall App";
|
||||||
lightboxPopup.bodyText = "The app that you are trying to update is installed.<br><br>" +
|
lightboxPopup.bodyText = "The app that you are trying to update is installed.<br><br>" +
|
||||||
|
@ -721,6 +727,35 @@ Rectangle {
|
||||||
sendToScript(msg);
|
sendToScript(msg);
|
||||||
};
|
};
|
||||||
lightboxPopup.visible = true;
|
lightboxPopup.visible = true;
|
||||||
|
} else if (msg.itemType === "wearable" && msg.wornEntityID !== '') {
|
||||||
|
lightboxPopup.titleText = "Remove Wearable";
|
||||||
|
lightboxPopup.bodyText = "You are currently wearing the wearable that you are trying to update.<br><br>" +
|
||||||
|
"If you proceed, this wearable will be removed.";
|
||||||
|
lightboxPopup.button1text = "CANCEL";
|
||||||
|
lightboxPopup.button1method = function() {
|
||||||
|
lightboxPopup.visible = false;
|
||||||
|
}
|
||||||
|
lightboxPopup.button2text = "CONFIRM";
|
||||||
|
lightboxPopup.button2method = function() {
|
||||||
|
Entities.deleteEntity(msg.wornEntityID);
|
||||||
|
purchasesModel.setProperty(index, 'wornEntityID', '');
|
||||||
|
sendToScript(msg);
|
||||||
|
};
|
||||||
|
lightboxPopup.visible = true;
|
||||||
|
} else if (msg.itemType === "avatar" && MyAvatar.skeletonModelURL === msg.itemHref) {
|
||||||
|
lightboxPopup.titleText = "Change Avatar to Default";
|
||||||
|
lightboxPopup.bodyText = "You are currently wearing the avatar that you are trying to update.<br><br>" +
|
||||||
|
"If you proceed, your avatar will be changed to the default avatar.";
|
||||||
|
lightboxPopup.button1text = "CANCEL";
|
||||||
|
lightboxPopup.button1method = function() {
|
||||||
|
lightboxPopup.visible = false;
|
||||||
|
}
|
||||||
|
lightboxPopup.button2text = "CONFIRM";
|
||||||
|
lightboxPopup.button2method = function() {
|
||||||
|
MyAvatar.useFullAvatarURL('');
|
||||||
|
sendToScript(msg);
|
||||||
|
};
|
||||||
|
lightboxPopup.visible = true;
|
||||||
} else {
|
} else {
|
||||||
sendToScript(msg);
|
sendToScript(msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3650,6 +3650,10 @@ bool Application::event(QEvent* event) {
|
||||||
|
|
||||||
bool Application::eventFilter(QObject* object, QEvent* event) {
|
bool Application::eventFilter(QObject* object, QEvent* event) {
|
||||||
|
|
||||||
|
if (_aboutToQuit) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (event->type() == QEvent::Leave) {
|
if (event->type() == QEvent::Leave) {
|
||||||
getApplicationCompositor().handleLeaveEvent();
|
getApplicationCompositor().handleLeaveEvent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,9 +144,19 @@ void AvatarBookmarks::removeBookmark(const QString& bookmarkName) {
|
||||||
emit bookmarkDeleted(bookmarkName);
|
emit bookmarkDeleted(bookmarkName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isWearableEntity(const EntityItemPointer& entity) {
|
||||||
|
return entity->isVisible() && entity->getParentJointIndex() != INVALID_JOINT_INDEX &&
|
||||||
|
(entity->getParentID() == DependencyManager::get<NodeList>()->getSessionUUID() || entity->getParentID() == DependencyManager::get<AvatarManager>()->getMyAvatar()->getSelfID());
|
||||||
|
}
|
||||||
|
|
||||||
void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) {
|
void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) {
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
myAvatar->removeAvatarEntities();
|
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
||||||
|
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
|
||||||
|
myAvatar->removeAvatarEntities([&](const QUuid& entityID) {
|
||||||
|
auto entity = entityTree->findEntityByID(entityID);
|
||||||
|
return entity && isWearableEntity(entity);
|
||||||
|
});
|
||||||
|
|
||||||
addAvatarEntities(avatarEntities);
|
addAvatarEntities(avatarEntities);
|
||||||
}
|
}
|
||||||
|
@ -163,7 +173,12 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) {
|
||||||
QVariantMap bookmark = bookmarkEntry.value().toMap();
|
QVariantMap bookmark = bookmarkEntry.value().toMap();
|
||||||
if (!bookmark.empty()) {
|
if (!bookmark.empty()) {
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
myAvatar->removeAvatarEntities();
|
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
||||||
|
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
|
||||||
|
myAvatar->removeAvatarEntities([&](const QUuid& entityID) {
|
||||||
|
auto entity = entityTree->findEntityByID(entityID);
|
||||||
|
return entity && isWearableEntity(entity);
|
||||||
|
});
|
||||||
const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString();
|
const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString();
|
||||||
myAvatar->useFullAvatarURL(avatarUrl);
|
myAvatar->useFullAvatarURL(avatarUrl);
|
||||||
qCDebug(interfaceapp) << "Avatar On " << avatarUrl;
|
qCDebug(interfaceapp) << "Avatar On " << avatarUrl;
|
||||||
|
@ -233,6 +248,27 @@ QVariantMap AvatarBookmarks::getAvatarDataToBookmark() {
|
||||||
bookmark.insert(ENTRY_AVATAR_URL, avatarUrl);
|
bookmark.insert(ENTRY_AVATAR_URL, avatarUrl);
|
||||||
bookmark.insert(ENTRY_AVATAR_SCALE, avatarScale);
|
bookmark.insert(ENTRY_AVATAR_SCALE, avatarScale);
|
||||||
bookmark.insert(ENTRY_AVATAR_ATTACHMENTS, myAvatar->getAttachmentsVariant());
|
bookmark.insert(ENTRY_AVATAR_ATTACHMENTS, myAvatar->getAttachmentsVariant());
|
||||||
bookmark.insert(ENTRY_AVATAR_ENTITIES, myAvatar->getAvatarEntitiesVariant());
|
|
||||||
|
QScriptEngine scriptEngine;
|
||||||
|
QVariantList wearableEntities;
|
||||||
|
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
||||||
|
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
|
||||||
|
auto avatarEntities = myAvatar->getAvatarEntityData();
|
||||||
|
for (auto entityID : avatarEntities.keys()) {
|
||||||
|
auto entity = entityTree->findEntityByID(entityID);
|
||||||
|
if (!entity || !isWearableEntity(entity)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QVariantMap avatarEntityData;
|
||||||
|
EncodeBitstreamParams params;
|
||||||
|
auto desiredProperties = entity->getEntityProperties(params);
|
||||||
|
desiredProperties += PROP_LOCAL_POSITION;
|
||||||
|
desiredProperties += PROP_LOCAL_ROTATION;
|
||||||
|
EntityItemProperties entityProperties = entity->getProperties(desiredProperties);
|
||||||
|
QScriptValue scriptProperties = EntityItemPropertiesToScriptValue(&scriptEngine, entityProperties);
|
||||||
|
avatarEntityData["properties"] = scriptProperties.toVariant();
|
||||||
|
wearableEntities.append(QVariant(avatarEntityData));
|
||||||
|
}
|
||||||
|
bookmark.insert(ENTRY_AVATAR_ENTITIES, wearableEntities);
|
||||||
return bookmark;
|
return bookmark;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1608,14 +1608,16 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||||
emit skeletonModelURLChanged();
|
emit skeletonModelURLChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::removeAvatarEntities() {
|
void MyAvatar::removeAvatarEntities(const std::function<bool(const QUuid& entityID)>& condition) {
|
||||||
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
||||||
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
|
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
|
||||||
if (entityTree) {
|
if (entityTree) {
|
||||||
entityTree->withWriteLock([&] {
|
entityTree->withWriteLock([&] {
|
||||||
AvatarEntityMap avatarEntities = getAvatarEntityData();
|
AvatarEntityMap avatarEntities = getAvatarEntityData();
|
||||||
for (auto entityID : avatarEntities.keys()) {
|
for (auto entityID : avatarEntities.keys()) {
|
||||||
entityTree->deleteEntity(entityID, true, true);
|
if (!condition || condition(entityID)) {
|
||||||
|
entityTree->deleteEntity(entityID, true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "MyCharacterController.h"
|
#include "MyCharacterController.h"
|
||||||
#include "RingBufferHistory.h"
|
#include "RingBufferHistory.h"
|
||||||
#include <ThreadSafeValueCache.h>
|
#include <ThreadSafeValueCache.h>
|
||||||
|
#include <EntityItem.h>
|
||||||
|
|
||||||
class AvatarActionHold;
|
class AvatarActionHold;
|
||||||
class ModelItemID;
|
class ModelItemID;
|
||||||
|
@ -926,7 +927,7 @@ public:
|
||||||
* @returns {object[]}
|
* @returns {object[]}
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE QVariantList getAvatarEntitiesVariant();
|
Q_INVOKABLE QVariantList getAvatarEntitiesVariant();
|
||||||
void removeAvatarEntities();
|
void removeAvatarEntities(const std::function<bool(const QUuid& entityID)>& condition = {});
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function MyAvatar.isFlying
|
* @function MyAvatar.isFlying
|
||||||
|
|
|
@ -56,6 +56,7 @@ Audio::Audio() : _devices(_contextIsHMD) {
|
||||||
connect(client, &AudioClient::inputVolumeChanged, this, &Audio::setInputVolume);
|
connect(client, &AudioClient::inputVolumeChanged, this, &Audio::setInputVolume);
|
||||||
connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged);
|
connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged);
|
||||||
enableNoiseReduction(enableNoiseReductionSetting.get());
|
enableNoiseReduction(enableNoiseReductionSetting.get());
|
||||||
|
onContextChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Audio::startRecording(const QString& filepath) {
|
bool Audio::startRecording(const QString& filepath) {
|
||||||
|
|
|
@ -27,10 +27,6 @@ ModelOverlay::ModelOverlay()
|
||||||
{
|
{
|
||||||
_model->setLoadingPriority(_loadPriority);
|
_model->setLoadingPriority(_loadPriority);
|
||||||
_isLoaded = false;
|
_isLoaded = false;
|
||||||
|
|
||||||
// Don't show overlay until textures have loaded
|
|
||||||
_visible = false;
|
|
||||||
|
|
||||||
render::ScenePointer scene = qApp->getMain3DScene();
|
render::ScenePointer scene = qApp->getMain3DScene();
|
||||||
_model->setVisibleInScene(false, scene);
|
_model->setVisibleInScene(false, scene);
|
||||||
}
|
}
|
||||||
|
@ -136,11 +132,13 @@ void ModelOverlay::update(float deltatime) {
|
||||||
}
|
}
|
||||||
scene->enqueueTransaction(transaction);
|
scene->enqueueTransaction(transaction);
|
||||||
|
|
||||||
|
if (_texturesDirty && !_modelTextures.isEmpty()) {
|
||||||
|
_texturesDirty = false;
|
||||||
|
_model->setTextures(_modelTextures);
|
||||||
|
}
|
||||||
|
|
||||||
if (!_texturesLoaded && _model->getGeometry() && _model->getGeometry()->areTexturesLoaded()) {
|
if (!_texturesLoaded && _model->getGeometry() && _model->getGeometry()->areTexturesLoaded()) {
|
||||||
_texturesLoaded = true;
|
_texturesLoaded = true;
|
||||||
if (!_modelTextures.isEmpty()) {
|
|
||||||
_model->setTextures(_modelTextures);
|
|
||||||
}
|
|
||||||
|
|
||||||
_model->setVisibleInScene(getVisible(), scene);
|
_model->setVisibleInScene(getVisible(), scene);
|
||||||
_model->updateRenderItems();
|
_model->updateRenderItems();
|
||||||
|
@ -242,6 +240,7 @@ void ModelOverlay::setProperties(const QVariantMap& properties) {
|
||||||
_texturesLoaded = false;
|
_texturesLoaded = false;
|
||||||
QVariantMap textureMap = texturesValue.toMap();
|
QVariantMap textureMap = texturesValue.toMap();
|
||||||
_modelTextures = textureMap;
|
_modelTextures = textureMap;
|
||||||
|
_texturesDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto groupCulledValue = properties["isGroupCulled"];
|
auto groupCulledValue = properties["isGroupCulled"];
|
||||||
|
|
|
@ -94,6 +94,7 @@ private:
|
||||||
ModelPointer _model;
|
ModelPointer _model;
|
||||||
QVariantMap _modelTextures;
|
QVariantMap _modelTextures;
|
||||||
bool _texturesLoaded { false };
|
bool _texturesLoaded { false };
|
||||||
|
bool _texturesDirty { false };
|
||||||
|
|
||||||
render::ItemIDs _subRenderItemIDs;
|
render::ItemIDs _subRenderItemIDs;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
set(TARGET_NAME audio-client)
|
set(TARGET_NAME audio-client)
|
||||||
setup_hifi_library(Network Multimedia)
|
if (ANDROID)
|
||||||
|
set(PLATFORM_QT_COMPONENTS AndroidExtras)
|
||||||
|
endif ()
|
||||||
|
setup_hifi_library(Network Multimedia ${PLATFORM_QT_COMPONENTS})
|
||||||
link_hifi_libraries(audio plugins)
|
link_hifi_libraries(audio plugins)
|
||||||
include_hifi_library_headers(shared)
|
include_hifi_library_headers(shared)
|
||||||
include_hifi_library_headers(networking)
|
include_hifi_library_headers(networking)
|
||||||
|
|
|
@ -52,6 +52,10 @@
|
||||||
#include "AudioLogging.h"
|
#include "AudioLogging.h"
|
||||||
#include "AudioHelpers.h"
|
#include "AudioHelpers.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
#include <QtAndroidExtras/QAndroidJniObject>
|
||||||
|
#endif
|
||||||
|
|
||||||
const int AudioClient::MIN_BUFFER_FRAMES = 1;
|
const int AudioClient::MIN_BUFFER_FRAMES = 1;
|
||||||
|
|
||||||
const int AudioClient::MAX_BUFFER_FRAMES = 20;
|
const int AudioClient::MAX_BUFFER_FRAMES = 20;
|
||||||
|
@ -60,7 +64,7 @@ static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100;
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
static const int CHECK_INPUT_READS_MSECS = 2000;
|
static const int CHECK_INPUT_READS_MSECS = 2000;
|
||||||
static const int MIN_READS_TO_CONSIDER_INPUT_ALIVE = 100;
|
static const int MIN_READS_TO_CONSIDER_INPUT_ALIVE = 10;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const auto DEFAULT_POSITION_GETTER = []{ return Vectors::ZERO; };
|
static const auto DEFAULT_POSITION_GETTER = []{ return Vectors::ZERO; };
|
||||||
|
@ -235,7 +239,7 @@ AudioClient::AudioClient() :
|
||||||
|
|
||||||
// start a thread to detect any device changes
|
// start a thread to detect any device changes
|
||||||
_checkDevicesTimer = new QTimer(this);
|
_checkDevicesTimer = new QTimer(this);
|
||||||
connect(_checkDevicesTimer, &QTimer::timeout, [this] {
|
connect(_checkDevicesTimer, &QTimer::timeout, this, [this] {
|
||||||
QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkDevices(); });
|
QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkDevices(); });
|
||||||
});
|
});
|
||||||
const unsigned long DEVICE_CHECK_INTERVAL_MSECS = 2 * 1000;
|
const unsigned long DEVICE_CHECK_INTERVAL_MSECS = 2 * 1000;
|
||||||
|
@ -243,7 +247,7 @@ AudioClient::AudioClient() :
|
||||||
|
|
||||||
// start a thread to detect peak value changes
|
// start a thread to detect peak value changes
|
||||||
_checkPeakValuesTimer = new QTimer(this);
|
_checkPeakValuesTimer = new QTimer(this);
|
||||||
connect(_checkPeakValuesTimer, &QTimer::timeout, [this] {
|
connect(_checkPeakValuesTimer, &QTimer::timeout, this, [this] {
|
||||||
QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkPeakValues(); });
|
QtConcurrent::run(QThreadPool::globalInstance(), [this] { checkPeakValues(); });
|
||||||
});
|
});
|
||||||
const unsigned long PEAK_VALUES_CHECK_INTERVAL_MSECS = 50;
|
const unsigned long PEAK_VALUES_CHECK_INTERVAL_MSECS = 50;
|
||||||
|
@ -482,6 +486,15 @@ bool nativeFormatForAudioDevice(const QAudioDeviceInfo& audioDevice,
|
||||||
audioFormat.setSampleType(QAudioFormat::SignedInt);
|
audioFormat.setSampleType(QAudioFormat::SignedInt);
|
||||||
audioFormat.setByteOrder(QAudioFormat::LittleEndian);
|
audioFormat.setByteOrder(QAudioFormat::LittleEndian);
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
// Using the HW sample rate (AUDIO_INPUT_FLAG_FAST) in some samsung phones causes a low volume at input stream
|
||||||
|
// Changing the sample rate forces a resampling that (in samsung) amplifies +18 dB
|
||||||
|
QAndroidJniObject brand = QAndroidJniObject::getStaticObjectField<jstring>("android/os/Build", "BRAND");
|
||||||
|
if (audioDevice == QAudioDeviceInfo::defaultInputDevice() && brand.toString().contains("samsung", Qt::CaseInsensitive)) {
|
||||||
|
audioFormat.setSampleRate(24000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!audioDevice.isFormatSupported(audioFormat)) {
|
if (!audioDevice.isFormatSupported(audioFormat)) {
|
||||||
qCWarning(audioclient) << "The native format is" << audioFormat << "but isFormatSupported() failed.";
|
qCWarning(audioclient) << "The native format is" << audioFormat << "but isFormatSupported() failed.";
|
||||||
return false;
|
return false;
|
||||||
|
@ -635,9 +648,7 @@ void AudioClient::start() {
|
||||||
qCDebug(audioclient) << "The closest format available is" << outputDeviceInfo.nearestFormat(_desiredOutputFormat);
|
qCDebug(audioclient) << "The closest format available is" << outputDeviceInfo.nearestFormat(_desiredOutputFormat);
|
||||||
}
|
}
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
connect(&_checkInputTimer, &QTimer::timeout, [this] {
|
connect(&_checkInputTimer, &QTimer::timeout, this, &AudioClient::checkInputTimeout);
|
||||||
checkInputTimeout();
|
|
||||||
});
|
|
||||||
_checkInputTimer.start(CHECK_INPUT_READS_MSECS);
|
_checkInputTimer.start(CHECK_INPUT_READS_MSECS);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -651,6 +662,7 @@ void AudioClient::stop() {
|
||||||
switchOutputToAudioDevice(QAudioDeviceInfo(), true);
|
switchOutputToAudioDevice(QAudioDeviceInfo(), true);
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
_checkInputTimer.stop();
|
_checkInputTimer.stop();
|
||||||
|
disconnect(&_checkInputTimer, &QTimer::timeout, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1558,9 +1570,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
if (_audioInput) {
|
if (_audioInput) {
|
||||||
_shouldRestartInputSetup = true;
|
_shouldRestartInputSetup = true;
|
||||||
connect(_audioInput, &QAudioInput::stateChanged, [this](QAudio::State state) {
|
connect(_audioInput, &QAudioInput::stateChanged, this, &AudioClient::audioInputStateChanged);
|
||||||
audioInputStateChanged(state);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
_inputDevice = _audioInput->start();
|
_inputDevice = _audioInput->start();
|
||||||
|
@ -1764,7 +1774,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI
|
||||||
_outputScratchBuffer = new int16_t[_outputPeriod];
|
_outputScratchBuffer = new int16_t[_outputPeriod];
|
||||||
|
|
||||||
// size local output mix buffer based on resampled network frame size
|
// size local output mix buffer based on resampled network frame size
|
||||||
int networkPeriod = _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO);
|
int networkPeriod = _localToOutputResampler ? _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO) : AudioConstants::NETWORK_FRAME_SAMPLES_STEREO;
|
||||||
_localOutputMixBuffer = new float[networkPeriod];
|
_localOutputMixBuffer = new float[networkPeriod];
|
||||||
|
|
||||||
// local period should be at least twice the output period,
|
// local period should be at least twice the output period,
|
||||||
|
|
|
@ -84,9 +84,15 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type,
|
||||||
EntityTreePointer entityTree,
|
EntityTreePointer entityTree,
|
||||||
EntityItemID entityItemID,
|
EntityItemID entityItemID,
|
||||||
const EntityItemProperties& properties) {
|
const EntityItemProperties& properties) {
|
||||||
if (properties.getClientOnly() && properties.getOwningAvatarID() == _myAvatar->getID()) {
|
if (properties.getClientOnly()) {
|
||||||
// this is an avatar-based entity --> update our avatar-data rather than sending to the entity-server
|
if (!_myAvatar) {
|
||||||
queueEditAvatarEntityMessage(type, entityTree, entityItemID, properties);
|
qCWarning(entities) << "Suppressing entity edit message: cannot send clientOnly edit with no myAvatar";
|
||||||
|
} else if (properties.getOwningAvatarID() == _myAvatar->getID()) {
|
||||||
|
// this is an avatar-based entity --> update our avatar-data rather than sending to the entity-server
|
||||||
|
queueEditAvatarEntityMessage(type, entityTree, entityItemID, properties);
|
||||||
|
} else {
|
||||||
|
qCWarning(entities) << "Suppressing entity edit message: cannot send clientOnly edit for another avatar";
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,7 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc
|
||||||
|
|
||||||
if (bytesWritten < 0) {
|
if (bytesWritten < 0) {
|
||||||
// when saturating a link this isn't an uncommon message - suppress it so it doesn't bomb the debug
|
// when saturating a link this isn't an uncommon message - suppress it so it doesn't bomb the debug
|
||||||
HIFI_FCDEBUG(networking(), "Socket::writeDatagram" << _udpSocket.error() << "-" << qPrintable(_udpSocket.errorString()) );
|
HIFI_FCDEBUG(networking(), "Socket::writeDatagram" << _udpSocket.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
|
@ -513,7 +513,7 @@ std::vector<HifiSockAddr> Socket::getConnectionSockAddrs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Socket::handleSocketError(QAbstractSocket::SocketError socketError) {
|
void Socket::handleSocketError(QAbstractSocket::SocketError socketError) {
|
||||||
HIFI_FCDEBUG(networking(), "udt::Socket error - " << socketError << _udpSocket.errorString());
|
HIFI_FCDEBUG(networking(), "udt::Socket error - " << socketError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) {
|
void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) {
|
||||||
|
|
|
@ -29,13 +29,25 @@ function executeLater(callback) {
|
||||||
Script.setTimeout(callback, 300);
|
Script.setTimeout(callback, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMyAvatarWearables() {
|
var INVALID_JOINT_INDEX = -1
|
||||||
var wearablesArray = MyAvatar.getAvatarEntitiesVariant();
|
function isWearable(avatarEntity) {
|
||||||
|
return avatarEntity.properties.visible === true && avatarEntity.properties.parentJointIndex !== INVALID_JOINT_INDEX &&
|
||||||
|
(avatarEntity.properties.parentID === MyAvatar.sessionUUID || avatarEntity.properties.parentID === MyAvatar.SELF_ID);
|
||||||
|
}
|
||||||
|
|
||||||
for(var i = 0; i < wearablesArray.length; ++i) {
|
function getMyAvatarWearables() {
|
||||||
var wearable = wearablesArray[i];
|
var entitiesArray = MyAvatar.getAvatarEntitiesVariant();
|
||||||
var localRotation = wearable.properties.localRotation;
|
var wearablesArray = [];
|
||||||
wearable.properties.localRotationAngles = Quat.safeEulerAngles(localRotation)
|
|
||||||
|
for (var i = 0; i < entitiesArray.length; ++i) {
|
||||||
|
var entity = entitiesArray[i];
|
||||||
|
if (!isWearable(entity)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var localRotation = entity.properties.localRotation;
|
||||||
|
entity.properties.localRotationAngles = Quat.safeEulerAngles(localRotation)
|
||||||
|
wearablesArray.push(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wearablesArray;
|
return wearablesArray;
|
||||||
|
@ -443,10 +455,6 @@ startup();
|
||||||
|
|
||||||
var isWired = false;
|
var isWired = false;
|
||||||
function off() {
|
function off() {
|
||||||
if (isWired) { // It is not ok to disconnect these twice, hence guard.
|
|
||||||
isWired = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(adjustWearables.opened) {
|
if(adjustWearables.opened) {
|
||||||
adjustWearables.setOpened(false);
|
adjustWearables.setOpened(false);
|
||||||
ensureWearableSelected(null);
|
ensureWearableSelected(null);
|
||||||
|
@ -456,16 +464,20 @@ function off() {
|
||||||
Messages.unsubscribe('Hifi-Object-Manipulation');
|
Messages.unsubscribe('Hifi-Object-Manipulation');
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarBookmarks.bookmarkLoaded.disconnect(onBookmarkLoaded);
|
if (isWired) { // It is not ok to disconnect these twice, hence guard.
|
||||||
AvatarBookmarks.bookmarkDeleted.disconnect(onBookmarkDeleted);
|
isWired = false;
|
||||||
AvatarBookmarks.bookmarkAdded.disconnect(onBookmarkAdded);
|
|
||||||
|
|
||||||
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
|
AvatarBookmarks.bookmarkLoaded.disconnect(onBookmarkLoaded);
|
||||||
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
|
AvatarBookmarks.bookmarkDeleted.disconnect(onBookmarkDeleted);
|
||||||
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
|
AvatarBookmarks.bookmarkAdded.disconnect(onBookmarkAdded);
|
||||||
MyAvatar.newCollisionSoundURL.disconnect(onNewCollisionSoundUrl);
|
|
||||||
MyAvatar.animGraphUrlChanged.disconnect(onAnimGraphUrlChanged);
|
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
|
||||||
MyAvatar.targetScaleChanged.disconnect(onTargetScaleChanged);
|
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
|
||||||
|
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
|
||||||
|
MyAvatar.newCollisionSoundURL.disconnect(onNewCollisionSoundUrl);
|
||||||
|
MyAvatar.animGraphUrlChanged.disconnect(onAnimGraphUrlChanged);
|
||||||
|
MyAvatar.targetScaleChanged.disconnect(onTargetScaleChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function on() {
|
function on() {
|
||||||
|
|
|
@ -263,7 +263,7 @@ SelectionManager = (function() {
|
||||||
|
|
||||||
that.worldDimensions = properties.boundingBox.dimensions;
|
that.worldDimensions = properties.boundingBox.dimensions;
|
||||||
that.worldPosition = properties.boundingBox.center;
|
that.worldPosition = properties.boundingBox.center;
|
||||||
that.worldRotation = properties.boundingBox.rotation;
|
that.worldRotation = Quat.IDENTITY;
|
||||||
|
|
||||||
that.entityType = properties.type;
|
that.entityType = properties.type;
|
||||||
|
|
||||||
|
@ -271,10 +271,6 @@ SelectionManager = (function() {
|
||||||
SelectionDisplay.setSpaceMode(SPACE_LOCAL);
|
SelectionDisplay.setSpaceMode(SPACE_LOCAL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
that.localRotation = null;
|
|
||||||
that.localDimensions = null;
|
|
||||||
that.localPosition = null;
|
|
||||||
|
|
||||||
properties = Entities.getEntityProperties(that.selections[0]);
|
properties = Entities.getEntityProperties(that.selections[0]);
|
||||||
|
|
||||||
that.entityType = properties.type;
|
that.entityType = properties.type;
|
||||||
|
@ -293,6 +289,7 @@ SelectionManager = (function() {
|
||||||
tfl.z = Math.max(bb.tfl.z, tfl.z);
|
tfl.z = Math.max(bb.tfl.z, tfl.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
that.localRotation = null;
|
||||||
that.localDimensions = null;
|
that.localDimensions = null;
|
||||||
that.localPosition = null;
|
that.localPosition = null;
|
||||||
that.worldDimensions = {
|
that.worldDimensions = {
|
||||||
|
@ -300,6 +297,7 @@ SelectionManager = (function() {
|
||||||
y: tfl.y - brn.y,
|
y: tfl.y - brn.y,
|
||||||
z: tfl.z - brn.z
|
z: tfl.z - brn.z
|
||||||
};
|
};
|
||||||
|
that.worldRotation = Quat.IDENTITY;
|
||||||
that.worldPosition = {
|
that.worldPosition = {
|
||||||
x: brn.x + (that.worldDimensions.x / 2),
|
x: brn.x + (that.worldDimensions.x / 2),
|
||||||
y: brn.y + (that.worldDimensions.y / 2),
|
y: brn.y + (that.worldDimensions.y / 2),
|
||||||
|
|
|
@ -279,9 +279,21 @@ function onMessage(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var POLAROID_PRINT_SOUND = SoundCache.getSound(Script.resourcesPath() + "sounds/snapshot/sound-print-photo.wav");
|
var POLAROID_PRINT_SOUND = SoundCache.getSound(Script.resourcesPath() + "sounds/snapshot/sound-print-photo.wav");
|
||||||
var POLAROID_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/alan/dev/Test/snapshot.fbx';
|
var POLAROID_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/alan/dev/Test/snapshot.fbx';
|
||||||
|
var POLAROID_RATE_LIMIT_MS = 1000;
|
||||||
|
var polaroidPrintingIsRateLimited = false;
|
||||||
|
|
||||||
function printToPolaroid(image_url) {
|
function printToPolaroid(image_url) {
|
||||||
|
|
||||||
|
// Rate-limit printing
|
||||||
|
if (polaroidPrintingIsRateLimited) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
polaroidPrintingIsRateLimited = true;
|
||||||
|
Script.setTimeout(function () {
|
||||||
|
polaroidPrintingIsRateLimited = false;
|
||||||
|
}, POLAROID_RATE_LIMIT_MS);
|
||||||
|
|
||||||
var polaroid_url = image_url;
|
var polaroid_url = image_url;
|
||||||
|
|
||||||
var model_pos = Vec3.sum(MyAvatar.position, Vec3.multiply(1.25, Quat.getForward(MyAvatar.orientation)));
|
var model_pos = Vec3.sum(MyAvatar.position, Vec3.multiply(1.25, Quat.getForward(MyAvatar.orientation)));
|
||||||
|
|
Loading…
Reference in a new issue