mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 00:13:53 +02:00
Merge pull request #2 from danteruiz/interstitalMerged
Dev review requests
This commit is contained in:
commit
07bda90519
10 changed files with 80 additions and 84 deletions
|
@ -1387,7 +1387,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
});
|
||||
connect(this, &Application::activeDisplayPluginChanged,
|
||||
reinterpret_cast<scripting::Audio*>(audioScriptingInterface.data()), &scripting::Audio::onContextChanged);
|
||||
connect(this, &Application::interstitialModeChanged, audioIO, &AudioClient::setInterstitialStatus);
|
||||
}
|
||||
|
||||
// Create the rendering engine. This can be slow on some machines due to lots of
|
||||
|
@ -2295,25 +2294,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Preload Tablet sounds
|
||||
DependencyManager::get<TabletScriptingInterface>()->preloadSounds();
|
||||
|
||||
connect(this, &Application::interstitialModeChanged, this, [this] (bool interstitialMode) {
|
||||
if (!interstitialMode) {
|
||||
DependencyManager::get<AudioClient>()->negotiateAudioFormat();
|
||||
_queryExpiry = SteadyClock::now();
|
||||
if (_avatarOverrideUrl.isValid()) {
|
||||
getMyAvatar()->useFullAvatarURL(_avatarOverrideUrl);
|
||||
}
|
||||
|
||||
if (getMyAvatar()->getFullAvatarURLFromPreferences() != getMyAvatar()->getSkeletonModelURL()) {
|
||||
getMyAvatar()->resetFullAvatarURL();
|
||||
}
|
||||
getMyAvatar()->markIdentityDataChanged();
|
||||
getMyAvatar()->resetLastSent();
|
||||
|
||||
// transmit a "sendAll" packet to the AvatarMixer we just connected to.
|
||||
getMyAvatar()->sendAvatarDataPacket(true);
|
||||
}
|
||||
});
|
||||
|
||||
_pendingIdleEvent = false;
|
||||
_pendingRenderEvent = false;
|
||||
|
||||
|
@ -3496,6 +3476,10 @@ bool Application::isServerlessMode() const {
|
|||
void Application::setIsInterstitialMode(bool interstitialMode) {
|
||||
if (_interstitialMode != interstitialMode) {
|
||||
_interstitialMode = interstitialMode;
|
||||
|
||||
DependencyManager::get<AudioClient>()->setAudioPaused(_interstitialMode);
|
||||
DependencyManager::get<AvatarManager>()->setMyAvatarDataPacketsPaused(_interstitialMode);
|
||||
|
||||
emit interstitialModeChanged(_interstitialMode);
|
||||
}
|
||||
}
|
||||
|
@ -5577,8 +5561,7 @@ void Application::update(float deltaTime) {
|
|||
// we haven't yet enabled physics. we wait until we think we have all the collision information
|
||||
// for nearby entities before starting bullet up.
|
||||
quint64 now = usecTimestampNow();
|
||||
bool renderReady = _octreeProcessor.isEntitiesRenderReady();
|
||||
if (isServerlessMode() || (_octreeProcessor.isLoadSequenceComplete() && renderReady)) {
|
||||
if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) {
|
||||
// we've received a new full-scene octree stats packet, or it's been long enough to try again anyway
|
||||
_lastPhysicsCheckTime = now;
|
||||
_fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter;
|
||||
|
@ -6476,7 +6459,7 @@ void Application::nodeActivated(SharedNodePointer node) {
|
|||
DependencyManager::get<AudioClient>()->negotiateAudioFormat();
|
||||
}
|
||||
|
||||
if (node->getType() == NodeType::AvatarMixer && !isInterstitialMode()) {
|
||||
if (node->getType() == NodeType::AvatarMixer) {
|
||||
_queryExpiry = SteadyClock::now();
|
||||
|
||||
// new avatar mixer, send off our identity packet on next update loop
|
||||
|
@ -6492,8 +6475,10 @@ void Application::nodeActivated(SharedNodePointer node) {
|
|||
getMyAvatar()->markIdentityDataChanged();
|
||||
getMyAvatar()->resetLastSent();
|
||||
|
||||
// transmit a "sendAll" packet to the AvatarMixer we just connected to.
|
||||
getMyAvatar()->sendAvatarDataPacket(true);
|
||||
if (!isInterstitialMode()) {
|
||||
// transmit a "sendAll" packet to the AvatarMixer we just connected to.
|
||||
getMyAvatar()->sendAvatarDataPacket(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ void AvatarManager::updateMyAvatar(float deltaTime) {
|
|||
quint64 now = usecTimestampNow();
|
||||
quint64 dt = now - _lastSendAvatarDataTime;
|
||||
|
||||
if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !qApp->isInterstitialMode()) {
|
||||
if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused) {
|
||||
// send head/hand data to the avatar mixer and voxel server
|
||||
PerformanceTimer perfTimer("send");
|
||||
_myAvatar->sendAvatarDataPacket();
|
||||
|
@ -155,6 +155,16 @@ float AvatarManager::getAvatarDataRate(const QUuid& sessionID, const QString& ra
|
|||
return avatar ? avatar->getDataRate(rateName) : 0.0f;
|
||||
}
|
||||
|
||||
void AvatarManager::setMyAvatarDataPacketsPaused(bool pause) {
|
||||
if (_myAvatarDataPacketsPaused != pause) {
|
||||
_myAvatarDataPacketsPaused = pause;
|
||||
|
||||
if (!_myAvatarDataPacketsPaused) {
|
||||
_myAvatar->sendAvatarDataPacket(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AvatarManager::getAvatarUpdateRate(const QUuid& sessionID, const QString& rateName) const {
|
||||
auto avatar = getAvatarBySessionID(sessionID);
|
||||
return avatar ? avatar->getUpdateRate(rateName) : 0.0f;
|
||||
|
|
|
@ -91,6 +91,8 @@ public:
|
|||
void updateOtherAvatars(float deltaTime);
|
||||
void sendIdentityRequest(const QUuid& avatarID) const;
|
||||
|
||||
void setMyAvatarDataPacketsPaused(bool puase);
|
||||
|
||||
void postUpdate(float deltaTime, const render::ScenePointer& scene);
|
||||
|
||||
void clearOtherAvatars();
|
||||
|
@ -219,6 +221,7 @@ private:
|
|||
int _numAvatarsNotUpdated { 0 };
|
||||
float _avatarSimulationTime { 0.0f };
|
||||
bool _shouldRender { true };
|
||||
bool _myAvatarDataPacketsPaused { false };
|
||||
mutable int _identityRequestsSent { 0 };
|
||||
|
||||
mutable std::mutex _spaceLock;
|
||||
|
|
|
@ -131,4 +131,4 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
|
|||
|
||||
void OctreePacketProcessor::startEntitySequence() {
|
||||
_safeLanding->startEntitySequence(qApp->getEntities());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ public:
|
|||
|
||||
void startEntitySequence();
|
||||
bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); }
|
||||
bool isEntitiesRenderReady() const { return _safeLanding->entitiesRenderReady(); }
|
||||
float domainLoadingProgress() { return _safeLanding->loadingProgressPercentage(); }
|
||||
|
||||
signals:
|
||||
void packetVersionMismatch();
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityT
|
|||
if (entityTree) {
|
||||
Locker lock(_lock);
|
||||
_entityTree = entityTree;
|
||||
_trackedEntitiesRenderStatus.clear();
|
||||
_trackedEntities.clear();
|
||||
_trackingEntities = true;
|
||||
connect(std::const_pointer_cast<EntityTree>(_entityTree).get(),
|
||||
|
@ -67,35 +66,19 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) {
|
|||
Locker lock(_lock);
|
||||
EntityItemPointer entity = _entityTree->findEntityByID(entityID);
|
||||
|
||||
if (entity && !entity->getCollisionless()) {
|
||||
const auto& entityType = entity->getType();
|
||||
if (entityType == EntityTypes::Model) {
|
||||
ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get();
|
||||
static const std::set<ShapeType> downloadedCollisionTypes
|
||||
{ SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL };
|
||||
bool hasAABox;
|
||||
entity->getAABox(hasAABox);
|
||||
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
||||
// Only track entities with downloaded collision bodies.
|
||||
_trackedEntities.emplace(entityID, entity);
|
||||
qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_trackedEntitiesRenderStatus.emplace(entityID, entity);
|
||||
float trackedEntityCount = (float)_trackedEntitiesRenderStatus.size();
|
||||
_trackedEntities.emplace(entityID, entity);
|
||||
int trackedEntityCount = _trackedEntities.size();
|
||||
|
||||
if (trackedEntityCount > _maxTrackedEntityCount) {
|
||||
_maxTrackedEntityCount = trackedEntityCount;
|
||||
}
|
||||
qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
|
||||
}
|
||||
}
|
||||
|
||||
void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) {
|
||||
Locker lock(_lock);
|
||||
_trackedEntities.erase(entityID);
|
||||
_trackedEntitiesRenderStatus.erase(entityID);
|
||||
}
|
||||
|
||||
void SafeLanding::setCompletionSequenceNumbers(int first, int last) {
|
||||
|
@ -114,7 +97,7 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) {
|
|||
}
|
||||
|
||||
bool SafeLanding::isLoadSequenceComplete() {
|
||||
if (isEntityPhysicsComplete() && isSequenceNumbersComplete()) {
|
||||
if (isEntityLoadingComplete() && isSequenceNumbersComplete()) {
|
||||
Locker lock(_lock);
|
||||
_trackedEntities.clear();
|
||||
_initialStart = INVALID_SEQUENCE;
|
||||
|
@ -130,7 +113,7 @@ bool SafeLanding::isLoadSequenceComplete() {
|
|||
float SafeLanding::loadingProgressPercentage() {
|
||||
Locker lock(_lock);
|
||||
if (_maxTrackedEntityCount > 0) {
|
||||
return ((_maxTrackedEntityCount - _trackedEntitiesRenderStatus.size()) / (float)_maxTrackedEntityCount);
|
||||
return ((_maxTrackedEntityCount - _trackedEntities.size()) / (float)_maxTrackedEntityCount);
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
|
@ -154,38 +137,45 @@ bool SafeLanding::isSequenceNumbersComplete() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SafeLanding::isEntityPhysicsComplete() {
|
||||
Locker lock(_lock);
|
||||
for (auto entityMapIter = _trackedEntities.begin(); entityMapIter != _trackedEntities.end(); ++entityMapIter) {
|
||||
auto entity = entityMapIter->second;
|
||||
if (!entity->shouldBePhysical() || entity->isReadyToComputeShape()) {
|
||||
entityMapIter = _trackedEntities.erase(entityMapIter);
|
||||
if (entityMapIter == _trackedEntities.end()) {
|
||||
break;
|
||||
bool isEntityPhysicsReady(const EntityItemPointer& entity) {
|
||||
if (entity && !entity->getCollisionless()) {
|
||||
const auto& entityType = entity->getType();
|
||||
if (entityType == EntityTypes::Model) {
|
||||
ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get();
|
||||
static const std::set<ShapeType> downloadedCollisionTypes
|
||||
{ SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL };
|
||||
bool hasAABox;
|
||||
entity->getAABox(hasAABox);
|
||||
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
||||
return entity->isReadyToComputeShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SafeLanding::isEntityLoadingComplete() {
|
||||
Locker lock(_lock);
|
||||
auto entityTree = qApp->getEntities();
|
||||
auto entityMapIter = _trackedEntities.begin();
|
||||
|
||||
while (entityMapIter != _trackedEntities.end()) {
|
||||
auto entity = entityMapIter->second;
|
||||
bool isVisuallyReady = (entity->isVisuallyReady() || !entityTree->renderableForEntityId(entityMapIter->first));
|
||||
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
|
||||
entityMapIter = _trackedEntities.erase(entityMapIter);
|
||||
} else {
|
||||
if (!isVisuallyReady) {
|
||||
entity->requestRenderUpdate();
|
||||
}
|
||||
|
||||
entityMapIter++;
|
||||
}
|
||||
}
|
||||
return _trackedEntities.empty();
|
||||
}
|
||||
|
||||
bool SafeLanding::entitiesRenderReady() {
|
||||
Locker lock(_lock);
|
||||
auto entityTree = qApp->getEntities();
|
||||
for (auto entityMapIter = _trackedEntitiesRenderStatus.begin(); entityMapIter != _trackedEntitiesRenderStatus.end(); ++entityMapIter) {
|
||||
auto entity = entityMapIter->second;
|
||||
bool visuallyReady = entity->isVisuallyReady();
|
||||
if (visuallyReady || !entityTree->renderableForEntityId(entityMapIter->first)) {
|
||||
entityMapIter = _trackedEntitiesRenderStatus.erase(entityMapIter);
|
||||
if (entityMapIter == _trackedEntitiesRenderStatus.end()) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
entity->requestRenderUpdate();
|
||||
}
|
||||
}
|
||||
return _trackedEntitiesRenderStatus.empty();
|
||||
}
|
||||
|
||||
float SafeLanding::ElevatedPriority(const EntityItem& entityItem) {
|
||||
return entityItem.getCollisionless() ? 0.0f : 10.0f;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ public:
|
|||
void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive.
|
||||
void noteReceivedsequenceNumber(int sequenceNumber);
|
||||
bool isLoadSequenceComplete();
|
||||
bool entitiesRenderReady();
|
||||
float loadingProgressPercentage();
|
||||
|
||||
private slots:
|
||||
|
@ -40,7 +39,7 @@ private slots:
|
|||
private:
|
||||
bool isSequenceNumbersComplete();
|
||||
void debugDumpSequenceIDs() const;
|
||||
bool isEntityPhysicsComplete();
|
||||
bool isEntityLoadingComplete();
|
||||
|
||||
std::mutex _lock;
|
||||
using Locker = std::lock_guard<std::mutex>;
|
||||
|
@ -48,12 +47,11 @@ private:
|
|||
EntityTreePointer _entityTree;
|
||||
using EntityMap = std::map<EntityItemID, EntityItemPointer>;
|
||||
EntityMap _trackedEntities;
|
||||
EntityMap _trackedEntitiesRenderStatus;
|
||||
|
||||
static constexpr int INVALID_SEQUENCE = -1;
|
||||
int _initialStart { INVALID_SEQUENCE };
|
||||
int _initialEnd { INVALID_SEQUENCE };
|
||||
float _maxTrackedEntityCount { 0.0f };
|
||||
int _maxTrackedEntityCount { 0 };
|
||||
|
||||
struct SequenceLessThan {
|
||||
bool operator()(const int& a, const int& b) const;
|
||||
|
|
|
@ -305,6 +305,16 @@ void AudioClient::audioMixerKilled() {
|
|||
emit disconnected();
|
||||
}
|
||||
|
||||
void AudioClient::setAudioPaused(bool pause) {
|
||||
if (_audioPaused != pause) {
|
||||
_audioPaused = pause;
|
||||
|
||||
if (!_audioPaused) {
|
||||
negotiateAudioFormat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) {
|
||||
QAudioDeviceInfo result;
|
||||
foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) {
|
||||
|
@ -1024,7 +1034,7 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
|||
}
|
||||
|
||||
void AudioClient::handleAudioInput(QByteArray& audioBuffer) {
|
||||
if (!_interstitialMode) {
|
||||
if (!_audioPaused) {
|
||||
if (_muted) {
|
||||
_lastInputLoudness = 0.0f;
|
||||
_timeSinceLastClip = 0.0f;
|
||||
|
|
|
@ -162,6 +162,7 @@ public:
|
|||
|
||||
bool startRecording(const QString& filename);
|
||||
void stopRecording();
|
||||
void setAudioPaused(bool pause);
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -187,7 +188,6 @@ public slots:
|
|||
void handleRecordedAudioInput(const QByteArray& audio);
|
||||
void reset();
|
||||
void audioMixerKilled();
|
||||
void setInterstitialStatus(bool interstitialMode) { _interstitialMode = interstitialMode; }
|
||||
|
||||
void setMuted(bool muted, bool emitSignal = true);
|
||||
bool isMuted() { return _muted; }
|
||||
|
@ -417,7 +417,7 @@ private:
|
|||
QVector<AudioInjectorPointer> _activeLocalAudioInjectors;
|
||||
|
||||
bool _isPlayingBackRecording { false };
|
||||
bool _interstitialMode { true };
|
||||
bool _audioPaused { false };
|
||||
|
||||
CodecPluginPointer _codec;
|
||||
QString _selectedCodecName;
|
||||
|
|
|
@ -305,7 +305,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
var THE_PLACE = "hifi://TheSpot-dev";
|
||||
var THE_PLACE = (HifiAbout.buildVersion === "dev") ? "hifi://TheSpot-dev": "hifi://TheSpot";
|
||||
function clickedOnOverlay(overlayID, event) {
|
||||
if (loadingToTheSpotID === overlayID) {
|
||||
location.handleLookupString(THE_PLACE);
|
||||
|
|
Loading…
Reference in a new issue