Showing the changes to interface/src/Application.cpp (1 of 70 files). Show all
Unified · Split
| @@ -420,7 +420,7 @@ bool setupEssentials(int& argc, char** argv) { · 419 unmodified lines | ||
| 420 | 420 | |
| 421 | 421 | Setting::preInit(); |
| 422 | 422 | |
| 423 | − bool previousSessionCrashed = CrashHandler::checkForAndHandleCrash(); | |
| 423 | + bool previousSessionCrashed = CrashHandler::checkForResetSettings(); | |
| 424 | 424 | CrashHandler::writeRunningMarkerFiler(); |
| 425 | 425 | qAddPostRoutine(CrashHandler::deleteRunningMarkerFile); |
| 426 | 426 | |
| @@ -3196,7 +3196,19 @@ void Application::cameraMenuChanged() { · 2769 unmodified lines | ||
| 3196 | 3196 | } |
| 3197 | 3197 | } |
| 3198 | 3198 | |
| 3199 | +void Application::resetPhysicsReadyInformation() { | |
| 3200 | + // we've changed domains or cleared out caches or something. we no longer know enough about the | |
| 3201 | + // collision information of nearby entities to make running bullet be safe. | |
| 3202 | + _fullSceneReceivedCounter = 0; | |
| 3203 | + _fullSceneCounterAtLastPhysicsCheck = 0; | |
| 3204 | + _nearbyEntitiesCountAtLastPhysicsCheck = 0; | |
| 3205 | + _nearbyEntitiesStabilityCount = 0; | |
| 3206 | + _physicsEnabled = false; | |
| 3207 | +} | |
| 3208 | + | |
| 3209 | + | |
| 3199 | 3210 | void Application::reloadResourceCaches() { |
| 3211 | + resetPhysicsReadyInformation(); | |
| 3200 | 3212 | // Clear entities out of view frustum |
| 3201 | 3213 | _viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE)); |
| 3202 | 3214 | _viewFrustum.setOrientation(glm::quat()); |
| @@ -3253,21 +3265,34 @@ void Application::update(float deltaTime) { · 50 unmodified lines | ||
| 3253 | 3265 | |
| 3254 | 3266 | updateLOD(); |
| 3255 | 3267 | |
| 3256 | − if (!_physicsEnabled && _processOctreeStatsCounter > 0) { | |
| 3257 | − | |
| 3258 | − // process octree stats packets are sent in between full sends of a scene. | |
| 3259 | − // We keep physics disabled until we've received a full scene and everything near the avatar in that | |
| 3260 | − // scene is ready to compute its collision shape. | |
| 3268 | + if (!_physicsEnabled) { | |
| 3269 | + // we haven't yet enabled physics. we wait until we think we have all the collision information | |
| 3270 | + // for nearby entities before starting bullet up. | |
| 3271 | + quint64 now = usecTimestampNow(); | |
| 3272 | + bool timeout = false; | |
| 3273 | + const int PHYSICS_CHECK_TIMEOUT = 2 * USECS_PER_SECOND; | |
| 3274 | + if (_lastPhysicsCheckTime > 0 && now - _lastPhysicsCheckTime > PHYSICS_CHECK_TIMEOUT) { | |
| 3275 | + timeout = true; | |
| 3276 | + } | |
| 3261 | 3277 | |
| 3262 | − if (nearbyEntitiesAreReadyForPhysics()) { | |
| 3263 | − _physicsEnabled = true; | |
| 3264 | − getMyAvatar()->updateMotionBehaviorFromMenu(); | |
| 3265 | − } else { | |
| 3266 | − auto characterController = getMyAvatar()->getCharacterController(); | |
| 3267 | − if (characterController) { | |
| 3268 | − // if we have a character controller, disable it here so the avatar doesn't get stuck due to | |
| 3269 | − // a non-loading collision hull. | |
| 3270 | − characterController->setEnabled(false); | |
| 3278 | + if (timeout || _fullSceneReceivedCounter > _fullSceneCounterAtLastPhysicsCheck) { | |
| 3279 | + // we've received a new full-scene octree stats packet, or it's been long enough to try again anyway | |
| 3280 | + _lastPhysicsCheckTime = now; | |
| 3281 | + _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; | |
| 3282 | + | |
| 3283 | + // process octree stats packets are sent in between full sends of a scene (this isn't currently true). | |
| 3284 | + // We keep physics disabled until we've received a full scene and everything near the avatar in that | |
| 3285 | + // scene is ready to compute its collision shape. | |
| 3286 | + if (nearbyEntitiesAreReadyForPhysics()) { | |
| 3287 | + _physicsEnabled = true; | |
| 3288 | + getMyAvatar()->updateMotionBehaviorFromMenu(); | |
| 3289 | + } else { | |
| 3290 | + auto characterController = getMyAvatar()->getCharacterController(); | |
| 3291 | + if (characterController) { | |
| 3292 | + // if we have a character controller, disable it here so the avatar doesn't get stuck due to | |
| 3293 | + // a non-loading collision hull. | |
| 3294 | + characterController->setEnabled(false); | |
| 3295 | + } | |
| 3271 | 3296 | } |
| 3272 | 3297 | } |
| 3273 | 3298 | } |
| @@ -4152,7 +4177,7 @@ void Application::clearDomainOctreeDetails() { · 878 unmodified lines | ||
| 4152 | 4177 | qCDebug(interfaceapp) << "Clearing domain octree details..."; |
| 4153 | 4178 | // reset the environment so that we don't erroneously end up with multiple |
| 4154 | 4179 | |
| 4155 | − _physicsEnabled = false; | |
| 4180 | + resetPhysicsReadyInformation(); | |
| 4156 | 4181 | |
| 4157 | 4182 | // reset our node to stats and node to jurisdiction maps... since these must be changing... |
| 4158 | 4183 | _entityServerJurisdictions.withWriteLock([&] { |
| @@ -4176,7 +4201,7 @@ void Application::domainChanged(const QString& domainHostname) { · 17 unmodified lines | ||
| 4176 | 4201 | updateWindowTitle(); |
| 4177 | 4202 | clearDomainOctreeDetails(); |
| 4178 | 4203 | // disable physics until we have enough information about our new location to not cause craziness. |
| 4179 | − _physicsEnabled = false; | |
| 4204 | + resetPhysicsReadyInformation(); | |
| 4180 | 4205 | } |
| 4181 | 4206 | |
| 4182 | 4207 | |
| @@ -4309,15 +4334,31 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { · 126 unmodified lines | ||
| 4309 | 4334 | entityTree->findEntities(box, entities); |
| 4310 | 4335 | }); |
| 4311 | 4336 | |
| 4312 | − foreach (EntityItemPointer entity, entities) { | |
| 4313 | − if (entity->shouldBePhysical() && !entity->isReadyToComputeShape()) { | |
| 4314 | − static QString repeatedMessage = | |
| 4315 | − LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*"); | |
| 4316 | − qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName(); | |
| 4317 | − return false; | |
| 4337 | + // For reasons I haven't found, we don't necessarily have the full scene when we receive a stats packet. Apply | |
| 4338 | + // a heuristic to try to decide when we actually know about all of the nearby entities. | |
| 4339 | + uint32_t nearbyCount = entities.size(); | |
| 4340 | + if (nearbyCount == _nearbyEntitiesCountAtLastPhysicsCheck) { | |
| 4341 | + _nearbyEntitiesStabilityCount++; | |
| 4342 | + } else { | |
| 4343 | + _nearbyEntitiesStabilityCount = 0; | |
| 4344 | + } | |
| 4345 | + _nearbyEntitiesCountAtLastPhysicsCheck = nearbyCount; | |
| 4346 | + | |
| 4347 | + const uint32_t MINIMUM_NEARBY_ENTITIES_STABILITY_COUNT = 3; | |
| 4348 | + if (_nearbyEntitiesStabilityCount >= MINIMUM_NEARBY_ENTITIES_STABILITY_COUNT) { | |
| 4349 | + // We've seen the same number of nearby entities for several stats packets in a row. assume we've got all | |
| 4350 | + // the local entities. | |
| 4351 | + foreach (EntityItemPointer entity, entities) { | |
| 4352 | + if (entity->shouldBePhysical() && !entity->isReadyToComputeShape()) { | |
| 4353 | + static QString repeatedMessage = | |
| 4354 | + LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*"); | |
| 4355 | + qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName(); | |
| 4356 | + return false; | |
| 4357 | + } | |
| 4318 | 4358 | } |
| 4359 | + return true; | |
| 4319 | 4360 | } |
| 4320 | − return true; | |
| 4361 | + return false; | |
| 4321 | 4362 | } |
| 4322 | 4363 | |
| 4323 | 4364 | int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode) { |
| @@ -4334,6 +4375,10 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer · 10 unmodified lines | ||
| 4334 | 4375 | OctreeSceneStats& octreeStats = _octreeServerSceneStats[nodeUUID]; |
| 4335 | 4376 | statsMessageLength = octreeStats.unpackFromPacket(message); |
| 4336 | 4377 | |
| 4378 | + if (octreeStats.isFullScene()) { | |
| 4379 | + _fullSceneReceivedCounter++; | |
| 4380 | + } | |
| 4381 | + | |
| 4337 | 4382 | // see if this is the first we've heard of this node... |
| 4338 | 4383 | NodeToJurisdictionMap* jurisdiction = nullptr; |
| 4339 | 4384 | QString serverType; |
| @@ -4365,8 +4410,6 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer · 25 unmodified lines | ||
| 4365 | 4410 | }); |
| 4366 | 4411 | }); |
| 4367 | 4412 | |
| 4368 | − _processOctreeStatsCounter++; | |
| 4369 | − | |
| 4370 | 4413 | return statsMessageLength; |
| 4371 | 4414 | } |
| 4372 | 4415 | |
| @@ -5156,13 +5199,6 @@ mat4 Application::getHMDSensorPose() const { · 783 unmodified lines | ||
| 5156 | 5199 | return mat4(); |
| 5157 | 5200 | } |
| 5158 | 5201 | |
| 5159 | −void Application::crashApplication() { | |
| 5160 | − qCDebug(interfaceapp) << "Intentionally crashed Interface"; | |
| 5161 | − QObject* object = nullptr; | |
| 5162 | − bool value = object->isWindowType(); | |
| 5163 | − Q_UNUSED(value); | |
| 5164 | −} | |
| 5165 | − | |
| 5166 | 5202 | void Application::deadlockApplication() { |
| 5167 | 5203 | qCDebug(interfaceapp) << "Intentionally deadlocked Interface"; |
| 5168 | 5204 | // Using a loop that will *technically* eventually exit (in ~600 billion years) |