Showing the changes to interface/src/Application.cpp (1 of 406 files). Show all
Unified · Split
| @@ -9,11 +9,9 @@ · 8 unmodified lines | ||
| 9 | 9 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html |
| 10 | 10 | // |
| 11 | 11 | |
| 12 | −#include <sstream> | |
| 12 | +#include "Application.h" | |
| 13 | 13 | |
| 14 | −#include <stdlib.h> | |
| 15 | −#include <cmath> | |
| 16 | −#include <math.h> | |
| 14 | +#include <sstream> | |
| 17 | 15 | |
| 18 | 16 | #include <glm/glm.hpp> |
| 19 | 17 | #include <glm/gtx/component_wise.hpp> |
| @@ -21,9 +19,6 @@ · 1 unmodified line | ||
| 21 | 19 | #include <glm/gtx/vector_angle.hpp> |
| 22 | 20 | #include <glm/gtc/type_ptr.hpp> |
| 23 | 21 | |
| 24 | −// include this before QGLWidget, which includes an earlier version of OpenGL | |
| 25 | −#include "InterfaceConfig.h" | |
| 26 | − | |
| 27 | 22 | #include <QAbstractNativeEventFilter> |
| 28 | 23 | #include <QActionGroup> |
| 29 | 24 | #include <QColorDialog> |
| @@ -58,13 +53,13 @@ · 28 unmodified lines | ||
| 58 | 53 | #include <AccountManager.h> |
| 59 | 54 | #include <AddressManager.h> |
| 60 | 55 | #include <CursorManager.h> |
| 61 | −#include <AmbientOcclusionEffect.h> | |
| 62 | 56 | #include <AudioInjector.h> |
| 63 | 57 | #include <AutoUpdater.h> |
| 64 | 58 | #include <DeferredLightingEffect.h> |
| 65 | 59 | #include <DependencyManager.h> |
| 66 | 60 | #include <EntityScriptingInterface.h> |
| 67 | 61 | #include <ErrorDialog.h> |
| 62 | +#include <FramebufferCache.h> | |
| 68 | 63 | #include <gpu/Batch.h> |
| 69 | 64 | #include <gpu/Context.h> |
| 70 | 65 | #include <gpu/GLBackend.h> |
| @@ -80,11 +75,10 @@ · 9 unmodified lines | ||
| 80 | 75 | #include <ObjectMotionState.h> |
| 81 | 76 | #include <OctalCode.h> |
| 82 | 77 | #include <OctreeSceneStats.h> |
| 83 | −#include <PacketHeaders.h> | |
| 78 | +#include <udt/PacketHeaders.h> | |
| 84 | 79 | #include <PathUtils.h> |
| 85 | 80 | #include <PerfStat.h> |
| 86 | 81 | #include <PhysicsEngine.h> |
| 87 | −#include <ProgramObject.h> | |
| 88 | 82 | #include <RenderDeferredTask.h> |
| 89 | 83 | #include <ResourceCache.h> |
| 90 | 84 | #include <SceneScriptingInterface.h> |
| @@ -92,14 +86,15 @@ · 1 unmodified line | ||
| 92 | 86 | #include <SettingHandle.h> |
| 93 | 87 | #include <SimpleAverage.h> |
| 94 | 88 | #include <SoundCache.h> |
| 89 | +#include <TextureCache.h> | |
| 95 | 90 | #include <Tooltip.h> |
| 96 | 91 | #include <UserActivityLogger.h> |
| 97 | 92 | #include <UUID.h> |
| 98 | 93 | #include <VrMenu.h> |
| 99 | 94 | |
| 100 | −#include "Application.h" | |
| 101 | 95 | #include "AudioClient.h" |
| 102 | 96 | #include "DiscoverabilityManager.h" |
| 97 | +#include "GLCanvas.h" | |
| 103 | 98 | #include "InterfaceVersion.h" |
| 104 | 99 | #include "LODManager.h" |
| 105 | 100 | #include "Menu.h" |
| @@ -174,8 +169,6 @@ public: · 68 unmodified lines | ||
| 174 | 169 | using namespace std; |
| 175 | 170 | |
| 176 | 171 | // Starfield information |
| 177 | −static unsigned STARFIELD_NUM_STARS = 50000; | |
| 178 | −static unsigned STARFIELD_SEED = 1; | |
| 179 | 172 | static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10; |
| 180 | 173 | |
| 181 | 174 | const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB |
| @@ -271,8 +264,9 @@ bool setupEssentials(int& argc, char** argv) { · 89 unmodified lines | ||
| 271 | 264 | auto audio = DependencyManager::set<AudioClient>(); |
| 272 | 265 | auto audioScope = DependencyManager::set<AudioScope>(); |
| 273 | 266 | auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>(); |
| 274 | − auto ambientOcclusionEffect = DependencyManager::set<AmbientOcclusionEffect>(); | |
| 275 | 267 | auto textureCache = DependencyManager::set<TextureCache>(); |
| 268 | + auto framebufferCache = DependencyManager::set<FramebufferCache>(); | |
| 269 | + | |
| 276 | 270 | auto animationCache = DependencyManager::set<AnimationCache>(); |
| 277 | 271 | auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>(); |
| 278 | 272 | auto modelBlender = DependencyManager::set<ModelBlender>(); |
| @@ -303,7 +297,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines | ||
| 303 | 297 | _window(new MainWindow(desktop())), |
| 304 | 298 | _toolWindow(NULL), |
| 305 | 299 | _friendsWindow(NULL), |
| 306 | − _datagramProcessor(), | |
| 307 | 300 | _undoStack(), |
| 308 | 301 | _undoStackScriptingInterface(&_undoStack), |
| 309 | 302 | _frameCount(0), |
| @@ -321,7 +314,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 11 unmodified lines | ||
| 321 | 314 | _previousScriptLocation("LastScriptLocation"), |
| 322 | 315 | _scriptsLocationHandle("scriptsLocation"), |
| 323 | 316 | _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), |
| 324 | − _viewTransform(), | |
| 325 | 317 | _scaleMirror(1.0f), |
| 326 | 318 | _rotateMirror(0.0f), |
| 327 | 319 | _raiseMirror(0.0f), |
| @@ -338,9 +330,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 10 unmodified lines | ||
| 338 | 330 | _lastNackTime(usecTimestampNow()), |
| 339 | 331 | _lastSendDownstreamAudioStats(usecTimestampNow()), |
| 340 | 332 | _isVSyncOn(true), |
| 341 | − _isThrottleFPSEnabled(false), | |
| 333 | + _isThrottleFPSEnabled(true), | |
| 342 | 334 | _aboutToQuit(false), |
| 343 | 335 | _notifiedPacketVersionMismatchThisDomain(false), |
| 336 | + _glWidget(new GLCanvas()), | |
| 344 | 337 | _domainConnectionRefusals(QList<QString>()), |
| 345 | 338 | _maxOctreePPS(maxOctreePacketsPerSecond.get()), |
| 346 | 339 | _lastFaceTrackerUpdate(0), |
| @@ -371,24 +364,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines | ||
| 371 | 364 | _bookmarks = new Bookmarks(); // Before setting up the menu |
| 372 | 365 | |
| 373 | 366 | _runningScriptsWidget = new RunningScriptsWidget(_window); |
| 374 | − _renderEngine->addTask(render::TaskPointer(new RenderDeferredTask())); | |
| 367 | + _renderEngine->addTask(make_shared<RenderDeferredTask>()); | |
| 375 | 368 | _renderEngine->registerScene(_main3DScene); |
| 376 | − | |
| 369 | + | |
| 377 | 370 | // start the nodeThread so its event loop is running |
| 378 | 371 | QThread* nodeThread = new QThread(this); |
| 379 | − nodeThread->setObjectName("Datagram Processor Thread"); | |
| 372 | + nodeThread->setObjectName("NodeList Thread"); | |
| 380 | 373 | nodeThread->start(); |
| 381 | 374 | |
| 382 | 375 | // make sure the node thread is given highest priority |
| 383 | 376 | nodeThread->setPriority(QThread::TimeCriticalPriority); |
| 384 | 377 | |
| 385 | − _datagramProcessor = new DatagramProcessor(nodeList.data()); | |
| 386 | − | |
| 387 | − // have the NodeList use deleteLater from DM customDeleter | |
| 388 | − nodeList->setCustomDeleter([](Dependency* dependency) { | |
| 389 | − static_cast<NodeList*>(dependency)->deleteLater(); | |
| 390 | − }); | |
| 391 | − | |
| 392 | 378 | // setup a timer for domain-server check ins |
| 393 | 379 | QTimer* domainCheckInTimer = new QTimer(nodeList.data()); |
| 394 | 380 | connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn); |
| @@ -404,9 +390,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 9 unmodified lines | ||
| 404 | 390 | ResourceCache* geometryCache = geometryCacheP.data(); |
| 405 | 391 | connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets); |
| 406 | 392 | |
| 407 | − // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal | |
| 408 | − connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams); | |
| 409 | − | |
| 410 | 393 | // put the audio processing on a separate thread |
| 411 | 394 | QThread* audioThread = new QThread(); |
| 412 | 395 | audioThread->setObjectName("Audio Thread"); |
| @@ -417,14 +400,27 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 4 unmodified lines | ||
| 417 | 400 | audioIO->setOrientationGetter(getOrientationForAudio); |
| 418 | 401 | |
| 419 | 402 | audioIO->moveToThread(audioThread); |
| 403 | + | |
| 404 | + auto& audioScriptingInterface = AudioScriptingInterface::getInstance(); | |
| 405 | + | |
| 420 | 406 | connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start); |
| 421 | 407 | connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit); |
| 422 | 408 | connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); |
| 423 | 409 | connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled); |
| 424 | − connect(audioIO.data(), &AudioClient::receivedFirstPacket, | |
| 425 | − &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::receivedFirstPacket); | |
| 426 | − connect(audioIO.data(), &AudioClient::disconnected, | |
| 427 | − &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::disconnected); | |
| 410 | + connect(audioIO.data(), &AudioClient::mutedByMixer, &audioScriptingInterface, &AudioScriptingInterface::mutedByMixer); | |
| 411 | + connect(audioIO.data(), &AudioClient::receivedFirstPacket, &audioScriptingInterface, &AudioScriptingInterface::receivedFirstPacket); | |
| 412 | + connect(audioIO.data(), &AudioClient::disconnected, &audioScriptingInterface, &AudioScriptingInterface::disconnected); | |
| 413 | + connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { | |
| 414 | + auto audioClient = DependencyManager::get<AudioClient>(); | |
| 415 | + float distance = glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), | |
| 416 | + position); | |
| 417 | + bool shouldMute = !audioClient->isMuted() && (distance < radius); | |
| 418 | + | |
| 419 | + if (shouldMute) { | |
| 420 | + audioClient->toggleMute(); | |
| 421 | + AudioScriptingInterface::getInstance().environmentMuted(); | |
| 422 | + } | |
| 423 | + }); | |
| 428 | 424 | |
| 429 | 425 | audioThread->start(); |
| 430 | 426 | |
| @@ -457,7 +453,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 26 unmodified lines | ||
| 457 | 453 | connect(nodeList.data(), &NodeList::uuidChanged, _myAvatar, &MyAvatar::setSessionUUID); |
| 458 | 454 | connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID); |
| 459 | 455 | connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset); |
| 460 | − connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch); | |
| 456 | + connect(&nodeList->getPacketReceiver(), &PacketReceiver::packetVersionMismatch, | |
| 457 | + this, &Application::notifyPacketVersionMismatch); | |
| 461 | 458 | |
| 462 | 459 | // connect to appropriate slots on AccountManager |
| 463 | 460 | AccountManager& accountManager = AccountManager::getInstance(); |
| @@ -537,7 +534,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 73 unmodified lines | ||
| 537 | 534 | // the GL surface |
| 538 | 535 | _glWidget->setCursor(Qt::BlankCursor); |
| 539 | 536 | #endif |
| 540 | − | |
| 537 | + | |
| 541 | 538 | // enable mouse tracking; otherwise, we only get drag events |
| 542 | 539 | _glWidget->setMouseTracking(true); |
| 543 | 540 | |
| @@ -571,10 +568,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 27 unmodified lines | ||
| 571 | 568 | |
| 572 | 569 | // hook up bandwidth estimator |
| 573 | 570 | QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>(); |
| 574 | − connect(nodeList.data(), SIGNAL(dataSent(const quint8, const int)), | |
| 575 | − bandwidthRecorder.data(), SLOT(updateOutboundData(const quint8, const int))); | |
| 576 | − connect(nodeList.data(), SIGNAL(dataReceived(const quint8, const int)), | |
| 577 | − bandwidthRecorder.data(), SLOT(updateInboundData(const quint8, const int))); | |
| 571 | + connect(nodeList.data(), &LimitedNodeList::dataSent, | |
| 572 | + bandwidthRecorder.data(), &BandwidthRecorder::updateOutboundData); | |
| 573 | + connect(&nodeList->getPacketReceiver(), &PacketReceiver::dataReceived, | |
| 574 | + bandwidthRecorder.data(), &BandwidthRecorder::updateInboundData); | |
| 578 | 575 | |
| 579 | 576 | connect(&_myAvatar->getSkeletonModel(), &SkeletonModel::skeletonLoaded, |
| 580 | 577 | this, &Application::checkSkeleton, Qt::QueuedConnection); |
| @@ -606,7 +603,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 25 unmodified lines | ||
| 606 | 603 | _settingsTimer.setSingleShot(false); |
| 607 | 604 | _settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL); |
| 608 | 605 | _settingsThread.start(); |
| 609 | − | |
| 606 | + | |
| 610 | 607 | if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) { |
| 611 | 608 | Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true); |
| 612 | 609 | cameraMenuChanged(); |
| @@ -637,10 +634,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines | ||
| 637 | 634 | ddeTracker->init(); |
| 638 | 635 | connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled); |
| 639 | 636 | #endif |
| 640 | − | |
| 637 | + | |
| 641 | 638 | auto applicationUpdater = DependencyManager::get<AutoUpdater>(); |
| 642 | 639 | connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog); |
| 643 | 640 | applicationUpdater->checkForUpdate(); |
| 641 | + | |
| 642 | + auto& packetReceiver = nodeList->getPacketReceiver(); | |
| 643 | + packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket"); | |
| 644 | 644 | } |
| 645 | 645 | |
| 646 | 646 | void Application::aboutToQuit() { |
| @@ -653,8 +653,10 @@ void Application::aboutToQuit() { · 6 unmodified lines | ||
| 653 | 653 | void Application::cleanupBeforeQuit() { |
| 654 | 654 | |
| 655 | 655 | _entities.clear(); // this will allow entity scripts to properly shutdown |
| 656 | − | |
| 657 | − _datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit | |
| 656 | + | |
| 657 | + // tell the packet receiver we're shutting down, so it can drop packets | |
| 658 | + DependencyManager::get<NodeList>()->getPacketReceiver().setShouldDropPackets(true); | |
| 659 | + | |
| 658 | 660 | _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts |
| 659 | 661 | ScriptEngine::stopAllScripts(this); // stop all currently running global scripts |
| 660 | 662 | |
| @@ -731,12 +733,15 @@ Application::~Application() { · 70 unmodified lines | ||
| 731 | 733 | DependencyManager::destroy<OffscreenUi>(); |
| 732 | 734 | DependencyManager::destroy<AvatarManager>(); |
| 733 | 735 | DependencyManager::destroy<AnimationCache>(); |
| 736 | + DependencyManager::destroy<FramebufferCache>(); | |
| 734 | 737 | DependencyManager::destroy<TextureCache>(); |
| 735 | 738 | DependencyManager::destroy<GeometryCache>(); |
| 736 | 739 | DependencyManager::destroy<ScriptCache>(); |
| 737 | 740 | DependencyManager::destroy<SoundCache>(); |
| 738 | 741 | |
| 739 | 742 | QThread* nodeThread = DependencyManager::get<NodeList>()->thread(); |
| 743 | + | |
| 744 | + // remove the NodeList from the DependencyManager | |
| 740 | 745 | DependencyManager::destroy<NodeList>(); |
| 741 | 746 | |
| 742 | 747 | // ask the node thread to quit and wait until it is done |
| @@ -762,32 +767,8 @@ void Application::initializeGL() { · 19 unmodified lines | ||
| 762 | 767 | } |
| 763 | 768 | #endif |
| 764 | 769 | |
| 765 | − qCDebug(interfaceapp) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); | |
| 766 | − qCDebug(interfaceapp) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); | |
| 767 | − qCDebug(interfaceapp) << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR)); | |
| 768 | − qCDebug(interfaceapp) << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); | |
| 769 | − | |
| 770 | − #ifdef WIN32 | |
| 771 | − GLenum err = glewInit(); | |
| 772 | − if (GLEW_OK != err) { | |
| 773 | − /* Problem: glewInit failed, something is seriously wrong. */ | |
| 774 | − qCDebug(interfaceapp, "Error: %s\n", glewGetErrorString(err)); | |
| 775 | − } | |
| 776 | − qCDebug(interfaceapp, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); | |
| 777 | − | |
| 778 | − if (wglewGetExtension("WGL_EXT_swap_control")) { | |
| 779 | − int swapInterval = wglGetSwapIntervalEXT(); | |
| 780 | − qCDebug(interfaceapp, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); | |
| 781 | − } | |
| 782 | − #endif | |
| 783 | − | |
| 784 | −#if defined(Q_OS_LINUX) | |
| 785 | − // TODO: Write the correct code for Linux... | |
| 786 | − /* if (wglewGetExtension("WGL_EXT_swap_control")) { | |
| 787 | − int swapInterval = wglGetSwapIntervalEXT(); | |
| 788 | − qCDebug(interfaceapp, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); | |
| 789 | − }*/ | |
| 790 | −#endif | |
| 770 | + // Where the gpuContext is created and where the TRUE Backend is created and assigned | |
| 771 | + _gpuContext = std::make_shared<gpu::Context>(new gpu::GLBackend()); | |
| 791 | 772 | |
| 792 | 773 | initDisplay(); |
| 793 | 774 | qCDebug(interfaceapp, "Initialized Display."); |
| @@ -876,8 +857,9 @@ void Application::paintGL() { · 82 unmodified lines | ||
| 876 | 857 | _glWidget->makeCurrent(); |
| 877 | 858 | |
| 878 | 859 | auto lodManager = DependencyManager::get<LODManager>(); |
| 879 | − gpu::Context context(new gpu::GLBackend()); | |
| 880 | − RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(), | |
| 860 | + | |
| 861 | + | |
| 862 | + RenderArgs renderArgs(_gpuContext, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(), | |
| 881 | 863 | lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, |
| 882 | 864 | RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); |
| 883 | 865 | |
| @@ -887,30 +869,56 @@ void Application::paintGL() { · 3 unmodified lines | ||
| 887 | 869 | OculusManager::beginFrameTiming(); |
| 888 | 870 | } |
| 889 | 871 | |
| 890 | − | |
| 872 | + | |
| 891 | 873 | PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); |
| 892 | 874 | bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); |
| 893 | 875 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); |
| 894 | 876 | resizeGL(); |
| 895 | 877 | |
| 878 | + // Before anything else, let's sync up the gpuContext with the true glcontext used in case anything happened | |
| 879 | + renderArgs._context->syncCache(); | |
| 880 | + | |
| 881 | + if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { | |
| 882 | + auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | |
| 883 | + | |
| 884 | + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 885 | + renderRearViewMirror(&renderArgs, _mirrorViewRect); | |
| 886 | + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 887 | + | |
| 888 | + { | |
| 889 | + float ratio = ((float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale()); | |
| 890 | + auto mirrorViewport = glm::ivec4(0, 0, _mirrorViewRect.width() * ratio, _mirrorViewRect.height() * ratio); | |
| 891 | + auto mirrorViewportDest = mirrorViewport; | |
| 892 | + | |
| 893 | + auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer(); | |
| 894 | + gpu::Batch batch; | |
| 895 | + batch.setFramebuffer(selfieFbo); | |
| 896 | + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); | |
| 897 | + batch.blit(primaryFbo, mirrorViewport, selfieFbo, mirrorViewportDest); | |
| 898 | + batch.setFramebuffer(nullptr); | |
| 899 | + renderArgs._context->render(batch); | |
| 900 | + } | |
| 901 | + } | |
| 902 | + | |
| 896 | 903 | { |
| 897 | 904 | PerformanceTimer perfTimer("renderOverlay"); |
| 898 | 905 | |
| 899 | 906 | // NOTE: There is no batch associated with this renderArgs |
| 900 | 907 | // the ApplicationOverlay class assumes it's viewport is setup to be the device size |
| 901 | 908 | QSize size = qApp->getDeviceSize(); |
| 902 | − renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); | |
| 909 | + renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); | |
| 903 | 910 | _applicationOverlay.renderOverlay(&renderArgs); |
| 904 | 911 | } |
| 905 | 912 | |
| 906 | − glEnable(GL_LINE_SMOOTH); | |
| 907 | − | |
| 908 | 913 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { |
| 909 | 914 | Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); |
| 910 | 915 | Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); |
| 911 | 916 | Application::getInstance()->cameraMenuChanged(); |
| 912 | 917 | } |
| 913 | 918 | |
| 919 | + // The render mode is default or mirror if the camera is in mirror mode, assigned further below | |
| 920 | + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 921 | + | |
| 914 | 922 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { |
| 915 | 923 | // Always use the default eye position, not the actual head eye position. |
| 916 | 924 | // Using the latter will cause the camera to wobble with idle animations, |
| @@ -947,6 +955,7 @@ void Application::paintGL() { · 30 unmodified lines | ||
| 947 | 955 | glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + |
| 948 | 956 | (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * |
| 949 | 957 | glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); |
| 958 | + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 950 | 959 | } |
| 951 | 960 | |
| 952 | 961 | // Update camera position |
| @@ -954,17 +963,6 @@ void Application::paintGL() { · 1 unmodified line | ||
| 954 | 963 | _myCamera.update(1.0f / _fps); |
| 955 | 964 | } |
| 956 | 965 | |
| 957 | − // Sync up the View Furstum with the camera | |
| 958 | − // FIXME: it's happening again in the updateSHadow and it shouldn't, this should be the place | |
| 959 | − loadViewFrustum(_myCamera, _viewFrustum); | |
| 960 | − | |
| 961 | − if (getShadowsEnabled()) { | |
| 962 | − renderArgs._renderMode = RenderArgs::SHADOW_RENDER_MODE; | |
| 963 | − updateShadowMap(&renderArgs); | |
| 964 | − } | |
| 965 | − | |
| 966 | − renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 967 | − | |
| 968 | 966 | if (OculusManager::isConnected()) { |
| 969 | 967 | //When in mirror mode, use camera rotation. Otherwise, use body rotation |
| 970 | 968 | if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { |
| @@ -976,45 +974,28 @@ void Application::paintGL() { · 5 unmodified lines | ||
| 976 | 974 | TV3DManager::display(&renderArgs, _myCamera); |
| 977 | 975 | } else { |
| 978 | 976 | PROFILE_RANGE(__FUNCTION__ "/mainRender"); |
| 979 | − | |
| 980 | − auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer(); | |
| 981 | − GLuint fbo = gpu::GLBackend::getFramebufferID(primaryFBO); | |
| 982 | − glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); | |
| 983 | − glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
| 984 | − | |
| 985 | 977 | // Viewport is assigned to the size of the framebuffer |
| 986 | − QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize(); | |
| 987 | − glViewport(0, 0, size.width(), size.height()); | |
| 978 | + QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize(); | |
| 988 | 979 | renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); |
| 989 | − | |
| 990 | − glMatrixMode(GL_MODELVIEW); | |
| 991 | − glPushMatrix(); | |
| 992 | − glLoadIdentity(); | |
| 993 | − displaySide(&renderArgs, _myCamera); | |
| 994 | − glPopMatrix(); | |
| 995 | 980 | |
| 996 | − renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | |
| 997 | − if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { | |
| 998 | − renderRearViewMirror(&renderArgs, _mirrorViewRect); | |
| 999 | − } | |
| 1000 | 981 | |
| 1001 | − renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE; | |
| 982 | + displaySide(&renderArgs, _myCamera); | |
| 1002 | 983 | |
| 1003 | − auto finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer(); | |
| 984 | + { | |
| 985 | + auto geometryCache = DependencyManager::get<GeometryCache>(); | |
| 986 | + auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | |
| 987 | + gpu::Batch batch; | |
| 988 | + batch.blit(primaryFbo, glm::ivec4(0, 0, _renderResolution.x, _renderResolution.y), | |
| 989 | + nullptr, glm::ivec4(0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height())); | |
| 1004 | 990 | |
| 1005 | − glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | |
| 1006 | − glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); | |
| 1007 | − glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y, | |
| 1008 | − 0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(), | |
| 1009 | − GL_COLOR_BUFFER_BIT, GL_LINEAR); | |
| 1010 | − glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); | |
| 1011 | − | |
| 1012 | − glBindTexture(GL_TEXTURE_2D, 0); // ??? | |
| 991 | + batch.setFramebuffer(nullptr); | |
| 992 | + | |
| 993 | + renderArgs._context->render(batch); | |
| 994 | + } | |
| 1013 | 995 | |
| 1014 | 996 | _compositor.displayOverlayTexture(&renderArgs); |
| 1015 | 997 | } |
| 1016 | − | |
| 1017 | − | |
| 998 | + | |
| 1018 | 999 | if (!OculusManager::isConnected() || OculusManager::allowSwap()) { |
| 1019 | 1000 | PROFILE_RANGE(__FUNCTION__ "/bufferSwap"); |
| 1020 | 1001 | _glWidget->swapBuffers(); |
| @@ -1024,6 +1005,7 @@ void Application::paintGL() { · 3 unmodified lines | ||
| 1024 | 1005 | OculusManager::endFrameTiming(); |
| 1025 | 1006 | } |
| 1026 | 1007 | _frameCount++; |
| 1008 | + _numFramesSinceLastResize++; | |
| 1027 | 1009 | Stats::getInstance()->setRenderDetails(renderArgs._details); |
| 1028 | 1010 | } |
| 1029 | 1011 | |
| @@ -1077,13 +1059,11 @@ void Application::resizeGL() { · 47 unmodified lines | ||
| 1077 | 1059 | } |
| 1078 | 1060 | |
| 1079 | 1061 | if (_renderResolution != toGlm(renderSize)) { |
| 1062 | + _numFramesSinceLastResize = 0; | |
| 1080 | 1063 | _renderResolution = toGlm(renderSize); |
| 1081 | − DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize); | |
| 1082 | − | |
| 1083 | − glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu??? | |
| 1064 | + DependencyManager::get<FramebufferCache>()->setFrameBufferSize(renderSize); | |
| 1084 | 1065 | |
| 1085 | − updateProjectionMatrix(); | |
| 1086 | − glLoadIdentity(); | |
| 1066 | + loadViewFrustum(_myCamera, _viewFrustum); | |
| 1087 | 1067 | } |
| 1088 | 1068 | |
| 1089 | 1069 | resetCameras(_myCamera, _renderResolution); |
| @@ -1093,32 +1073,6 @@ void Application::resizeGL() { · 3 unmodified lines | ||
| 1093 | 1073 | auto canvasSize = _glWidget->size(); |
| 1094 | 1074 | offscreenUi->resize(canvasSize); |
| 1095 | 1075 | _glWidget->makeCurrent(); |
| 1096 | − | |
| 1097 | −} | |
| 1098 | − | |
| 1099 | −void Application::updateProjectionMatrix() { | |
| 1100 | − updateProjectionMatrix(_myCamera); | |
| 1101 | −} | |
| 1102 | − | |
| 1103 | −void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum) { | |
| 1104 | − _projectionMatrix = camera.getProjection(); | |
| 1105 | − | |
| 1106 | − glMatrixMode(GL_PROJECTION); | |
| 1107 | − glLoadMatrixf(glm::value_ptr(_projectionMatrix)); | |
| 1108 | − | |
| 1109 | − // Tell our viewFrustum about this change, using the application camera | |
| 1110 | − if (updateViewFrustum) { | |
| 1111 | − loadViewFrustum(camera, _viewFrustum); | |
| 1112 | − } | |
| 1113 | − | |
| 1114 | − glMatrixMode(GL_MODELVIEW); | |
| 1115 | −} | |
| 1116 | − | |
| 1117 | −void Application::controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { | |
| 1118 | − foreach(NodeType_t type, destinationNodeTypes) { | |
| 1119 | − // Perform the broadcast for one type | |
| 1120 | − DependencyManager::get<NodeList>()->broadcastToNodes(packet, NodeSet() << type); | |
| 1121 | − } | |
| 1122 | 1076 | } |
| 1123 | 1077 | |
| 1124 | 1078 | bool Application::importSVOFromURL(const QString& urlString) { |
| @@ -1267,12 +1221,6 @@ void Application::keyPressEvent(QKeyEvent* event) { · 142 unmodified lines | ||
| 1267 | 1221 | Menu::getInstance()->triggerOption(MenuOption::Stars); |
| 1268 | 1222 | break; |
| 1269 | 1223 | |
| 1270 | − case Qt::Key_W: | |
| 1271 | − if (isOption && !isShifted && !isMeta) { | |
| 1272 | − Menu::getInstance()->triggerOption(MenuOption::Wireframe); | |
| 1273 | − } | |
| 1274 | − break; | |
| 1275 | − | |
| 1276 | 1224 | case Qt::Key_S: |
| 1277 | 1225 | if (isShifted && isMeta && !isOption) { |
| 1278 | 1226 | Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings); |
| @@ -1786,10 +1734,21 @@ bool Application::acceptSnapshot(const QString& urlString) { · 507 unmodified lines | ||
| 1786 | 1734 | } |
| 1787 | 1735 | |
| 1788 | 1736 | void Application::sendPingPackets() { |
| 1789 | − QByteArray pingPacket = DependencyManager::get<NodeList>()->constructPingPacket(); | |
| 1790 | − controlledBroadcastToNodes(pingPacket, NodeSet() | |
| 1791 | − << NodeType::EntityServer | |
| 1792 | − << NodeType::AudioMixer << NodeType::AvatarMixer); | |
| 1737 | + | |
| 1738 | + auto nodeList = DependencyManager::get<NodeList>(); | |
| 1739 | + | |
| 1740 | + nodeList->eachMatchingNode([](const SharedNodePointer& node)->bool { | |
| 1741 | + switch (node->getType()) { | |
| 1742 | + case NodeType::AvatarMixer: | |
| 1743 | + case NodeType::AudioMixer: | |
| 1744 | + case NodeType::EntityServer: | |
| 1745 | + return true; | |
| 1746 | + default: | |
| 1747 | + return false; | |
| 1748 | + } | |
| 1749 | + }, [nodeList](const SharedNodePointer& node) { | |
| 1750 | + nodeList->sendPacket(nodeList->constructPingPacket(), *node); | |
| 1751 | + }); | |
| 1793 | 1752 | } |
| 1794 | 1753 | |
| 1795 | 1754 | // Every second, check the frame rates and other stuff |
| @@ -1802,7 +1761,6 @@ void Application::checkFPS() { · 6 unmodified lines | ||
| 1802 | 1761 | |
| 1803 | 1762 | _fps = (float)_frameCount / diffTime; |
| 1804 | 1763 | _frameCount = 0; |
| 1805 | − _datagramProcessor->resetCounters(); | |
| 1806 | 1764 | _timerStart.start(); |
| 1807 | 1765 | } |
| 1808 | 1766 | |
| @@ -1868,11 +1826,15 @@ void Application::idle() { · 59 unmodified lines | ||
| 1868 | 1826 | _idleLoopMeasuredJitter = _idleLoopStdev.getStDev(); |
| 1869 | 1827 | _idleLoopStdev.reset(); |
| 1870 | 1828 | } |
| 1871 | − | |
| 1872 | 1829 | } |
| 1830 | + | |
| 1873 | 1831 | // After finishing all of the above work, ensure the idle timer is set to the proper interval, |
| 1874 | − // depending on whether we're throttling or not | |
| 1875 | − idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 1); | |
| 1832 | + // depending on whether we're throttling or not. | |
| 1833 | + // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in | |
| 1834 | + // perpetuity and not expect events to get backed up. | |
| 1835 | + | |
| 1836 | + static const int IDLE_TIMER_DELAY_MS = 2; | |
| 1837 | + idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS); | |
| 1876 | 1838 | } |
| 1877 | 1839 | |
| 1878 | 1840 | // check for any requested background downloads. |
| @@ -1955,7 +1917,6 @@ void Application::setEnableVRMode(bool enableVRMode) { · 76 unmodified lines | ||
| 1955 | 1917 | OculusManager::connect(_glWidget->context()->contextHandle()); |
| 1956 | 1918 | _glWidget->setFocus(); |
| 1957 | 1919 | _glWidget->makeCurrent(); |
| 1958 | − glClear(GL_COLOR_BUFFER_BIT); | |
| 1959 | 1920 | } |
| 1960 | 1921 | OculusManager::recalibrate(); |
| 1961 | 1922 | } else { |
| @@ -2151,12 +2112,6 @@ QVector<EntityItemID> Application::pasteEntities(float x, float y, float z) { · 189 unmodified lines | ||
| 2151 | 2112 | } |
| 2152 | 2113 | |
| 2153 | 2114 | void Application::initDisplay() { |
| 2154 | − glEnable(GL_BLEND); | |
| 2155 | − glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); | |
| 2156 | − glShadeModel(GL_SMOOTH); | |
| 2157 | − glEnable(GL_LIGHTING); | |
| 2158 | − glEnable(GL_LIGHT0); | |
| 2159 | − glEnable(GL_DEPTH_TEST); | |
| 2160 | 2115 | } |
| 2161 | 2116 | |
| 2162 | 2117 | void Application::init() { |
| @@ -2166,7 +2121,6 @@ void Application::init() { · 3 unmodified lines | ||
| 2166 | 2121 | _environment.init(); |
| 2167 | 2122 | |
| 2168 | 2123 | DependencyManager::get<DeferredLightingEffect>()->init(this); |
| 2169 | − DependencyManager::get<AmbientOcclusionEffect>()->init(this); | |
| 2170 | 2124 | |
| 2171 | 2125 | // TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager |
| 2172 | 2126 | DependencyManager::get<AvatarManager>()->init(); |
| @@ -2262,8 +2216,8 @@ void Application::shrinkMirrorView() { · 89 unmodified lines | ||
| 2262 | 2216 | |
| 2263 | 2217 | const float HEAD_SPHERE_RADIUS = 0.1f; |
| 2264 | 2218 | |
| 2265 | −bool Application::isLookingAtMyAvatar(Avatar* avatar) { | |
| 2266 | − glm::vec3 theirLookAt = avatar->getHead()->getLookAtPosition(); | |
| 2219 | +bool Application::isLookingAtMyAvatar(AvatarSharedPointer avatar) { | |
| 2220 | + glm::vec3 theirLookAt = dynamic_pointer_cast<Avatar>(avatar)->getHead()->getLookAtPosition(); | |
| 2267 | 2221 | glm::vec3 myEyePosition = _myAvatar->getHead()->getEyePosition(); |
| 2268 | 2222 | if (pointInSphere(theirLookAt, myEyePosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { |
| 2269 | 2223 | return true; |
| @@ -2327,7 +2281,7 @@ void Application::updateMyAvatarLookAtPosition() { · 57 unmodified lines | ||
| 2327 | 2281 | if (lookingAt && _myAvatar != lookingAt.get()) { |
| 2328 | 2282 | // If I am looking at someone else, look directly at one of their eyes |
| 2329 | 2283 | isLookingAtSomeone = true; |
| 2330 | − Head* lookingAtHead = static_cast<Avatar*>(lookingAt.get())->getHead(); | |
| 2284 | + auto lookingAtHead = static_pointer_cast<Avatar>(lookingAt)->getHead(); | |
| 2331 | 2285 | |
| 2332 | 2286 | const float MAXIMUM_FACE_ANGLE = 65.0f * RADIANS_PER_DEGREE; |
| 2333 | 2287 | glm::vec3 lookingAtFaceOrientation = lookingAtHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; |
| @@ -2357,23 +2311,21 @@ void Application::updateMyAvatarLookAtPosition() { · 23 unmodified lines | ||
| 2357 | 2311 | lookAtSpot = _myAvatar->getHead()->getEyePosition() + |
| 2358 | 2312 | (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); |
| 2359 | 2313 | } |
| 2360 | − } | |
| 2361 | 2314 | |
| 2362 | − // Deflect the eyes a bit to match the detected gaze from Faceshift if active. | |
| 2363 | − // DDE doesn't track eyes. | |
| 2364 | − if (tracker && typeid(*tracker) == typeid(Faceshift) && !tracker->isMuted()) { | |
| 2365 | − float eyePitch = tracker->getEstimatedEyePitch(); | |
| 2366 | − float eyeYaw = tracker->getEstimatedEyeYaw(); | |
| 2367 | − const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; | |
| 2368 | − glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); | |
| 2369 | − float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f; | |
| 2370 | − float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection(); | |
| 2371 | − if (isLookingAtSomeone) { | |
| 2372 | − deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; | |
| 2373 | − } | |
| 2374 | − lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( | |
| 2375 | − eyePitch * pitchSign * deflection, eyeYaw * deflection, 0.0f))) * | |
| 2315 | + // Deflect the eyes a bit to match the detected gaze from the face tracker if active. | |
| 2316 | + if (tracker && !tracker->isMuted()) { | |
| 2317 | + float eyePitch = tracker->getEstimatedEyePitch(); | |
| 2318 | + float eyeYaw = tracker->getEstimatedEyeYaw(); | |
| 2319 | + const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; | |
| 2320 | + glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); | |
| 2321 | + float deflection = tracker->getEyeDeflection(); | |
| 2322 | + if (isLookingAtSomeone) { | |
| 2323 | + deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; | |
| 2324 | + } | |
| 2325 | + lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( | |
| 2326 | + eyePitch * deflection, eyeYaw * deflection, 0.0f))) * | |
| 2376 | 2327 | glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin); |
| 2328 | + } | |
| 2377 | 2329 | } |
| 2378 | 2330 | |
| 2379 | 2331 | _myAvatar->getHead()->setLookAtPosition(lookAtSpot); |
| @@ -2534,10 +2486,18 @@ void Application::update(float deltaTime) { · 154 unmodified lines | ||
| 2534 | 2486 | _myAvatar->setDriveKeys(DOWN, _userInputMapper.getActionState(UserInputMapper::VERTICAL_DOWN)); |
| 2535 | 2487 | _myAvatar->setDriveKeys(LEFT, _userInputMapper.getActionState(UserInputMapper::LATERAL_LEFT)); |
| 2536 | 2488 | _myAvatar->setDriveKeys(RIGHT, _userInputMapper.getActionState(UserInputMapper::LATERAL_RIGHT)); |
| 2537 | − _myAvatar->setDriveKeys(ROT_UP, _userInputMapper.getActionState(UserInputMapper::PITCH_UP)); | |
| 2538 | − _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN)); | |
| 2539 | − _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT)); | |
| 2540 | − _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT)); | |
| 2489 | + if (deltaTime > FLT_EPSILON) { | |
| 2490 | + // For rotations what we really want are meausures of "angles per second" (in order to prevent | |
| 2491 | + // fps-dependent spin rates) so we need to scale the units of the controller contribution. | |
| 2492 | + // (TODO?: maybe we should similarly scale ALL action state info, or change the expected behavior | |
| 2493 | + // controllers to provide a delta_per_second value rather than a raw delta.) | |
| 2494 | + const float EXPECTED_FRAME_RATE = 60.0f; | |
| 2495 | + float timeFactor = EXPECTED_FRAME_RATE * deltaTime; | |
| 2496 | + _myAvatar->setDriveKeys(ROT_UP, _userInputMapper.getActionState(UserInputMapper::PITCH_UP) / timeFactor); | |
| 2497 | + _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN) / timeFactor); | |
| 2498 | + _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT) / timeFactor); | |
| 2499 | + _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT) / timeFactor); | |
| 2500 | + } | |
| 2541 | 2501 | } |
| 2542 | 2502 | _myAvatar->setDriveKeys(BOOM_IN, _userInputMapper.getActionState(UserInputMapper::BOOM_IN)); |
| 2543 | 2503 | _myAvatar->setDriveKeys(BOOM_OUT, _userInputMapper.getActionState(UserInputMapper::BOOM_OUT)); |
| @@ -2658,7 +2618,7 @@ void Application::update(float deltaTime) { · 114 unmodified lines | ||
| 2658 | 2618 | _lastQueriedTime = now; |
| 2659 | 2619 | |
| 2660 | 2620 | if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { |
| 2661 | − queryOctree(NodeType::EntityServer, PacketTypeEntityQuery, _entityServerJurisdictions); | |
| 2621 | + queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions); | |
| 2662 | 2622 | } |
| 2663 | 2623 | _lastQueriedViewFrustum = _viewFrustum; |
| 2664 | 2624 | } |
| @@ -2691,16 +2651,17 @@ int Application::sendNackPackets() { · 26 unmodified lines | ||
| 2691 | 2651 | return 0; |
| 2692 | 2652 | } |
| 2693 | 2653 | |
| 2694 | − int packetsSent = 0; | |
| 2695 | − char packet[MAX_PACKET_SIZE]; | |
| 2696 | − | |
| 2697 | − // iterates thru all nodes in NodeList | |
| 2654 | + // iterates through all nodes in NodeList | |
| 2698 | 2655 | auto nodeList = DependencyManager::get<NodeList>(); |
| 2699 | 2656 | |
| 2657 | + int packetsSent = 0; | |
| 2658 | + | |
| 2700 | 2659 | nodeList->eachNode([&](const SharedNodePointer& node){ |
| 2701 | 2660 | |
| 2702 | 2661 | if (node->getActiveSocket() && node->getType() == NodeType::EntityServer) { |
| 2703 | 2662 | |
| 2663 | + NLPacketList nackPacketList(PacketType::OctreeDataNack); | |
| 2664 | + | |
| 2704 | 2665 | QUuid nodeUUID = node->getUUID(); |
| 2705 | 2666 | |
| 2706 | 2667 | // if there are octree packets from this node that are waiting to be processed, |
| @@ -2716,55 +2677,36 @@ int Application::sendNackPackets() { · 9 unmodified lines | ||
| 2716 | 2677 | _octreeSceneStatsLock.unlock(); |
| 2717 | 2678 | return; |
| 2718 | 2679 | } |
| 2719 | − | |
| 2680 | + | |
| 2720 | 2681 | // get sequence number stats of node, prune its missing set, and make a copy of the missing set |
| 2721 | 2682 | SequenceNumberStats& sequenceNumberStats = _octreeServerSceneStats[nodeUUID].getIncomingOctreeSequenceNumberStats(); |
| 2722 | 2683 | sequenceNumberStats.pruneMissingSet(); |
| 2723 | 2684 | const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = sequenceNumberStats.getMissingSet(); |
| 2724 | − | |
| 2685 | + | |
| 2725 | 2686 | _octreeSceneStatsLock.unlock(); |
| 2726 | − | |
| 2687 | + | |
| 2727 | 2688 | // construct nack packet(s) for this node |
| 2728 | − int numSequenceNumbersAvailable = missingSequenceNumbers.size(); | |
| 2729 | − QSet<OCTREE_PACKET_SEQUENCE>::const_iterator missingSequenceNumbersIterator = missingSequenceNumbers.constBegin(); | |
| 2730 | − while (numSequenceNumbersAvailable > 0) { | |
| 2731 | − | |
| 2732 | − char* dataAt = packet; | |
| 2733 | − int bytesRemaining = MAX_PACKET_SIZE; | |
| 2734 | − | |
| 2735 | − // pack header | |
| 2736 | − int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeOctreeDataNack); | |
| 2737 | − dataAt += numBytesPacketHeader; | |
| 2738 | − bytesRemaining -= numBytesPacketHeader; | |
| 2739 | − | |
| 2740 | − // calculate and pack the number of sequence numbers | |
| 2741 | − int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE); | |
| 2742 | − uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor); | |
| 2743 | − uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt; | |
| 2744 | − *numSequenceNumbersAt = numSequenceNumbers; | |
| 2745 | − dataAt += sizeof(uint16_t); | |
| 2746 | − | |
| 2747 | − // pack sequence numbers | |
| 2748 | − for (int i = 0; i < numSequenceNumbers; i++) { | |
| 2749 | − OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt; | |
| 2750 | − *sequenceNumberAt = *missingSequenceNumbersIterator; | |
| 2751 | − dataAt += sizeof(OCTREE_PACKET_SEQUENCE); | |
| 2752 | − | |
| 2753 | − missingSequenceNumbersIterator++; | |
| 2754 | − } | |
| 2755 | − numSequenceNumbersAvailable -= numSequenceNumbers; | |
| 2756 | − | |
| 2757 | − // send it | |
| 2758 | − nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node); | |
| 2759 | − packetsSent++; | |
| 2689 | + auto it = missingSequenceNumbers.constBegin(); | |
| 2690 | + while (it != missingSequenceNumbers.constEnd()) { | |
| 2691 | + OCTREE_PACKET_SEQUENCE missingNumber = *it; | |
| 2692 | + nackPacketList.writePrimitive(missingNumber); | |
| 2693 | + ++it; | |
| 2694 | + } | |
| 2695 | + | |
| 2696 | + if (nackPacketList.getNumPackets()) { | |
| 2697 | + packetsSent += nackPacketList.getNumPackets(); | |
| 2698 | + | |
| 2699 | + // send the packet list | |
| 2700 | + nodeList->sendPacketList(nackPacketList, *node); | |
| 2760 | 2701 | } |
| 2761 | 2702 | } |
| 2762 | 2703 | }); |
| 2763 | 2704 | |
| 2705 | + | |
| 2764 | 2706 | return packetsSent; |
| 2765 | 2707 | } |
| 2766 | 2708 | |
| 2767 | −void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) { | |
| 2709 | +void Application::queryOctree(NodeType_t serverType, PacketType::Value packetType, NodeToJurisdictionMap& jurisdictions) { | |
| 2768 | 2710 | |
| 2769 | 2711 | //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); |
| 2770 | 2712 | bool wantExtraDebugging = getLogger()->extraDebugging(); |
| @@ -2787,9 +2729,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 16 unmodified lines | ||
| 2787 | 2729 | _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); |
| 2788 | 2730 | _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); |
| 2789 | 2731 | |
| 2790 | − unsigned char queryPacket[MAX_PACKET_SIZE]; | |
| 2791 | − | |
| 2792 | − // Iterate all of the nodes, and get a count of how many voxel servers we have... | |
| 2732 | + // Iterate all of the nodes, and get a count of how many octree servers we have... | |
| 2793 | 2733 | int totalServers = 0; |
| 2794 | 2734 | int inViewServers = 0; |
| 2795 | 2735 | int unknownJurisdictionServers = 0; |
| @@ -2856,6 +2796,8 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 60 unmodified lines | ||
| 2856 | 2796 | qCDebug(interfaceapp, "perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); |
| 2857 | 2797 | } |
| 2858 | 2798 | |
| 2799 | + auto queryPacket = NLPacket::create(packetType); | |
| 2800 | + | |
| 2859 | 2801 | nodeList->eachNode([&](const SharedNodePointer& node){ |
| 2860 | 2802 | // only send to the NodeTypes that are serverType |
| 2861 | 2803 | if (node->getActiveSocket() && node->getType() == serverType) { |
| @@ -2930,19 +2872,13 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 68 unmodified lines | ||
| 2930 | 2872 | } else { |
| 2931 | 2873 | _octreeQuery.setMaxQueryPacketsPerSecond(0); |
| 2932 | 2874 | } |
| 2933 | − // set up the packet for sending... | |
| 2934 | − unsigned char* endOfQueryPacket = queryPacket; | |
| 2935 | 2875 | |
| 2936 | − // insert packet type/version and node UUID | |
| 2937 | − endOfQueryPacket += nodeList->populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType); | |
| 2938 | − | |
| 2939 | − // encode the query data... | |
| 2940 | − endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket); | |
| 2941 | − | |
| 2942 | − int packetLength = endOfQueryPacket - queryPacket; | |
| 2876 | + // encode the query data | |
| 2877 | + int packetSize = _octreeQuery.getBroadcastData(reinterpret_cast<unsigned char*>(queryPacket->getPayload())); | |
| 2878 | + queryPacket->setPayloadSize(packetSize); | |
| 2943 | 2879 | |
| 2944 | 2880 | // make sure we still have an active socket |
| 2945 | − nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node); | |
| 2881 | + nodeList->sendUnreliablePacket(*queryPacket, *node); | |
| 2946 | 2882 | } |
| 2947 | 2883 | }); |
| 2948 | 2884 | } |
| @@ -3006,169 +2942,6 @@ glm::vec3 Application::getSunDirection() { · 57 unmodified lines | ||
| 3006 | 2942 | // FIXME, preprocessor guard this check to occur only in DEBUG builds |
| 3007 | 2943 | static QThread * activeRenderingThread = nullptr; |
| 3008 | 2944 | |
| 3009 | −void Application::updateShadowMap(RenderArgs* renderArgs) { | |
| 3010 | − activeRenderingThread = QThread::currentThread(); | |
| 3011 | − | |
| 3012 | − PerformanceTimer perfTimer("shadowMap"); | |
| 3013 | − auto shadowFramebuffer = DependencyManager::get<TextureCache>()->getShadowFramebuffer(); | |
| 3014 | − glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(shadowFramebuffer)); | |
| 3015 | − | |
| 3016 | − glEnable(GL_DEPTH_TEST); | |
| 3017 | − glClear(GL_DEPTH_BUFFER_BIT); | |
| 3018 | − | |
| 3019 | − glm::vec3 lightDirection = getSunDirection(); | |
| 3020 | − glm::quat rotation = rotationBetween(IDENTITY_FRONT, lightDirection); | |
| 3021 | − glm::quat inverseRotation = glm::inverse(rotation); | |
| 3022 | − | |
| 3023 | − const float SHADOW_MATRIX_DISTANCES[] = { 0.0f, 2.0f, 6.0f, 14.0f, 30.0f }; | |
| 3024 | − const glm::vec2 MAP_COORDS[] = { glm::vec2(0.0f, 0.0f), glm::vec2(0.5f, 0.0f), | |
| 3025 | − glm::vec2(0.0f, 0.5f), glm::vec2(0.5f, 0.5f) }; | |
| 3026 | − | |
| 3027 | − float frustumScale = 1.0f / (_viewFrustum.getFarClip() - _viewFrustum.getNearClip()); | |
| 3028 | − loadViewFrustum(_myCamera, _viewFrustum); | |
| 3029 | − | |
| 3030 | − int matrixCount = 1; | |
| 3031 | − //int targetSize = fbo->width(); | |
| 3032 | − int sourceSize = shadowFramebuffer->getWidth(); | |
| 3033 | − int targetSize = shadowFramebuffer->getWidth(); | |
| 3034 | − float targetScale = 1.0f; | |
| 3035 | − if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { | |
| 3036 | − matrixCount = CASCADED_SHADOW_MATRIX_COUNT; | |
| 3037 | − targetSize = sourceSize / 2; | |
| 3038 | − targetScale = 0.5f; | |
| 3039 | − } | |
| 3040 | − for (int i = 0; i < matrixCount; i++) { | |
| 3041 | − const glm::vec2& coord = MAP_COORDS[i]; | |
| 3042 | − glViewport(coord.s * sourceSize, coord.t * sourceSize, targetSize, targetSize); | |
| 3043 | − | |
| 3044 | − // if simple shadow then since the resolution is twice as much as with cascaded, cover 2 regions with the map, not just one | |
| 3045 | − int regionIncrement = (matrixCount == 1 ? 2 : 1); | |
| 3046 | − float nearScale = SHADOW_MATRIX_DISTANCES[i] * frustumScale; | |
| 3047 | − float farScale = SHADOW_MATRIX_DISTANCES[i + regionIncrement] * frustumScale; | |
| 3048 | − glm::vec3 points[] = { | |
| 3049 | − glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), nearScale), | |
| 3050 | − glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), nearScale), | |
| 3051 | − glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), nearScale), | |
| 3052 | − glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), nearScale), | |
| 3053 | − glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), farScale), | |
| 3054 | − glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), farScale), | |
| 3055 | − glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), farScale), | |
| 3056 | − glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), farScale) }; | |
| 3057 | − glm::vec3 center; | |
| 3058 | − for (size_t j = 0; j < sizeof(points) / sizeof(points[0]); j++) { | |
| 3059 | − center += points[j]; | |
| 3060 | − } | |
| 3061 | − center /= (float)(sizeof(points) / sizeof(points[0])); | |
| 3062 | − float radius = 0.0f; | |
| 3063 | − for (size_t j = 0; j < sizeof(points) / sizeof(points[0]); j++) { | |
| 3064 | − radius = qMax(radius, glm::distance(points[j], center)); | |
| 3065 | − } | |
| 3066 | − if (i < 3) { | |
| 3067 | − const float RADIUS_SCALE = 0.5f; | |
| 3068 | − _shadowDistances[i] = -glm::distance(_viewFrustum.getPosition(), center) - radius * RADIUS_SCALE; | |
| 3069 | − } | |
| 3070 | − center = inverseRotation * center; | |
| 3071 | − | |
| 3072 | − // to reduce texture "shimmer," move in texel increments | |
| 3073 | − float texelSize = (2.0f * radius) / targetSize; | |
| 3074 | − center = glm::vec3(roundf(center.x / texelSize) * texelSize, roundf(center.y / texelSize) * texelSize, | |
| 3075 | − roundf(center.z / texelSize) * texelSize); | |
| 3076 | − | |
| 3077 | − glm::vec3 minima(center.x - radius, center.y - radius, center.z - radius); | |
| 3078 | − glm::vec3 maxima(center.x + radius, center.y + radius, center.z + radius); | |
| 3079 | − | |
| 3080 | − // stretch out our extents in z so that we get all of the avatars | |
| 3081 | − minima.z -= _viewFrustum.getFarClip() * 0.5f; | |
| 3082 | − maxima.z += _viewFrustum.getFarClip() * 0.5f; | |
| 3083 | − | |
| 3084 | − // save the combined matrix for rendering | |
| 3085 | − _shadowMatrices[i] = glm::transpose(glm::translate(glm::vec3(coord, 0.0f)) * | |
| 3086 | − glm::scale(glm::vec3(targetScale, targetScale, 1.0f)) * | |
| 3087 | − glm::translate(glm::vec3(0.5f, 0.5f, 0.5f)) * glm::scale(glm::vec3(0.5f, 0.5f, 0.5f)) * | |
| 3088 | − glm::ortho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z) * glm::mat4_cast(inverseRotation)); | |
| 3089 | − | |
| 3090 | − // update the shadow view frustum | |
| 3091 | − // glm::vec3 shadowFrustumCenter = glm::vec3((minima.x + maxima.x) * 0.5f, (minima.y + maxima.y) * 0.5f, (minima.z + maxima.z) * 0.5f); | |
| 3092 | − glm::vec3 shadowFrustumCenter = rotation * ((minima + maxima) * 0.5f); | |
| 3093 | − _shadowViewFrustum.setPosition(shadowFrustumCenter); | |
| 3094 | − _shadowViewFrustum.setOrientation(rotation); | |
| 3095 | − _shadowViewFrustum.setProjection(glm::ortho(minima.x, maxima.x, minima.y, maxima.y, minima.z, maxima.z)); | |
| 3096 | − _shadowViewFrustum.calculate(); | |
| 3097 | − | |
| 3098 | − glMatrixMode(GL_PROJECTION); | |
| 3099 | − glPushMatrix(); | |
| 3100 | − glLoadIdentity(); | |
| 3101 | − glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z); | |
| 3102 | − | |
| 3103 | − glm::mat4 projAgain; | |
| 3104 | − glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&projAgain); | |
| 3105 | − | |
| 3106 | − | |
| 3107 | − glMatrixMode(GL_MODELVIEW); | |
| 3108 | − glPushMatrix(); | |
| 3109 | − glLoadIdentity(); | |
| 3110 | − glm::vec3 axis = glm::axis(inverseRotation); | |
| 3111 | − glRotatef(glm::degrees(glm::angle(inverseRotation)), axis.x, axis.y, axis.z); | |
| 3112 | − | |
| 3113 | − // store view matrix without translation, which we'll use for precision-sensitive objects | |
| 3114 | − updateUntranslatedViewMatrix(); | |
| 3115 | − | |
| 3116 | − // Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation | |
| 3117 | − // the viewTransofmr object is updatded with the correct values and saved, | |
| 3118 | − // this is what is used for rendering the Entities and avatars | |
| 3119 | − Transform viewTransform; | |
| 3120 | − viewTransform.setRotation(rotation); | |
| 3121 | − // viewTransform.postTranslate(shadowFrustumCenter); | |
| 3122 | − setViewTransform(viewTransform); | |
| 3123 | − | |
| 3124 | − | |
| 3125 | − glEnable(GL_POLYGON_OFFSET_FILL); | |
| 3126 | − glPolygonOffset(1.1f, 4.0f); // magic numbers courtesy http://www.eecs.berkeley.edu/~ravir/6160/papers/shadowmaps.ppt | |
| 3127 | − | |
| 3128 | − { | |
| 3129 | − PerformanceTimer perfTimer("entities"); | |
| 3130 | − _entities.render(renderArgs); | |
| 3131 | − } | |
| 3132 | − | |
| 3133 | − glDisable(GL_POLYGON_OFFSET_FILL); | |
| 3134 | − | |
| 3135 | − glPopMatrix(); | |
| 3136 | − | |
| 3137 | − glMatrixMode(GL_PROJECTION); | |
| 3138 | − glPopMatrix(); | |
| 3139 | − | |
| 3140 | − glMatrixMode(GL_MODELVIEW); | |
| 3141 | − } | |
| 3142 | − | |
| 3143 | − // fbo->release(); | |
| 3144 | − | |
| 3145 | − glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); | |
| 3146 | − activeRenderingThread = nullptr; | |
| 3147 | −} | |
| 3148 | − | |
| 3149 | −const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f }; | |
| 3150 | −const GLfloat WORLD_DIFFUSE_COLOR[] = { 0.6f, 0.525f, 0.525f }; | |
| 3151 | −const GLfloat WORLD_SPECULAR_COLOR[] = { 0.08f, 0.08f, 0.08f, 1.0f }; | |
| 3152 | − | |
| 3153 | −const glm::vec3 GLOBAL_LIGHT_COLOR = { 0.6f, 0.525f, 0.525f }; | |
| 3154 | − | |
| 3155 | −void Application::setupWorldLight() { | |
| 3156 | − | |
| 3157 | − // Setup 3D lights (after the camera transform, so that they are positioned in world space) | |
| 3158 | − glEnable(GL_COLOR_MATERIAL); | |
| 3159 | − glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); | |
| 3160 | − | |
| 3161 | − glm::vec3 sunDirection = getSunDirection(); | |
| 3162 | − GLfloat light_position0[] = { sunDirection.x, sunDirection.y, sunDirection.z, 0.0 }; | |
| 3163 | − glLightfv(GL_LIGHT0, GL_POSITION, light_position0); | |
| 3164 | − glLightfv(GL_LIGHT0, GL_AMBIENT, WORLD_AMBIENT_COLOR); | |
| 3165 | − glLightfv(GL_LIGHT0, GL_DIFFUSE, WORLD_DIFFUSE_COLOR); | |
| 3166 | − glLightfv(GL_LIGHT0, GL_SPECULAR, WORLD_SPECULAR_COLOR); | |
| 3167 | − glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR); | |
| 3168 | − glMateriali(GL_FRONT, GL_SHININESS, 96); | |
| 3169 | − | |
| 3170 | −} | |
| 3171 | − | |
| 3172 | 2945 | bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) { |
| 3173 | 2946 | return DependencyManager::get<LODManager>()->shouldRenderMesh(largestDimension, distanceToCamera); |
| 3174 | 2947 | } |
| @@ -3189,35 +2962,25 @@ PickRay Application::computePickRay(float x, float y) const { · 14 unmodified lines | ||
| 3189 | 2962 | if (isHMDMode()) { |
| 3190 | 2963 | getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); |
| 3191 | 2964 | } else { |
| 3192 | − if (QThread::currentThread() == activeRenderingThread) { | |
| 3193 | − getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3194 | − } else { | |
| 3195 | − getViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3196 | − } | |
| 2965 | + getViewFrustum()->computePickRay(x, y, result.origin, result.direction); | |
| 3197 | 2966 | } |
| 3198 | 2967 | return result; |
| 3199 | 2968 | } |
| 3200 | 2969 | |
| 3201 | 2970 | QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { |
| 3202 | − auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer(); | |
| 3203 | − glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer)); | |
| 3204 | − | |
| 3205 | − // clear the alpha channel so the background is transparent | |
| 3206 | − glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); | |
| 3207 | − glClearColor(0.0, 0.0, 0.0, 0.0); | |
| 3208 | − glClear(GL_COLOR_BUFFER_BIT); | |
| 3209 | − glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | |
| 3210 | 2971 | |
| 3211 | 2972 | const int BILLBOARD_SIZE = 64; |
| 3212 | − // TODO: Pass a RenderArgs to renderAvatarBillboard | |
| 3213 | − renderRearViewMirror(renderArgs, QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, | |
| 3214 | − BILLBOARD_SIZE, BILLBOARD_SIZE), | |
| 3215 | − true); | |
| 2973 | + | |
| 2974 | + // Need to make sure the gl context is current here | |
| 2975 | + _glWidget->makeCurrent(); | |
| 2976 | + | |
| 2977 | + renderArgs->_renderMode = RenderArgs::DEFAULT_RENDER_MODE; | |
| 2978 | + renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true); | |
| 2979 | + | |
| 2980 | + auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | |
| 3216 | 2981 | QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32); |
| 3217 | − glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); | |
| 3218 | − glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
| 2982 | + renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image); | |
| 3219 | 2983 | |
| 3220 | − glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
| 3221 | 2984 | return image; |
| 3222 | 2985 | } |
| 3223 | 2986 | |
| @@ -3322,9 +3085,6 @@ namespace render { · 98 unmodified lines | ||
| 3322 | 3085 | PerformanceTimer perfTimer("stars"); |
| 3323 | 3086 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 3324 | 3087 | "Application::payloadRender<BackgroundRenderData>() ... stars..."); |
| 3325 | − if (!background->_stars.isStarsLoaded()) { | |
| 3326 | − background->_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED); | |
| 3327 | − } | |
| 3328 | 3088 | // should be the first rendering pass - w/o depth buffer / lighting |
| 3329 | 3089 | |
| 3330 | 3090 | // compute starfield alpha based on distance from atmosphere |
| @@ -3352,7 +3112,7 @@ namespace render { · 21 unmodified lines | ||
| 3352 | 3112 | + APPROXIMATE_DISTANCE_FROM_HORIZON; |
| 3353 | 3113 | alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); |
| 3354 | 3114 | } |
| 3355 | − | |
| 3115 | + | |
| 3356 | 3116 | |
| 3357 | 3117 | } else if (height < closestData.getAtmosphereOuterRadius()) { |
| 3358 | 3118 | alpha = (height - closestData.getAtmosphereInnerRadius()) / |
| @@ -3372,7 +3132,7 @@ namespace render { · 13 unmodified lines | ||
| 3372 | 3132 | |
| 3373 | 3133 | // finally render the starfield |
| 3374 | 3134 | if (hasStars) { |
| 3375 | − background->_stars.render(args->_viewFrustum->getFieldOfView(), args->_viewFrustum->getAspectRatio(), args->_viewFrustum->getNearClip(), alpha); | |
| 3135 | + background->_stars.render(args, alpha); | |
| 3376 | 3136 | } |
| 3377 | 3137 | |
| 3378 | 3138 | // draw the sky dome |
| @@ -3387,16 +3147,12 @@ namespace render { · 8 unmodified lines | ||
| 3387 | 3147 | } |
| 3388 | 3148 | } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { |
| 3389 | 3149 | PerformanceTimer perfTimer("skybox"); |
| 3390 | − | |
| 3150 | + | |
| 3391 | 3151 | skybox = skyStage->getSkybox(); |
| 3392 | 3152 | if (skybox) { |
| 3393 | 3153 | model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox); |
| 3394 | 3154 | } |
| 3395 | 3155 | } |
| 3396 | − // FIX ME - If I don't call this renderBatch() here, then the atmosphere and skybox don't render, but it | |
| 3397 | − // seems like these payloadRender() methods shouldn't be doing this. We need to investigate why the engine | |
| 3398 | − // isn't rendering our batch | |
| 3399 | − gpu::GLBackend::renderBatch(batch, true); | |
| 3400 | 3156 | } |
| 3401 | 3157 | } |
| 3402 | 3158 | |
| @@ -3416,76 +3172,22 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 13 unmodified lines | ||
| 3416 | 3172 | // load the view frustum |
| 3417 | 3173 | loadViewFrustum(theCamera, _displayViewFrustum); |
| 3418 | 3174 | |
| 3419 | − // transform view according to theCamera | |
| 3420 | − // could be myCamera (if in normal mode) | |
| 3421 | − // or could be viewFrustumOffsetCamera if in offset mode | |
| 3422 | − | |
| 3423 | − glm::quat rotation = theCamera.getRotation(); | |
| 3424 | − glm::vec3 axis = glm::axis(rotation); | |
| 3425 | − glRotatef(-glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); | |
| 3426 | − | |
| 3427 | − // store view matrix without translation, which we'll use for precision-sensitive objects | |
| 3428 | − updateUntranslatedViewMatrix(-theCamera.getPosition()); | |
| 3429 | − | |
| 3430 | − // Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation | |
| 3431 | − // the viewTransofmr object is updatded with the correct values and saved, | |
| 3432 | − // this is what is used for rendering the Entities and avatars | |
| 3433 | − Transform viewTransform; | |
| 3434 | − viewTransform.setTranslation(theCamera.getPosition()); | |
| 3435 | − viewTransform.setRotation(rotation); | |
| 3436 | − if (renderArgs->_renderSide != RenderArgs::MONO) { | |
| 3437 | − glm::mat4 invView = glm::inverse(_untranslatedViewMatrix); | |
| 3438 | − | |
| 3439 | − viewTransform.evalFromRawMatrix(invView); | |
| 3440 | − viewTransform.preTranslate(_viewMatrixTranslation); | |
| 3441 | − } | |
| 3442 | − | |
| 3443 | − setViewTransform(viewTransform); | |
| 3444 | − | |
| 3445 | − glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z); | |
| 3446 | − | |
| 3447 | − // Setup 3D lights (after the camera transform, so that they are positioned in world space) | |
| 3448 | − { | |
| 3449 | − PerformanceTimer perfTimer("lights"); | |
| 3450 | − setupWorldLight(); | |
| 3451 | − } | |
| 3452 | − | |
| 3453 | − // setup shadow matrices (again, after the camera transform) | |
| 3454 | − int shadowMatrixCount = 0; | |
| 3455 | − if (Menu::getInstance()->isOptionChecked(MenuOption::SimpleShadows)) { | |
| 3456 | − shadowMatrixCount = 1; | |
| 3457 | − } else if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { | |
| 3458 | − shadowMatrixCount = CASCADED_SHADOW_MATRIX_COUNT; | |
| 3459 | − } | |
| 3460 | − for (int i = shadowMatrixCount - 1; i >= 0; i--) { | |
| 3461 | − glActiveTexture(GL_TEXTURE0 + i); | |
| 3462 | − glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][0]); | |
| 3463 | − glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][1]); | |
| 3464 | − glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]); | |
| 3465 | − } | |
| 3175 | + // TODO fix shadows and make them use the GPU library | |
| 3466 | 3176 | |
| 3467 | 3177 | // The pending changes collecting the changes here |
| 3468 | 3178 | render::PendingChanges pendingChanges; |
| 3469 | 3179 | |
| 3470 | 3180 | // Background rendering decision |
| 3471 | 3181 | if (BackgroundRenderData::_item == 0) { |
| 3472 | − auto backgroundRenderData = BackgroundRenderData::Pointer(new BackgroundRenderData(&_environment)); | |
| 3473 | − auto backgroundRenderPayload = render::PayloadPointer(new BackgroundRenderData::Payload(backgroundRenderData)); | |
| 3182 | + auto backgroundRenderData = make_shared<BackgroundRenderData>(&_environment); | |
| 3183 | + auto backgroundRenderPayload = make_shared<BackgroundRenderData::Payload>(backgroundRenderData); | |
| 3474 | 3184 | BackgroundRenderData::_item = _main3DScene->allocateID(); |
| 3475 | 3185 | pendingChanges.resetItem(WorldBoxRenderData::_item, backgroundRenderPayload); |
| 3476 | 3186 | } else { |
| 3477 | 3187 | |
| 3478 | 3188 | } |
| 3479 | 3189 | |
| 3480 | − if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { | |
| 3481 | − glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
| 3482 | − } | |
| 3483 | − | |
| 3484 | − glEnable(GL_LIGHTING); | |
| 3485 | − glEnable(GL_DEPTH_TEST); | |
| 3486 | − | |
| 3487 | 3190 | // Assuming nothing get's rendered through that |
| 3488 | − | |
| 3489 | 3191 | if (!selfAvatarOnly) { |
| 3490 | 3192 | if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { |
| 3491 | 3193 | // render models... |
| @@ -3505,20 +3207,12 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 13 unmodified lines | ||
| 3505 | 3207 | renderArgs->_debugFlags = renderDebugFlags; |
| 3506 | 3208 | _entities.render(renderArgs); |
| 3507 | 3209 | } |
| 3508 | − | |
| 3509 | − // render the ambient occlusion effect if enabled | |
| 3510 | − if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { | |
| 3511 | − PerformanceTimer perfTimer("ambientOcclusion"); | |
| 3512 | − PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 3513 | − "Application::displaySide() ... AmbientOcclusion..."); | |
| 3514 | − DependencyManager::get<AmbientOcclusionEffect>()->render(); | |
| 3515 | − } | |
| 3516 | 3210 | } |
| 3517 | 3211 | |
| 3518 | 3212 | // Make sure the WorldBox is in the scene |
| 3519 | 3213 | if (WorldBoxRenderData::_item == 0) { |
| 3520 | − auto worldBoxRenderData = WorldBoxRenderData::Pointer(new WorldBoxRenderData()); | |
| 3521 | − auto worldBoxRenderPayload = render::PayloadPointer(new WorldBoxRenderData::Payload(worldBoxRenderData)); | |
| 3214 | + auto worldBoxRenderData = make_shared<WorldBoxRenderData>(); | |
| 3215 | + auto worldBoxRenderPayload = make_shared<WorldBoxRenderData::Payload>(worldBoxRenderData); | |
| 3522 | 3216 | |
| 3523 | 3217 | WorldBoxRenderData::_item = _main3DScene->allocateID(); |
| 3524 | 3218 | |
| @@ -3572,6 +3266,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 47 unmodified lines | ||
| 3572 | 3266 | renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus(); |
| 3573 | 3267 | renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect(); |
| 3574 | 3268 | |
| 3269 | + renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion); | |
| 3270 | + | |
| 3575 | 3271 | renderArgs->_shouldRender = LODManager::shouldRender; |
| 3576 | 3272 | |
| 3577 | 3273 | renderContext.args = renderArgs; |
| @@ -3580,7 +3276,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 2 unmodified lines | ||
| 3580 | 3276 | |
| 3581 | 3277 | // Before the deferred pass, let's try to use the render engine |
| 3582 | 3278 | _renderEngine->run(); |
| 3583 | − | |
| 3279 | + | |
| 3584 | 3280 | auto engineRC = _renderEngine->getRenderContext(); |
| 3585 | 3281 | sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); |
| 3586 | 3282 | sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems); |
| @@ -3591,10 +3287,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 4 unmodified lines | ||
| 3591 | 3287 | sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems); |
| 3592 | 3288 | sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems); |
| 3593 | 3289 | } |
| 3594 | − //Render the sixense lasers | |
| 3595 | − if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { | |
| 3596 | − _myAvatar->renderLaserPointers(*renderArgs->_batch); | |
| 3597 | − } | |
| 3598 | 3290 | |
| 3599 | 3291 | if (!selfAvatarOnly) { |
| 3600 | 3292 | // give external parties a change to hook in |
| @@ -3604,37 +3296,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 3 unmodified lines | ||
| 3604 | 3296 | } |
| 3605 | 3297 | } |
| 3606 | 3298 | |
| 3607 | − if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { | |
| 3608 | − glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
| 3609 | − } | |
| 3610 | − | |
| 3611 | 3299 | activeRenderingThread = nullptr; |
| 3612 | 3300 | } |
| 3613 | 3301 | |
| 3614 | −void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) { | |
| 3615 | − glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix); | |
| 3616 | − _viewMatrixTranslation = viewMatrixTranslation; | |
| 3617 | −} | |
| 3618 | − | |
| 3619 | −void Application::setViewTransform(const Transform& view) { | |
| 3620 | − _viewTransform = view; | |
| 3621 | −} | |
| 3622 | − | |
| 3623 | −void Application::loadTranslatedViewMatrix(const glm::vec3& translation) { | |
| 3624 | − glLoadMatrixf((const GLfloat*)&_untranslatedViewMatrix); | |
| 3625 | − glTranslatef(translation.x + _viewMatrixTranslation.x, translation.y + _viewMatrixTranslation.y, | |
| 3626 | − translation.z + _viewMatrixTranslation.z); | |
| 3627 | −} | |
| 3628 | − | |
| 3629 | −void Application::getModelViewMatrix(glm::dmat4* modelViewMatrix) { | |
| 3630 | − (*modelViewMatrix) =_untranslatedViewMatrix; | |
| 3631 | − (*modelViewMatrix)[3] = _untranslatedViewMatrix * glm::vec4(_viewMatrixTranslation, 1); | |
| 3632 | −} | |
| 3633 | − | |
| 3634 | −void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) { | |
| 3635 | − *projectionMatrix = _projectionMatrix; | |
| 3636 | −} | |
| 3637 | − | |
| 3638 | 3302 | void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal, |
| 3639 | 3303 | float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { |
| 3640 | 3304 | |
| @@ -3685,9 +3349,9 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) { · 44 unmodified lines | ||
| 3685 | 3349 | } |
| 3686 | 3350 | |
| 3687 | 3351 | void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) { |
| 3352 | + auto originalViewport = renderArgs->_viewport; | |
| 3688 | 3353 | // Grab current viewport to reset it at the end |
| 3689 | − int viewport[4]; | |
| 3690 | − glGetIntegerv(GL_VIEWPORT, viewport); | |
| 3354 | + | |
| 3691 | 3355 | float aspect = (float)region.width() / region.height(); |
| 3692 | 3356 | float fov = MIRROR_FIELD_OF_VIEW; |
| 3693 | 3357 | |
| @@ -3718,43 +3382,30 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 24 unmodified lines | ||
| 3718 | 3382 | // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further |
| 3719 | 3383 | // investigated in order to adapt the technique while fixing the head rendering issue, |
| 3720 | 3384 | // but the complexity of the hack suggests that a better approach |
| 3721 | − _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + | |
| 3385 | + _mirrorCamera.setPosition(_myAvatar->getDefaultEyePosition() + | |
| 3722 | 3386 | _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); |
| 3723 | 3387 | } |
| 3724 | 3388 | _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); |
| 3725 | 3389 | _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); |
| 3726 | 3390 | |
| 3391 | + | |
| 3727 | 3392 | // set the bounds of rear mirror view |
| 3393 | + gpu::Vec4i viewport; | |
| 3728 | 3394 | if (billboard) { |
| 3729 | − QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize(); | |
| 3730 | − glViewport(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); | |
| 3731 | − glScissor(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); | |
| 3732 | − renderArgs->_viewport = glm::ivec4(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); | |
| 3395 | + viewport = gpu::Vec4i(0, 0, region.width(), region.height()); | |
| 3733 | 3396 | } else { |
| 3734 | 3397 | // if not rendering the billboard, the region is in device independent coordinates; must convert to device |
| 3735 | − QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize(); | |
| 3736 | 3398 | float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale(); |
| 3737 | − int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio; | |
| 3738 | − glViewport(x, size.height() - y - height, width, height); | |
| 3739 | − glScissor(x, size.height() - y - height, width, height); | |
| 3740 | − | |
| 3741 | − renderArgs->_viewport = glm::ivec4(x, size.height() - y - height, width, height); | |
| 3399 | + int width = region.width() * ratio; | |
| 3400 | + int height = region.height() * ratio; | |
| 3401 | + viewport = gpu::Vec4i(0, 0, width, height); | |
| 3742 | 3402 | } |
| 3743 | − bool updateViewFrustum = false; | |
| 3744 | − updateProjectionMatrix(_mirrorCamera, updateViewFrustum); | |
| 3745 | − glEnable(GL_SCISSOR_TEST); | |
| 3746 | − glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
| 3403 | + renderArgs->_viewport = viewport; | |
| 3747 | 3404 | |
| 3748 | 3405 | // render rear mirror view |
| 3749 | − glPushMatrix(); | |
| 3750 | 3406 | displaySide(renderArgs, _mirrorCamera, true, billboard); |
| 3751 | − glPopMatrix(); | |
| 3752 | 3407 | |
| 3753 | − // reset Viewport and projection matrix | |
| 3754 | − renderArgs->_viewport = glm::ivec4(viewport[0], viewport[1], viewport[2], viewport[3]); | |
| 3755 | − glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); | |
| 3756 | − glDisable(GL_SCISSOR_TEST); | |
| 3757 | − updateProjectionMatrix(_myCamera, updateViewFrustum); | |
| 3408 | + renderArgs->_viewport = originalViewport; | |
| 3758 | 3409 | } |
| 3759 | 3410 | |
| 3760 | 3411 | void Application::resetSensors() { |
| @@ -3841,11 +3492,24 @@ void Application::domainChanged(const QString& domainHostname) { · 80 unmodified lines | ||
| 3841 | 3492 | _domainConnectionRefusals.clear(); |
| 3842 | 3493 | } |
| 3843 | 3494 | |
| 3844 | −void Application::domainConnectionDenied(const QString& reason) { | |
| 3495 | +void Application::handleDomainConnectionDeniedPacket(QSharedPointer<NLPacket> packet) { | |
| 3496 | + // Read deny reason from packet | |
| 3497 | + quint16 reasonSize; | |
| 3498 | + packet->readPrimitive(&reasonSize); | |
| 3499 | + QString reason = QString::fromUtf8(packet->getPayload() + packet->pos(), reasonSize); | |
| 3500 | + packet->seek(packet->pos() + reasonSize); | |
| 3501 | + | |
| 3502 | + // output to the log so the user knows they got a denied connection request | |
| 3503 | + // and check and signal for an access token so that we can make sure they are logged in | |
| 3504 | + qCDebug(interfaceapp) << "The domain-server denied a connection request: " << reason; | |
| 3505 | + qCDebug(interfaceapp) << "You may need to re-log to generate a keypair so you can provide a username signature."; | |
| 3506 | + | |
| 3845 | 3507 | if (!_domainConnectionRefusals.contains(reason)) { |
| 3846 | 3508 | _domainConnectionRefusals.append(reason); |
| 3847 | 3509 | emit domainConnectionRefused(reason); |
| 3848 | 3510 | } |
| 3511 | + | |
| 3512 | + AccountManager::getInstance().checkAndSignalForAccessToken(); | |
| 3849 | 3513 | } |
| 3850 | 3514 | |
| 3851 | 3515 | void Application::connectedToDomain(const QString& hostname) { |
| @@ -3910,12 +3574,12 @@ void Application::nodeKilled(SharedNodePointer node) { · 58 unmodified lines | ||
| 3910 | 3574 | DependencyManager::get<AvatarManager>()->clearOtherAvatars(); |
| 3911 | 3575 | } |
| 3912 | 3576 | } |
| 3913 | − | |
| 3914 | −void Application::trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket) { | |
| 3577 | + | |
| 3578 | +void Application::trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket) { | |
| 3915 | 3579 | |
| 3916 | 3580 | // Attempt to identify the sender from its address. |
| 3917 | 3581 | if (sendingNode) { |
| 3918 | − QUuid nodeUUID = sendingNode->getUUID(); | |
| 3582 | + const QUuid& nodeUUID = sendingNode->getUUID(); | |
| 3919 | 3583 | |
| 3920 | 3584 | // now that we know the node ID, let's add these stats to the stats for that node... |
| 3921 | 3585 | _octreeSceneStatsLock.lockForWrite(); |
| @@ -3927,60 +3591,54 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar · 5 unmodified lines | ||
| 3927 | 3591 | } |
| 3928 | 3592 | } |
| 3929 | 3593 | |
| 3930 | −int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode) { | |
| 3594 | +int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode) { | |
| 3931 | 3595 | // But, also identify the sender, and keep track of the contained jurisdiction root for this server |
| 3932 | 3596 | |
| 3933 | 3597 | // parse the incoming stats datas stick it in a temporary object for now, while we |
| 3934 | 3598 | // determine which server it belongs to |
| 3935 | − OctreeSceneStats temp; | |
| 3936 | − int statsMessageLength = temp.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size()); | |
| 3599 | + int statsMessageLength = 0; | |
| 3937 | 3600 | |
| 3938 | − // quick fix for crash... why would voxelServer be NULL? | |
| 3939 | − if (sendingNode) { | |
| 3940 | − QUuid nodeUUID = sendingNode->getUUID(); | |
| 3601 | + const QUuid& nodeUUID = sendingNode->getUUID(); | |
| 3602 | + | |
| 3603 | + // now that we know the node ID, let's add these stats to the stats for that node... | |
| 3604 | + _octreeSceneStatsLock.lockForWrite(); | |
| 3605 | + | |
| 3606 | + OctreeSceneStats& octreeStats = _octreeServerSceneStats[nodeUUID]; | |
| 3607 | + statsMessageLength = octreeStats.unpackFromPacket(packet); | |
| 3608 | + | |
| 3609 | + _octreeSceneStatsLock.unlock(); | |
| 3941 | 3610 | |
| 3942 | − // now that we know the node ID, let's add these stats to the stats for that node... | |
| 3943 | − _octreeSceneStatsLock.lockForWrite(); | |
| 3944 | − if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { | |
| 3945 | − _octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), | |
| 3946 | − packet.size()); | |
| 3947 | − } else { | |
| 3948 | − _octreeServerSceneStats[nodeUUID] = temp; | |
| 3949 | − } | |
| 3950 | − _octreeSceneStatsLock.unlock(); | |
| 3611 | + // see if this is the first we've heard of this node... | |
| 3612 | + NodeToJurisdictionMap* jurisdiction = NULL; | |
| 3613 | + QString serverType; | |
| 3614 | + if (sendingNode->getType() == NodeType::EntityServer) { | |
| 3615 | + jurisdiction = &_entityServerJurisdictions; | |
| 3616 | + serverType = "Entity"; | |
| 3617 | + } | |
| 3951 | 3618 | |
| 3619 | + jurisdiction->lockForRead(); | |
| 3620 | + if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { | |
| 3621 | + jurisdiction->unlock(); | |
| 3622 | + | |
| 3952 | 3623 | VoxelPositionSize rootDetails; |
| 3953 | − voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails); | |
| 3624 | + voxelDetailsForCode(octreeStats.getJurisdictionRoot(), rootDetails); | |
| 3954 | 3625 | |
| 3955 | − // see if this is the first we've heard of this node... | |
| 3956 | − NodeToJurisdictionMap* jurisdiction = NULL; | |
| 3957 | − QString serverType; | |
| 3958 | − if (sendingNode->getType() == NodeType::EntityServer) { | |
| 3959 | − jurisdiction = &_entityServerJurisdictions; | |
| 3960 | − serverType = "Entity"; | |
| 3961 | − } | |
| 3962 | − | |
| 3963 | − jurisdiction->lockForRead(); | |
| 3964 | − if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { | |
| 3965 | − jurisdiction->unlock(); | |
| 3966 | − | |
| 3967 | − qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]", | |
| 3968 | − qPrintable(serverType), | |
| 3969 | − (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); | |
| 3970 | − | |
| 3971 | − } else { | |
| 3972 | − jurisdiction->unlock(); | |
| 3973 | − } | |
| 3974 | − // store jurisdiction details for later use | |
| 3975 | − // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it | |
| 3976 | − // but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the | |
| 3977 | − // details from the OctreeSceneStats to construct the JurisdictionMap | |
| 3978 | − JurisdictionMap jurisdictionMap; | |
| 3979 | − jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes()); | |
| 3980 | − jurisdiction->lockForWrite(); | |
| 3981 | − (*jurisdiction)[nodeUUID] = jurisdictionMap; | |
| 3626 | + qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]", | |
| 3627 | + qPrintable(serverType), | |
| 3628 | + (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); | |
| 3629 | + } else { | |
| 3982 | 3630 | jurisdiction->unlock(); |
| 3983 | 3631 | } |
| 3632 | + // store jurisdiction details for later use | |
| 3633 | + // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it | |
| 3634 | + // but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the | |
| 3635 | + // details from the OctreeSceneStats to construct the JurisdictionMap | |
| 3636 | + JurisdictionMap jurisdictionMap; | |
| 3637 | + jurisdictionMap.copyContents(octreeStats.getJurisdictionRoot(), octreeStats.getJurisdictionEndNodes()); | |
| 3638 | + jurisdiction->lockForWrite(); | |
| 3639 | + (*jurisdiction)[nodeUUID] = jurisdictionMap; | |
| 3640 | + jurisdiction->unlock(); | |
| 3641 | + | |
| 3984 | 3642 | return statsMessageLength; |
| 3985 | 3643 | } |
| 3986 | 3644 | |
| @@ -4120,10 +3778,13 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 133 unmodified lines | ||
| 4120 | 3778 | |
| 4121 | 3779 | // when the worker thread is started, call our engine's run.. |
| 4122 | 3780 | connect(workerThread, &QThread::started, scriptEngine, &ScriptEngine::run); |
| 4123 | − | |
| 3781 | + | |
| 4124 | 3782 | // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue |
| 4125 | − connect(scriptEngine, SIGNAL(doneRunning()), scriptEngine, SLOT(deleteLater())); | |
| 4126 | − connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); | |
| 3783 | + connect(scriptEngine, &ScriptEngine::doneRunning, scriptEngine, &ScriptEngine::deleteLater); | |
| 3784 | + connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater); | |
| 3785 | + | |
| 3786 | + // tell the thread to stop when the script engine is done | |
| 3787 | + connect(scriptEngine, &ScriptEngine::destroyed, workerThread, &QThread::quit); | |
| 4127 | 3788 | |
| 4128 | 3789 | auto nodeList = DependencyManager::get<NodeList>(); |
| 4129 | 3790 | connect(nodeList.data(), &NodeList::nodeKilled, scriptEngine, &ScriptEngine::nodeKilled); |
| @@ -4763,7 +4424,11 @@ void Application::friendsWindowClosed() { · 633 unmodified lines | ||
| 4763 | 4424 | } |
| 4764 | 4425 | |
| 4765 | 4426 | void Application::postLambdaEvent(std::function<void()> f) { |
| 4766 | − QCoreApplication::postEvent(this, new LambdaEvent(f)); | |
| 4427 | + if (this->thread() == QThread::currentThread()) { | |
| 4428 | + f(); | |
| 4429 | + } else { | |
| 4430 | + QCoreApplication::postEvent(this, new LambdaEvent(f)); | |
| 4431 | + } | |
| 4767 | 4432 | } |
| 4768 | 4433 | |
| 4769 | 4434 | void Application::initPlugins() { |
| @@ -4824,7 +4489,7 @@ mat4 Application::getEyeProjection(int eye) const { · 54 unmodified lines | ||
| 4824 | 4489 | if (isHMDMode()) { |
| 4825 | 4490 | return OculusManager::getEyeProjection(eye); |
| 4826 | 4491 | } |
| 4827 | − | |
| 4492 | + | |
| 4828 | 4493 | return _viewFrustum.getProjection(); |
| 4829 | 4494 | } |
| 4830 | 4495 | |