History

Fixup after Merge branch 'master' of https://github.com/highfidelity/hifi into SelectionScriptingInterface

Zach Fox committed 9 years ago

Commit 0cdef282 parents 3c7fadb d675ee9164 files · +9284 −5766Browse files

Showing the changes to interface/src/Application.cpp (1 of 164 files). Show all

Unified · Split

interface/src/Application.cpp+239−153
@@ -113,7 +113,6 @@ · 112 unmodified lines
113113 #include <plugins/SteamClientPlugin.h>
114114 #include <plugins/InputConfiguration.h>
115115 #include <RecordingScriptingInterface.h>
116−#include <RenderableWebEntityItem.h>
117116 #include <UpdateSceneTask.h>
118117 #include <RenderViewTask.h>
119118 #include <SecondaryCamera.h>
@@ -139,6 +138,7 @@ · 19 unmodified lines
139138 #include <display-plugins/CompositorHelper.h>
140139 #include <trackers/EyeTracker.h>
141140 #include <avatars-renderer/ScriptAvatar.h>
141+#include <RenderableEntityItem.h>
142142
143143 #include "AudioClient.h"
144144 #include "audio/AudioScope.h"
@@ -184,6 +184,7 @@ · 39 unmodified lines
184184 #include "ui/UpdateDialog.h"
185185 #include "ui/overlays/Overlays.h"
186186 #include "ui/DomainConnectionModel.h"
187+#include "ui/ImageProvider.h"
187188 #include "Util.h"
188189 #include "InterfaceParentFinder.h"
189190 #include "ui/OctreeStatsProvider.h"
@@ -212,6 +213,73 @@ extern "C" { · 22 unmodified lines
212213 }
213214 #endif
214215
216+enum ApplicationEvent {
217+ // Execute a lambda function
218+ Lambda = QEvent::User + 1,
219+ // Trigger the next render
220+ Render,
221+ // Trigger the next idle
222+ Idle,
223+};
224+
225+
226+class RenderEventHandler : public QObject {
227+ using Parent = QObject;
228+ Q_OBJECT
229+public:
230+ RenderEventHandler(QOpenGLContext* context) {
231+ _renderContext = new OffscreenGLCanvas();
232+ _renderContext->setObjectName("RenderContext");
233+ _renderContext->create(context);
234+ if (!_renderContext->makeCurrent()) {
235+ qFatal("Unable to make rendering context current");
236+ }
237+ _renderContext->doneCurrent();
238+
239+ // Deleting the object with automatically shutdown the thread
240+ connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
241+
242+ // Transfer to a new thread
243+ moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) {
244+ hifi::qt::addBlockingForbiddenThread("Render", renderThread);
245+ _renderContext->moveToThreadWithContext(renderThread);
246+ qApp->_lastTimeRendered.start();
247+ }, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority);
248+ }
249+
250+private:
251+ void initialize() {
252+ PROFILE_SET_THREAD_NAME("Render");
253+ if (!_renderContext->makeCurrent()) {
254+ qFatal("Unable to make rendering context current on render thread");
255+ }
256+ }
257+
258+ void render() {
259+ if (qApp->shouldPaint()) {
260+ qApp->paintGL();
261+ }
262+ }
263+
264+ bool event(QEvent* event) override {
265+ switch ((int)event->type()) {
266+ case ApplicationEvent::Render:
267+ render();
268+ // Ensure we never back up the render events. Each render should be triggered only in response
269+ // to the NEXT render event after the last render occured
270+ QCoreApplication::removePostedEvents(this, ApplicationEvent::Render);
271+ return true;
272+
273+ default:
274+ break;
275+ }
276+ return Parent::event(event);
277+ }
278+
279+ OffscreenGLCanvas* _renderContext { nullptr };
280+};
281+
282+
215283 Q_LOGGING_CATEGORY(trace_app_input_mouse, "trace.app.input.mouse")
216284
217285 using namespace std;
@@ -427,10 +495,10 @@ class LambdaEvent : public QEvent { · 209 unmodified lines
427495 std::function<void()> _fun;
428496 public:
429497 LambdaEvent(const std::function<void()> & fun) :
430− QEvent(static_cast<QEvent::Type>(Application::Lambda)), _fun(fun) {
498+ QEvent(static_cast<QEvent::Type>(ApplicationEvent::Lambda)), _fun(fun) {
431499 }
432500 LambdaEvent(std::function<void()> && fun) :
433− QEvent(static_cast<QEvent::Type>(Application::Lambda)), _fun(fun) {
501+ QEvent(static_cast<QEvent::Type>(ApplicationEvent::Lambda)), _fun(fun) {
434502 }
435503 void call() const { _fun(); }
436504 };
@@ -1368,8 +1436,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 931 unmodified lines
13681436 auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
13691437 connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity,
13701438 [this](const EntityItemID& entityItemID, const PointerEvent& event) {
1371− auto entity = getEntities()->getTree()->findEntityByID(entityItemID);
1372− if (entity && entity->wantsKeyboardFocus()) {
1439+ if (getEntities()->wantsKeyboardFocus(entityItemID)) {
13731440 setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
13741441 setKeyboardFocusEntity(entityItemID);
13751442 } else {
@@ -1693,7 +1760,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 317 unmodified lines
16931760 _defaultSkybox->setCubemap(_defaultSkyboxTexture);
16941761 }
16951762
1696− EntityItem::setEntitiesShouldFadeFunction([this]() {
1763+ EntityTreeRenderer::setEntitiesShouldFadeFunction([this]() {
16971764 SharedNodePointer entityServerNode = DependencyManager::get<NodeList>()->soloNodeOfType(NodeType::EntityServer);
16981765 return entityServerNode && !isPhysicsEnabled();
16991766 });
@@ -1737,6 +1804,27 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 37 unmodified lines
17371804
17381805 connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged);
17391806
1807+ // Setup the mouse ray pick and related operators
1808+ DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(_rayPickManager.createRayPick(
1809+ RayPickFilter(DependencyManager::get<RayPickScriptingInterface>()->PICK_ENTITIES() | DependencyManager::get<RayPickScriptingInterface>()->PICK_INCLUDE_NONCOLLIDABLE()),
1810+ 0.0f, true));
1811+ DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](QUuid rayPickID) {
1812+ RayToEntityIntersectionResult entityResult;
1813+ RayPickResult result = _rayPickManager.getPrevRayPickResult(rayPickID);
1814+ entityResult.intersects = result.type != DependencyManager::get<RayPickScriptingInterface>()->INTERSECTED_NONE();
1815+ if (entityResult.intersects) {
1816+ entityResult.intersection = result.intersection;
1817+ entityResult.distance = result.distance;
1818+ entityResult.surfaceNormal = result.surfaceNormal;
1819+ entityResult.entityID = result.objectID;
1820+ entityResult.entity = DependencyManager::get<EntityTreeRenderer>()->getTree()->findEntityByID(entityResult.entityID);
1821+ }
1822+ return entityResult;
1823+ });
1824+ DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([&](QUuid rayPickID, bool value) {
1825+ _rayPickManager.setPrecisionPicking(rayPickID, value);
1826+ });
1827+
17401828 qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID());
17411829 }
17421830
@@ -2079,6 +2167,13 @@ void Application::initializeGL() { · 336 unmodified lines
20792167 _renderEngine->load();
20802168 _renderEngine->registerScene(_main3DScene);
20812169
2170+ _offscreenContext = new OffscreenGLCanvas();
2171+ _offscreenContext->setObjectName("MainThreadContext");
2172+ _offscreenContext->create(_glWidget->qglContext());
2173+ if (!_offscreenContext->makeCurrent()) {
2174+ qFatal("Unable to make offscreen context current");
2175+ }
2176+
20822177 // The UI can't be created until the primary OpenGL
20832178 // context is created, because it needs to share
20842179 // texture resources
@@ -2102,14 +2197,15 @@ void Application::initializeGL() { · 17 unmodified lines
21022197
21032198 _idleLoopStdev.reset();
21042199
2105− _offscreenContext = new OffscreenGLCanvas();
2106− _offscreenContext->setObjectName("MainThreadContext");
2107− _offscreenContext->create(_glWidget->qglContext());
2108− _offscreenContext->makeCurrent();
2200+ _renderEventHandler = new RenderEventHandler(_glWidget->qglContext());
2201+
2202+ // Restore the primary GL content for the main thread
2203+ if (!_offscreenContext->makeCurrent()) {
2204+ qFatal("Unable to make offscreen context current");
2205+ }
21092206
21102207 // update before the first render
21112208 update(0);
2112−
21132209 }
21142210
21152211 FrameTimingsScriptingInterface _frameTimingsScriptingInterface;
@@ -2117,6 +2213,9 @@ FrameTimingsScriptingInterface _frameTimingsScriptingInterface; · 1 unmodified line
21172213 extern void setupPreferences();
21182214
21192215 void Application::initializeUi() {
2216+ // Make sure all QML surfaces share the main thread GL context
2217+ OffscreenQmlSurface::setSharedContext(_offscreenContext->getContext());
2218+
21202219 AddressBarDialog::registerType();
21212220 ErrorDialog::registerType();
21222221 LoginDialog::registerType();
@@ -2127,7 +2226,7 @@ void Application::initializeUi() { · 4 unmodified lines
21272226 qmlRegisterType<Preference>("Hifi", 1, 0, "Preference");
21282227
21292228 auto offscreenUi = DependencyManager::get<OffscreenUi>();
2130− offscreenUi->create(_glWidget->qglContext());
2229+ offscreenUi->create();
21312230
21322231 auto surfaceContext = offscreenUi->getSurfaceContext();
21332232
@@ -2146,6 +2245,9 @@ void Application::initializeUi() { · 12 unmodified lines
21462245 qApp->quit();
21472246 });
21482247
2248+ // register the pixmap image provider (used only for security image, for now)
2249+ engine->addImageProvider(ImageProvider::PROVIDER_NAME, new ImageProvider());
2250+
21492251 setupPreferences();
21502252
21512253 // For some reason there is already an "Application" object in the QML context,
@@ -2270,14 +2372,12 @@ void Application::initializeUi() { · 118 unmodified lines
22702372
22712373 void Application::paintGL() {
22722374 // Some plugins process message events, allowing paintGL to be called reentrantly.
2273− if (_inPaint || _aboutToQuit || _window->isMinimized()) {
2375+ if (_aboutToQuit || _window->isMinimized()) {
22742376 return;
22752377 }
22762378
2277− _inPaint = true;
2278− Finally clearFlag([this] { _inPaint = false; });
2279−
22802379 _frameCount++;
2380+ _lastTimeRendered.start();
22812381
22822382 auto lastPaintBegin = usecTimestampNow();
22832383 PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount);
@@ -2293,18 +2393,11 @@ void Application::paintGL() { · 9 unmodified lines
22932393 displayPlugin = getActiveDisplayPlugin();
22942394 }
22952395
2296− {
2297− PROFILE_RANGE(render, "/offscreenMakeCurrent");
2298− // FIXME not needed anymore?
2299− _offscreenContext->makeCurrent();
2300− }
2301−
23022396 {
23032397 PROFILE_RANGE(render, "/pluginBeginFrameRender");
23042398 // If a display plugin loses it's underlying support, it
23052399 // needs to be able to signal us to not use it
23062400 if (!displayPlugin->beginFrameRender(_frameCount)) {
2307− _inPaint = false;
23082401 updateDisplayMode();
23092402 return;
23102403 }
@@ -2372,12 +2465,6 @@ void Application::paintGL() { · 61 unmodified lines
23722465 auto myAvatar = getMyAvatar();
23732466 boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD;
23742467
2375− if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
2376− Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
2377− Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
2378− cameraMenuChanged();
2379− }
2380−
23812468 // The render mode is default or mirror if the camera is in mirror mode, assigned further below
23822469 renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
23832470
@@ -2685,15 +2772,6 @@ void Application::resizeGL() { · 301 unmodified lines
26852772 QMutexLocker viewLocker(&_viewMutex);
26862773 _myCamera.loadViewFrustum(_viewFrustum);
26872774 }
2688−
2689− auto offscreenUi = DependencyManager::get<OffscreenUi>();
2690− auto uiSize = displayPlugin->getRecommendedUiSize();
2691− // Bit of a hack since there's no device pixel ratio change event I can find.
2692− if (offscreenUi->size() != fromGlm(uiSize)) {
2693− qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize;
2694− offscreenUi->resize(fromGlm(uiSize), true);
2695− _offscreenContext->makeCurrent();
2696− }
26972775 }
26982776
26992777 void Application::handleSandboxStatus(QNetworkReply* reply) {
@@ -2867,56 +2945,26 @@ bool Application::importFromZIP(const QString& filePath) { · 167 unmodified lines
28672945 }
28682946
28692947 void Application::onPresent(quint32 frameCount) {
2870− if (shouldPaint()) {
2871− postEvent(this, new QEvent(static_cast<QEvent::Type>(Idle)), Qt::HighEventPriority);
2872− postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority);
2948+ postEvent(this, new QEvent((QEvent::Type)ApplicationEvent::Idle), Qt::HighEventPriority);
2949+ if (_renderEventHandler && !isAboutToQuit()) {
2950+ postEvent(_renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render));
28732951 }
28742952 }
28752953
2876−bool _renderRequested { false };
2877−
2878−bool Application::event(QEvent* event) {
2879− if (!Menu::getInstance()) {
2880− return false;
2881− }
2882−
2883− int type = event->type();
2884− switch (type) {
2885− case Event::Lambda:
2886− static_cast<LambdaEvent*>(event)->call();
2887− return true;
2888−
2889− // Explicit idle keeps the idle running at a lower interval, but without any rendering
2890− // see (windowMinimizedChanged)
2891− case Event::Idle:
2892− idle();
2893− // Clear the event queue of pending idle calls
2894− removePostedEvents(this, Idle);
2895− return true;
2896−
2897− case Event::Paint:
2898− // NOTE: This must be updated as close to painting as possible,
2899− // or AvatarInputs will mysteriously move to the bottom-right
2900− AvatarInputs::getInstance()->update();
2901− paintGL();
2902− // Clear the event queue of pending paint calls
2903− removePostedEvents(this, Paint);
2904− return true;
2905−
2906− default:
2907− break;
2908− }
2954+static inline bool isKeyEvent(QEvent::Type type) {
2955+ return type == QEvent::KeyPress || type == QEvent::KeyRelease;
2956+}
29092957
2910− {
2911− if (!_keyboardFocusedEntity.get().isInvalidID()) {
2912− switch (event->type()) {
2913− case QEvent::KeyPress:
2914− case QEvent::KeyRelease: {
2915− //auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
2916− auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get());
2917− if (entity && entity->getEventHandler()) {
2958+bool Application::handleKeyEventForFocusedEntityOrOverlay(QEvent* event) {
2959+ if (!_keyboardFocusedEntity.get().isInvalidID()) {
2960+ switch (event->type()) {
2961+ case QEvent::KeyPress:
2962+ case QEvent::KeyRelease:
2963+ {
2964+ auto eventHandler = getEntities()->getEventHandler(_keyboardFocusedEntity.get());
2965+ if (eventHandler) {
29182966 event->setAccepted(false);
2919− QCoreApplication::sendEvent(entity->getEventHandler(), event);
2967+ QCoreApplication::sendEvent(eventHandler, event);
29202968 if (event->isAccepted()) {
29212969 _lastAcceptedKeyPress = usecTimestampNow();
29222970 return true;
@@ -2924,20 +2972,17 @@ bool Application::event(QEvent* event) { · 1 unmodified line
29242972 }
29252973 break;
29262974 }
2927− default:
2928− break;
2929− }
2975+ default:
2976+ break;
29302977 }
29312978 }
29322979
2933− {
2934− if (_keyboardFocusedOverlay.get() != UNKNOWN_OVERLAY_ID) {
2935− switch (event->type()) {
2936− case QEvent::KeyPress:
2937− case QEvent::KeyRelease: {
2980+ if (_keyboardFocusedOverlay.get() != UNKNOWN_OVERLAY_ID) {
2981+ switch (event->type()) {
2982+ case QEvent::KeyPress:
2983+ case QEvent::KeyRelease: {
29382984 // Only Web overlays can have focus.
2939− auto overlay =
2940− std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedOverlay.get()));
2985+ auto overlay = std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedOverlay.get()));
29412986 if (overlay && overlay->getEventHandler()) {
29422987 event->setAccepted(false);
29432988 QCoreApplication::sendEvent(overlay->getEventHandler(), event);
@@ -2946,15 +2991,52 @@ bool Application::event(QEvent* event) { · 2 unmodified lines
29462991 return true;
29472992 }
29482993 }
2949− break;
2950− }
2951− default:
2952− break;
29532994 }
2995+ break;
2996+
2997+ default:
2998+ break;
29542999 }
29553000 }
29563001
2957− switch (event->type()) {
3002+ return false;
3003+}
3004+
3005+bool Application::handleFileOpenEvent(QFileOpenEvent* fileEvent) {
3006+ QUrl url = fileEvent->url();
3007+ if (!url.isEmpty()) {
3008+ QString urlString = url.toString();
3009+ if (canAcceptURL(urlString)) {
3010+ return acceptURL(urlString);
3011+ }
3012+ }
3013+ return false;
3014+}
3015+
3016+bool Application::event(QEvent* event) {
3017+ if (!Menu::getInstance()) {
3018+ return false;
3019+ }
3020+
3021+ // Allow focused Entities and Overlays to handle keyboard input
3022+ if (isKeyEvent(event->type()) && handleKeyEventForFocusedEntityOrOverlay(event)) {
3023+ return true;
3024+ }
3025+
3026+ int type = event->type();
3027+ switch (type) {
3028+ case ApplicationEvent::Lambda:
3029+ static_cast<LambdaEvent*>(event)->call();
3030+ return true;
3031+
3032+ // Explicit idle keeps the idle running at a lower interval, but without any rendering
3033+ // see (windowMinimizedChanged)
3034+ case ApplicationEvent::Idle:
3035+ idle();
3036+ // Don't process extra idle events that arrived in the event queue while we were doing this idle
3037+ QCoreApplication::removePostedEvents(this, ApplicationEvent::Idle);
3038+ return true;
3039+
29583040 case QEvent::MouseMove:
29593041 mouseMoveEvent(static_cast<QMouseEvent*>(event));
29603042 return true;
@@ -2995,26 +3077,15 @@ bool Application::event(QEvent* event) { · 34 unmodified lines
29953077 case QEvent::Drop:
29963078 dropEvent(static_cast<QDropEvent*>(event));
29973079 return true;
2998− default:
2999− break;
3000− }
30013080
3002− // handle custom URL
3003− if (event->type() == QEvent::FileOpen) {
3004−
3005− QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
3006−
3007− QUrl url = fileEvent->url();
3008−
3009− if (!url.isEmpty()) {
3010− QString urlString = url.toString();
3011−
3012− if (canAcceptURL(urlString)) {
3013−
3014− return acceptURL(urlString);
3081+ case QEvent::FileOpen:
3082+ if (handleFileOpenEvent(static_cast<QFileOpenEvent*>(event))) {
3083+ return true;
30153084 }
3016− }
3017− return false;
3085+ break;
3086+
3087+ default:
3088+ break;
30183089 }
30193090
30203091 if (HFActionEvent::types().contains(event->type())) {
@@ -3719,11 +3790,12 @@ bool Application::acceptSnapshot(const QString& urlString) { · 698 unmodified lines
37193790
37203791 static uint32_t _renderedFrameIndex { INVALID_FRAME };
37213792
3722−bool Application::shouldPaint() {
3793+bool Application::shouldPaint() const {
37233794 if (_aboutToQuit) {
37243795 return false;
37253796 }
37263797
3798+
37273799 auto displayPlugin = getActiveDisplayPlugin();
37283800
37293801 #ifdef DEBUG_PAINT_DELAY
@@ -3739,15 +3811,14 @@ bool Application::shouldPaint() { · 9 unmodified lines
37393811 (float)paintDelaySamples / paintDelayUsecs << "us";
37403812 }
37413813 #endif
3742−
3814+
37433815 // Throttle if requested
3744− if (displayPlugin->isThrottled() && (_lastTimeUpdated.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) {
3816+ if (displayPlugin->isThrottled() && (_lastTimeRendered.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) {
37453817 return false;
37463818 }
37473819
37483820 // Sync up the _renderedFrameIndex
37493821 _renderedFrameIndex = displayPlugin->presentCount();
3750−
37513822 return true;
37523823 }
37533824
@@ -3957,7 +4028,6 @@ void setupCpuMonitorThread() { · 203 unmodified lines
39574028
39584029 #endif
39594030
3960−
39614031 void Application::idle() {
39624032 PerformanceTimer perfTimer("idle");
39634033
@@ -3988,9 +4058,17 @@ void Application::idle() { · 24 unmodified lines
39884058 });
39894059 #endif
39904060
3991−
3992−
39934061 auto displayPlugin = getActiveDisplayPlugin();
4062+ if (displayPlugin) {
4063+ auto uiSize = displayPlugin->getRecommendedUiSize();
4064+ // Bit of a hack since there's no device pixel ratio change event I can find.
4065+ if (offscreenUi->size() != fromGlm(uiSize)) {
4066+ qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize;
4067+ offscreenUi->resize(fromGlm(uiSize), true);
4068+ _offscreenContext->makeCurrent();
4069+ }
4070+ }
4071+
39944072 if (displayPlugin) {
39954073 PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate());
39964074 }
@@ -4038,6 +4116,10 @@ void Application::idle() { · 41 unmodified lines
40384116 bool showWarnings = getLogger()->extraDebugging();
40394117 PerformanceWarning warn(showWarnings, "idle()");
40404118
4119+ if (!_offscreenContext->makeCurrent()) {
4120+ qFatal("Unable to make main thread context current");
4121+ }
4122+
40414123 {
40424124 PerformanceTimer perfTimer("update");
40434125 PerformanceWarning warn(showWarnings, "Application::idle()... update()");
@@ -4100,6 +4182,13 @@ void Application::idle() { · 56 unmodified lines
41004182 }
41014183
41024184 _overlayConductor.update(secondsSinceLastUpdate);
4185+
4186+ auto myAvatar = getMyAvatar();
4187+ if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
4188+ Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
4189+ Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
4190+ cameraMenuChanged();
4191+ }
41034192 }
41044193
41054194 ivec2 Application::getMouse() const {
@@ -4354,7 +4443,6 @@ void Application::init() { · 248 unmodified lines
43544443 _timerStart.start();
43554444 _lastTimeUpdated.start();
43564445
4357−
43584446 if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
43594447 // when +connect_lobby in command line, join steam lobby
43604448 const QString STEAM_LOBBY_COMMAND_LINE_KEY = "+connect_lobby";
@@ -4403,14 +4491,7 @@ void Application::init() { · 42 unmodified lines
44034491
44044492 // Make sure any new sounds are loaded as soon as know about them.
44054493 connect(tree.get(), &EntityTree::newCollisionSoundURL, this, [this](QUrl newURL, EntityItemID id) {
4406− EntityTreePointer tree = getEntities()->getTree();
4407− if (auto entity = tree->findEntityByEntityItemID(id)) {
4408− auto sound = DependencyManager::get<SoundCache>()->getSound(newURL);
4409− auto renderable = entity->getRenderableInterface();
4410− if (renderable) {
4411− renderable->setCollisionSound(sound);
4412− }
4413− }
4494+ getEntities()->setCollisionSound(id, DependencyManager::get<SoundCache>()->getSound(newURL));
44144495 }, Qt::QueuedConnection);
44154496 connect(getMyAvatar().get(), &MyAvatar::newCollisionSoundURL, this, [this](QUrl newURL) {
44164497 if (auto avatar = getMyAvatar()) {
@@ -4721,9 +4802,12 @@ void Application::setKeyboardFocusEntity(EntityItemID entityItemID) { · 304 unmodified lines
47214802 auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
47224803 auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
47234804 if (!properties.getLocked() && properties.getVisible()) {
4724− auto entity = getEntities()->getTree()->findEntityByID(entityItemID);
4725− if (entity && entity->wantsKeyboardFocus()) {
4726− entity->setProxyWindow(_window->windowHandle());
4805+
4806+ auto entities = getEntities();
4807+ auto entityId = _keyboardFocusedEntity.get();
4808+ if (entities->wantsKeyboardFocus(entityId)) {
4809+ entities->setProxyWindow(entityId, _window->windowHandle());
4810+ auto entity = getEntities()->getEntity(entityId);
47274811 if (_keyboardMouseDevice->isActive()) {
47284812 _keyboardMouseDevice->pluginFocusOutEvent();
47294813 }
@@ -4999,7 +5083,7 @@ void Application::update(float deltaTime) { · 269 unmodified lines
49995083 PerformanceTimer perfTimer("physics");
50005084
50015085 {
5002− PROFILE_RANGE_EX(simulation_physics, "UpdateStats", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
5086+ PROFILE_RANGE_EX(simulation_physics, "UpdateStates", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
50035087
50045088 PerformanceTimer perfTimer("updateStates)");
50055089 static VectorOfMotionStates motionStates;
@@ -5068,7 +5152,7 @@ void Application::update(float deltaTime) { · 62 unmodified lines
50685152
50695153 // NOTE: the getEntities()->update() call below will wait for lock
50705154 // and will simulate entity motion (the EntityTree has been given an EntitySimulation).
5071− getEntities()->update(); // update the models...
5155+ getEntities()->update(true); // update the models...
50725156 }
50735157
50745158 myAvatar->harvestResultsFromPhysicsSimulation(deltaTime);
@@ -5081,6 +5165,9 @@ void Application::update(float deltaTime) { · 6 unmodified lines
50815165 _physicsEngine->dumpStatsIfNecessary();
50825166 }
50835167 }
5168+ } else {
5169+ // update the rendering without any simulation
5170+ getEntities()->update(false);
50845171 }
50855172
50865173 // AvatarManager update
@@ -6256,7 +6343,11 @@ bool Application::askToReplaceDomainContent(const QString& url) { · 1169 unmodified lines
62566343 octreeFilePacket->write(urlData);
62576344 limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode);
62586345 });
6259− DependencyManager::get<AddressManager>()->handleLookupString(DOMAIN_SPAWNING_POINT);
6346+ auto addressManager = DependencyManager::get<AddressManager>();
6347+ addressManager->handleLookupString(DOMAIN_SPAWNING_POINT);
6348+ QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT;
6349+ qCDebug(interfaceapp) << "Setting new home bookmark to: " << newHomeAddress;
6350+ DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(newHomeAddress);
62606351 methodDetails = "SuccessfulRequestToReplaceContent";
62616352 } else {
62626353 methodDetails = "UserDeclinedToReplaceContent";
@@ -6269,7 +6360,7 @@ bool Application::askToReplaceDomainContent(const QString& url) { · 6 unmodified lines
62696360 OffscreenUi::warning("Unable to replace content", "You do not have permissions to replace domain content",
62706361 QMessageBox::Ok, QMessageBox::Ok);
62716362 }
6272− QJsonObject messageProperties = {
6363+ QJsonObject messageProperties = {
62736364 { "status", methodDetails },
62746365 { "content_set_url", url }
62756366 };
@@ -6352,14 +6443,14 @@ void Application::showAssetServerWidget(QString filePath) { · 76 unmodified lines
63526443
63536444 void Application::addAssetToWorldFromURL(QString url) {
63546445 qInfo(interfaceapp) << "Download model and add to world from" << url;
6355−
6446+
63566447 QString filename;
63576448 if (url.contains("filename")) {
63586449 filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL.
63596450 }
63606451 if (url.contains("vr.google.com/downloads")) {
63616452 filename = url.section('/', -1);
6362− filename.remove(".zip?noDownload=false");
6453+ filename.remove(".zip");
63636454 }
63646455
63656456 if (!DependencyManager::get<NodeList>()->getThisNodeCanWriteAssets()) {
@@ -6389,7 +6480,7 @@ void Application::addAssetToWorldFromURLRequestFinished() { · 23 unmodified lines
63896480 }
63906481 if (url.contains("vr.google.com/downloads")) {
63916482 filename = url.section('/', -1);
6392− filename.remove(".zip?noDownload=false");
6483+ filename.remove(".zip");
63936484 isBlocks = true;
63946485 }
63956486
@@ -6406,6 +6497,7 @@ void Application::addAssetToWorldFromURLRequestFinished() { · 10 unmodified lines
64066497 if (tempFile.open(QIODevice::WriteOnly)) {
64076498 tempFile.write(request->getData());
64086499 addAssetToWorldInfoClear(filename); // Remove message from list; next one added will have a different key.
6500+ tempFile.close();
64096501 qApp->getFileDownloadInterface()->runUnzip(downloadPath, url, true, false, isBlocks);
64106502 } else {
64116503 QString errorInfo = "Couldn't open temporary file for download";
@@ -7223,14 +7315,6 @@ void Application::updateDisplayMode() { · 811 unmodified lines
72237315 qFatal("Attempted to switch display plugins from a non-main thread");
72247316 }
72257317
7226− // Some plugins *cough* Oculus *cough* process message events from inside their
7227− // display function, and we don't want to change the display plugin underneath
7228− // the paintGL call, so we need to guard against that
7229− // The current oculus runtime doesn't do this anymore
7230− if (_inPaint) {
7231− qFatal("Attempted to switch display plugins while in painting");
7232− }
7233−
72347318 auto menu = Menu::getInstance();
72357319 auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
72367320
@@ -7307,12 +7391,12 @@ void Application::updateDisplayMode() { · 70 unmodified lines
73077391 bool wasRepositionLocked = offscreenUi->getDesktop()->property("repositionLocked").toBool();
73087392 offscreenUi->getDesktop()->setProperty("repositionLocked", true);
73097393
7310− auto oldDisplayPlugin = _displayPlugin;
73117394 if (_displayPlugin) {
7312− disconnect(_displayPluginPresentConnection);
7395+ disconnect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent);
73137396 _displayPlugin->deactivate();
73147397 }
73157398
7399+ auto oldDisplayPlugin = _displayPlugin;
73167400 bool active = newDisplayPlugin->activate();
73177401
73187402 if (!active) {
@@ -7350,7 +7434,7 @@ void Application::updateDisplayMode() { · 31 unmodified lines
73507434 _offscreenContext->makeCurrent();
73517435 getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
73527436 _displayPlugin = newDisplayPlugin;
7353− _displayPluginPresentConnection = connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent);
7437+ connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent);
73547438 offscreenUi->getDesktop()->setProperty("repositionLocked", wasRepositionLocked);
73557439 }
73567440
@@ -7602,3 +7686,5 @@ void Application::setAvatarOverrideUrl(const QUrl& url, bool save) { · 245 unmodified lines
76027686 _avatarOverrideUrl = url;
76037687 _saveAvatarOverrideUrl = save;
76047688 }
7689+
7690+#include "Application.moc"