From c897dffb8afe576c93326dc6813d2b06a3159d0b Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Tue, 1 Feb 2022 11:16:17 -0800 Subject: [PATCH 1/4] Basic refactoring. Fix races on test startup that made the `setPosition` have no effect. Fix scaling bug in --- common/WhirlyGlobeLib/include/SceneRenderer.h | 75 ++++++++++++------- .../WhirlyGlobeLib/include/SelectionManager.h | 2 + common/WhirlyGlobeLib/src/ChangeRequest.cpp | 2 +- common/WhirlyGlobeLib/src/LayoutManager.cpp | 6 +- .../src/MaplyAnimateTranslation.cpp | 18 +++-- common/WhirlyGlobeLib/src/RenderTarget.cpp | 23 +++--- common/WhirlyGlobeLib/src/Scene.cpp | 11 ++- common/WhirlyGlobeLib/src/SceneRenderer.cpp | 36 ++++++--- .../WhirlyGlobeLib/src/SelectionManager.cpp | 18 ++--- .../AutoTester/AutoTester/MaplyTesterBridge.h | 5 +- .../testCases/BNGCustomMapTestCase.swift | 15 ++-- .../AutoTester/testCases/BNGTestCase.swift | 15 ++-- .../private/ViewPlacementActiveModel.h | 5 +- .../src/control/MaplyBaseViewController.mm | 11 +-- .../src/control/MaplyGlobeRenderController.mm | 10 +-- .../src/control/MaplyRenderController.mm | 3 +- .../src/control/MaplyViewController.mm | 12 +-- .../src/control/WhirlyGlobeViewController.mm | 44 ++++++----- .../src/gestures/MaplyTwoFingerTapDelegate.mm | 3 +- .../src/gestures/MaplyZoomGestureDelegate.mm | 13 ++-- .../src/rendering/ViewPlacementActiveModel.mm | 34 ++++----- .../WhirlyGlobeLib/src/LayerViewWatcher.mm | 4 +- .../WhirlyGlobeLib/src/SceneRendererMTL.mm | 35 +++++---- 23 files changed, 224 insertions(+), 176 deletions(-) diff --git a/common/WhirlyGlobeLib/include/SceneRenderer.h b/common/WhirlyGlobeLib/include/SceneRenderer.h index 1970f8f382..c45c34015b 100644 --- a/common/WhirlyGlobeLib/include/SceneRenderer.h +++ b/common/WhirlyGlobeLib/include/SceneRenderer.h @@ -218,14 +218,20 @@ class SceneRenderer : public DelayedDeletable virtual void setClearColor(const RGBAColor &color); /// Return the current clear color - RGBAColor getClearColor(); + RGBAColor getClearColor() const; /// Get the framebuffer size (in pixels) - Point2f getFramebufferSize(); - + Point2f getFramebufferSize() const; + + /// Get the framebuffer size (in pixels) with a margin + Mbr getFramebufferBound(float marginFrac) const; + /// Get the framebuffer size (divided by scale) - Point2f getFramebufferSizeScaled(); - + Point2f getFramebufferSizeScaled() const; + + /// Get the framebuffer size (divided by scale) with a margin + Mbr getFramebufferBoundScaled(float marginFrac) const; + /// Return the attached Scene Scene *getScene(); @@ -233,11 +239,11 @@ class SceneRenderer : public DelayedDeletable View *getView(); /// Return the device scale (e.g. retina vs. not) - float getScale(); - + float getScale() const; + /// Set the screen scale (can vary) void setScale(float newScale); - + /// Used by the subclasses to determine if the view changed and needs to be updated virtual bool viewDidChange(); @@ -325,24 +331,8 @@ class SceneRenderer : public DelayedDeletable /// Maps name IDs to slots (slots are just used by Metal) virtual int getSlotForNameID(SimpleIdentity nameID); - /// The pixel width of the CAEAGLLayer. - int framebufferWidth; - /// The pixel height of the CAEAGLLayer. - int framebufferHeight; - - /// Scale, to reflect the device's screen - float scale; - - std::vector renderTargets; - std::vector workGroups; - - // Drawables that we currently know about, but are off - std::set offDrawables; + const std::vector &getRenderTargets() const { return renderTargets; } - // Explicitly clear any held structures - void shutdown(); - -public: // Called by the subclass virtual void init(); @@ -354,9 +344,23 @@ class SceneRenderer : public DelayedDeletable // Update the extra frame rendering count virtual void updateExtraFrames(); - + + const RenderTeardownInfoRef &getTeardownInfo() const { return teardownInfo; } + +protected: + /// Set the framebuffer size + /// You probably want resize() instead. + void setFramebufferSize(float width, float height); + void setFramebufferSize(const Point2f &size) { setFramebufferSize(size.x(), size.y()); } + + // Explicitly clear any held structures + void shutdown(); + +public: /// Scene we're drawing. This is set from outside Scene *scene; + +protected: /// The view controls how we're looking at the scene View *theView; /// Set this mode to modify how Z buffering is used (if at all) @@ -402,9 +406,9 @@ class SceneRenderer : public DelayedDeletable // If we're an offline renderer, the texture we're rendering into TextureRef framebufferTex; - + TimeInterval lightsLastUpdated; - Material defaultMat; + Material defaultMat; std::vector lights; // Everything torn down until the next frame @@ -412,6 +416,21 @@ class SceneRenderer : public DelayedDeletable // Map Name IDs to slots (when using Metal) std::map slotMap; + +protected: + /// The pixel width of the CAEAGLLayer. + int framebufferWidth; + /// The pixel height of the CAEAGLLayer. + int framebufferHeight; + + /// Scale, to reflect the device's screen + float scale; + + std::vector renderTargets; + std::vector workGroups; + + // Drawables that we currently know about, but are off + std::set offDrawables; }; typedef std::shared_ptr SceneRendererRef; diff --git a/common/WhirlyGlobeLib/include/SelectionManager.h b/common/WhirlyGlobeLib/include/SelectionManager.h index 3637df41a5..9f6e65cd37 100644 --- a/common/WhirlyGlobeLib/include/SelectionManager.h +++ b/common/WhirlyGlobeLib/include/SelectionManager.h @@ -321,6 +321,8 @@ class SelectionManager : public SceneManager Point2f frameSize; Point2f frameSizeScale; + + /// frame with margin, not scaled Mbr frameMbr; }; diff --git a/common/WhirlyGlobeLib/src/ChangeRequest.cpp b/common/WhirlyGlobeLib/src/ChangeRequest.cpp index 16f43c8705..4d6dfe854f 100644 --- a/common/WhirlyGlobeLib/src/ChangeRequest.cpp +++ b/common/WhirlyGlobeLib/src/ChangeRequest.cpp @@ -31,7 +31,7 @@ void RenderTeardownInfo::destroyTexture(SceneRenderer *renderer,const TextureBas void RenderTeardownInfo::destroyDrawable(SceneRenderer *renderer,const DrawableRef &draw) { - draw->teardownForRenderer(renderer->getRenderSetupInfo(), renderer->getScene(), renderer->teardownInfo); + draw->teardownForRenderer(renderer->getRenderSetupInfo(), renderer->getScene(), renderer->getTeardownInfo()); } bool ChangeRequest::needsFlush() { return false; } diff --git a/common/WhirlyGlobeLib/src/LayoutManager.cpp b/common/WhirlyGlobeLib/src/LayoutManager.cpp index 4fbacac217..5eb0d7f2c1 100644 --- a/common/WhirlyGlobeLib/src/LayoutManager.cpp +++ b/common/WhirlyGlobeLib/src/LayoutManager.cpp @@ -768,7 +768,7 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, } // Extents for the layout helpers - const Point2f frameBufferSize(renderer->framebufferWidth, renderer->framebufferHeight); + const Point2f frameBufferSize = renderer->getFramebufferSize(); const Mbr screenMbr(frameBufferSize * -ScreenBuffer, frameBufferSize * (1.0 + ScreenBuffer)); @@ -1740,7 +1740,7 @@ void LayoutManager::handleFadeOut(const TimeInterval curTime, } // Build drawables for them... - ScreenSpaceBuilder ssBuild(renderer,coordAdapter,renderer->scale); + ScreenSpaceBuilder ssBuild(renderer,coordAdapter,renderer->getScale()); buildDrawables(ssBuild, /*doFades*/false, /*doClusters=*/false, curTime, nullptr, rebuildLayoutObjs, oldClusters, oldClusterParams, nullptr, nullptr); const auto newDraws = ssBuild.flushChanges(changes); @@ -1873,7 +1873,7 @@ void LayoutManager::updateLayout(PlatformThreadInfo *threadInfo,const ViewStateR // Generate the drawables. // Note that the renderer is not managed by a shared pointer, and will be destroyed // during shutdown, so we must stop using it quickly if controller shutdown is initiated. - ScreenSpaceBuilder ssBuild(renderer,coordAdapter,renderer->scale); + ScreenSpaceBuilder ssBuild(renderer,coordAdapter,renderer->getScale()); //wkLog("Starting Layout t=%f", curTime); diff --git a/common/WhirlyGlobeLib/src/MaplyAnimateTranslation.cpp b/common/WhirlyGlobeLib/src/MaplyAnimateTranslation.cpp index d5dfc67ea7..b7a7afcaea 100644 --- a/common/WhirlyGlobeLib/src/MaplyAnimateTranslation.cpp +++ b/common/WhirlyGlobeLib/src/MaplyAnimateTranslation.cpp @@ -24,7 +24,8 @@ using namespace Eigen; namespace Maply { -bool MaplyGestureWithinBounds(const Point2dVector &bounds,const Point3d &loc,SceneRenderer *sceneRender,MapView *testMapView,Point3d *newCenter) +bool MaplyGestureWithinBounds(const Point2dVector &bounds,const Point3d &loc, + SceneRenderer *sceneRender,MapView *testMapView,Point3d *newCenter) { if (newCenter) *newCenter = loc; @@ -33,15 +34,16 @@ bool MaplyGestureWithinBounds(const Point2dVector &bounds,const Point3d &loc,Sce return true; // The corners of the view should be within the bounds - Point2f corners[4]; - corners[0] = Point2f(0,0); - corners[1] = Point2f(sceneRender->framebufferWidth, 0.0); - corners[2] = Point2f(sceneRender->framebufferWidth, sceneRender->framebufferHeight); - corners[3] = Point2f(0.0, sceneRender->framebufferHeight); - + Point2f frameSize = sceneRender->getFramebufferSize(); + const Point2f corners[4] = { + { 0, 0 }, + { frameSize.x(), 0.0 }, + frameSize, + { 0.0, frameSize.y() }, + }; + bool isValid = false; Point2d locOffset(0,0); - Point2f frameSize(sceneRender->framebufferWidth,sceneRender->framebufferHeight); for (unsigned tests=0;tests<4;tests++) { Point3d newLoc = loc+Point3d(locOffset.x(),locOffset.y(),0.0); diff --git a/common/WhirlyGlobeLib/src/RenderTarget.cpp b/common/WhirlyGlobeLib/src/RenderTarget.cpp index 7f7bc26d4e..4f5e21ec43 100644 --- a/common/WhirlyGlobeLib/src/RenderTarget.cpp +++ b/common/WhirlyGlobeLib/src/RenderTarget.cpp @@ -66,7 +66,7 @@ AddRenderTargetReq::AddRenderTargetReq(SimpleIdentity renderTargetID,int width,i // Set up a render target void AddRenderTargetReq::execute(Scene *scene,SceneRenderer *renderer,View *view) { - RenderTargetRef renderTarget = RenderTargetRef(renderer->makeRenderTarget()); + auto renderTarget = renderer->makeRenderTarget(); renderTarget->setId(renderTargetID); renderTarget->width = width; renderTarget->height = height; @@ -81,35 +81,38 @@ void AddRenderTargetReq::execute(Scene *scene,SceneRenderer *renderer,View *view renderTarget->calcMinMax = calcMinMax; renderTarget->init(renderer,scene,texID); - renderer->addRenderTarget(renderTarget); + renderer->addRenderTarget(std::move(renderTarget)); } -ChangeRenderTargetReq::ChangeRenderTargetReq(SimpleIdentity renderTargetID,SimpleIdentity texID) -: renderTargetID(renderTargetID), texID(texID) +ChangeRenderTargetReq::ChangeRenderTargetReq(SimpleIdentity renderTargetID,SimpleIdentity texID) : + renderTargetID(renderTargetID), + texID(texID) { } void ChangeRenderTargetReq::execute(Scene *scene,SceneRenderer *renderer,View *view) { - for (RenderTargetRef renderTarget : renderer->renderTargets) + for (const auto &renderTarget : renderer->getRenderTargets()) { - if (renderTarget->getId() == renderTargetID) { + if (renderTarget->getId() == renderTargetID) + { renderTarget->setTargetTexture(renderer,scene,texID); break; } } } -ClearRenderTargetReq::ClearRenderTargetReq(SimpleIdentity targetID) -: renderTargetID(targetID) +ClearRenderTargetReq::ClearRenderTargetReq(SimpleIdentity targetID) : + renderTargetID(targetID) { } void ClearRenderTargetReq::execute(Scene *scene,SceneRenderer *renderer,View *view) { - for (RenderTargetRef renderTarget : renderer->renderTargets) + for (const auto &renderTarget : renderer->getRenderTargets()) { - if (renderTarget->getId() == renderTargetID) { + if (renderTarget->getId() == renderTargetID) + { renderTarget->clearOnce = true; break; } diff --git a/common/WhirlyGlobeLib/src/Scene.cpp b/common/WhirlyGlobeLib/src/Scene.cpp index 5cf2339331..3ce77c9a23 100644 --- a/common/WhirlyGlobeLib/src/Scene.cpp +++ b/common/WhirlyGlobeLib/src/Scene.cpp @@ -737,9 +737,9 @@ void RemTextureReq::execute(Scene *scene,SceneRenderer *renderer,WhirlyKit::View TextureBaseRef tex = scene->getTexture(texture); if (tex) { - if (renderer->teardownInfo) + if (auto info = renderer->getTeardownInfo()) { - renderer->teardownInfo->destroyTexture(renderer,tex); + info->destroyTexture(renderer,tex); } scene->removeTexture(texture); } else @@ -816,10 +816,9 @@ RemDrawableReq::RemDrawableReq(SimpleIdentity drawId,TimeInterval inWhen) void RemDrawableReq::execute(Scene *scene,SceneRenderer *renderer,WhirlyKit::View *view) { - DrawableRef draw = scene->getDrawable(drawID); - if (draw) + if (DrawableRef draw = scene->getDrawable(drawID)) { - renderer->removeDrawable(draw, true, renderer->teardownInfo); + renderer->removeDrawable(draw, true, renderer->getTeardownInfo()); scene->remDrawable(draw); } else @@ -836,7 +835,7 @@ void AddProgramReq::execute(Scene *scene,SceneRenderer *renderer,WhirlyKit::View void RemProgramReq::execute(Scene *scene,SceneRenderer *renderer,WhirlyKit::View *view) { - scene->removeProgram(programId,renderer->teardownInfo); + scene->removeProgram(programId,renderer->getTeardownInfo()); } RunBlockReq::RunBlockReq(BlockFunc newFunc) : func(std::move(newFunc)) diff --git a/common/WhirlyGlobeLib/src/SceneRenderer.cpp b/common/WhirlyGlobeLib/src/SceneRenderer.cpp index 02ac997636..de41010062 100644 --- a/common/WhirlyGlobeLib/src/SceneRenderer.cpp +++ b/common/WhirlyGlobeLib/src/SceneRenderer.cpp @@ -151,12 +151,18 @@ Scene *SceneRenderer::getScene() View *SceneRenderer::getView() { return theView; } -float SceneRenderer::getScale() +float SceneRenderer::getScale() const { return scale; } void SceneRenderer::setScale(float newScale) { scale = newScale; } +void SceneRenderer::setFramebufferSize(float width, float height) +{ + framebufferWidth = width; + framebufferHeight = height; +} + void SceneRenderer::setZBufferMode(WhirlyKitSceneRendererZBufferMode inZBufferMode) { zBufferMode = inZBufferMode; } @@ -171,9 +177,9 @@ void SceneRenderer::setView(View *newView) void SceneRenderer::addRenderTarget(RenderTargetRef newTarget) { - auto workGroup = workGroups[WorkGroup::Offscreen]; + const auto &workGroup = workGroups[WorkGroup::Offscreen]; workGroup->renderTargetContainers.push_back(workGroup->makeRenderTargetContainer(newTarget)); - renderTargets.insert(renderTargets.begin(),newTarget); + renderTargets.insert(renderTargets.begin(),std::move(newTarget)); } void SceneRenderer::addDrawable(DrawableRef newDrawable) @@ -289,21 +295,33 @@ void SceneRenderer::removeRenderTarget(SimpleIdentity targetID) } void SceneRenderer::defaultTargetInit(RenderTarget *) - { } +{ } void SceneRenderer::presentRender() - { } +{ } -Point2f SceneRenderer::getFramebufferSize() +Point2f SceneRenderer::getFramebufferSize() const { return Point2f(framebufferWidth,framebufferHeight); } -Point2f SceneRenderer::getFramebufferSizeScaled() +Mbr SceneRenderer::getFramebufferBound(float margin) const +{ + const Point2f size = getFramebufferSize(); + return { size * -margin, size * (1.0f + margin) }; +} + +Point2f SceneRenderer::getFramebufferSizeScaled() const { return Point2f(framebufferWidth/scale,framebufferHeight/scale); } - + +Mbr SceneRenderer::getFramebufferBoundScaled(float margin) const +{ + const Point2f size = getFramebufferSizeScaled(); + return { size * -margin, size * (1.0f + margin) }; +} + void SceneRenderer::setRenderUntil(TimeInterval newRenderUntil) { renderUntil = std::max(renderUntil,newRenderUntil); @@ -357,7 +375,7 @@ void SceneRenderer::setScene(WhirlyKit::Scene *newScene) } } -RGBAColor SceneRenderer::getClearColor() +RGBAColor SceneRenderer::getClearColor() const { return clearColor; } diff --git a/common/WhirlyGlobeLib/src/SelectionManager.cpp b/common/WhirlyGlobeLib/src/SelectionManager.cpp index e21cacd2bd..c3def9ede4 100644 --- a/common/WhirlyGlobeLib/src/SelectionManager.cpp +++ b/common/WhirlyGlobeLib/src/SelectionManager.cpp @@ -779,22 +779,18 @@ void SelectionManager::getScreenSpaceObjects(const PlacementInfo &pInfo,std::vec SelectionManager::PlacementInfo::PlacementInfo(ViewStateRef inViewState,SceneRenderer *renderer) : viewState(std::move(inViewState)) { - const float scale = renderer->getScale(); - // Sort out what kind of view it is globeViewState = dynamic_cast(viewState.get()); mapViewState = dynamic_cast(viewState.get()); heightAboveSurface = globeViewState ? globeViewState->heightAboveGlobe : - mapViewState ? mapViewState->heightAboveSurface : 0; + mapViewState ? mapViewState->heightAboveSurface : 0; // Calculate a slightly bigger framebuffer to grab nearby features - frameSize = Point2f(renderer->framebufferWidth,renderer->framebufferHeight); - frameSizeScale = Point2f((float)renderer->framebufferWidth/scale, - (float)renderer->framebufferHeight/scale); - const float marginX = frameSize.x() * 0.25f; - const float marginY = frameSize.y() * 0.25f; - frameMbr.ll() = Point2f(0 - marginX,0 - marginY); - frameMbr.ur() = Point2f(frameSize.x() + marginX,frameSize.y() + marginY); + frameSize = renderer->getFramebufferSize(); + frameSizeScale = renderer->getFramebufferSizeScaled(); + + const float margin = 0.25f; + frameMbr = renderer->getFramebufferBound(margin); } void SelectionManager::projectWorldPointToScreen(const Point3d &worldLoc,const PlacementInfo &pInfo,Point2dVector &screenPts,float scale) @@ -933,7 +929,7 @@ void SelectionManager::pickObjects(const Point2f &touchPt,float maxDist,const Vi const Matrix4d modelTrans = pInfo.viewState->fullMatrices[0]; const Matrix4d normalMat = pInfo.viewState->fullMatrices[0].inverse().transpose(); - const Point2f frameBufferSize(renderer->framebufferWidth, renderer->framebufferHeight); + const Point2f frameBufferSize = renderer->getFramebufferSize(); const auto layoutManager = scene->getManager(kWKLayoutManager); diff --git a/ios/apps/AutoTester/AutoTester/MaplyTesterBridge.h b/ios/apps/AutoTester/AutoTester/MaplyTesterBridge.h index 9efc727edd..6942e91eea 100644 --- a/ios/apps/AutoTester/AutoTester/MaplyTesterBridge.h +++ b/ios/apps/AutoTester/AutoTester/MaplyTesterBridge.h @@ -11,6 +11,9 @@ #import "MaplyBridge.h" +#import "GeoJSONSource.h" +#import "GeographicLib.h" + #import "MaplyTestCase.h" #import "VectorsTestCase.h" #import "TextureVectorTestCase.h" @@ -30,11 +33,9 @@ #import "PagingLayerTestCase.h" #import "VectorHoleTestCase.h" #import "VectorStyleTestCase.h" -#import "GeoJSONSource.h" #import "GlyphProblemTestCase.h" #import "ChangeVectorsTestCase.h" #import "RepresentationsTestCase.h" -#import "GeographicLib.h" #import "LIDARTestCase.h" #import "ParticleTest.h" diff --git a/ios/apps/AutoTester/AutoTester/testCases/BNGCustomMapTestCase.swift b/ios/apps/AutoTester/AutoTester/testCases/BNGCustomMapTestCase.swift index b302dde933..86c0c7ef3e 100644 --- a/ios/apps/AutoTester/AutoTester/testCases/BNGCustomMapTestCase.swift +++ b/ios/apps/AutoTester/AutoTester/testCases/BNGCustomMapTestCase.swift @@ -21,12 +21,15 @@ class BNGCustomMapTestCase: MaplyTestCase { baseCase.setUpWithMap(mapVC) createBritishNationalOverlayLocal(mapVC) - let bound = geoBound(Self.buildBritishNationalGrid(false)) - let middle = MaplyCoordinate(x: (bound.ll.x + bound.ur.x) / 2.0, - y: (bound.ll.y + bound.ur.y) / 2.0) - let h = mapVC.findHeight(toViewBounds: bound, pos: middle) - mapVC.setPosition(middle, height: h/3) - mapVC.animate(toPosition: middle, height: h, heading: 0, time: 1) + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak self] in + guard let self = self else { return } + let bound = self.geoBound(Self.buildBritishNationalGrid(false)) + let middle = MaplyCoordinate(x: (bound.ll.x + bound.ur.x) / 2.0, + y: (bound.ll.y + bound.ur.y) / 2.0) + let h = mapVC.findHeight(toViewBounds: bound, pos: middle) + mapVC.setPosition(middle, height: h/3) + mapVC.animate(toPosition: middle, height: h, heading: 0, time: 1) + } } public func geoBound(_ coordSys: MaplyCoordinateSystem) -> MaplyBoundingBox { diff --git a/ios/apps/AutoTester/AutoTester/testCases/BNGTestCase.swift b/ios/apps/AutoTester/AutoTester/testCases/BNGTestCase.swift index 2e895f031c..fb7728c5d2 100644 --- a/ios/apps/AutoTester/AutoTester/testCases/BNGTestCase.swift +++ b/ios/apps/AutoTester/AutoTester/testCases/BNGTestCase.swift @@ -26,12 +26,15 @@ class BNGTestCase: MaplyTestCase { bngCase.createBritishNationalOverlayLocal(globeVC) - let bound = bngCase.geoBound(BNGCustomMapTestCase.buildBritishNationalGrid(false)) - let middle = MaplyCoordinate(x: (bound.ll.x + bound.ur.x) / 2.0, - y: (bound.ll.y + bound.ur.y) / 2.0) - let h = globeVC.findHeight(toViewBounds: bound, pos: middle) - globeVC.setPosition(middle, height: h/3) - globeVC.animate(toPosition: middle, height: h, heading: 0, time: 1) + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak self] in + guard let self = self else { return } + let bound = self.bngCase.geoBound(BNGCustomMapTestCase.buildBritishNationalGrid(false)) + let middle = MaplyCoordinate(x: (bound.ll.x + bound.ur.x) / 2.0, + y: (bound.ll.y + bound.ur.y) / 2.0) + let h = globeVC.findHeight(toViewBounds: bound, pos: middle) + globeVC.setPosition(middle, height: h/3) + globeVC.animate(toPosition: middle, height: h, heading: 0, time: 1) + } } override func stop() { diff --git a/ios/library/WhirlyGlobe-MaplyComponent/include/private/ViewPlacementActiveModel.h b/ios/library/WhirlyGlobe-MaplyComponent/include/private/ViewPlacementActiveModel.h index cbd6d8e51f..5dcd36f283 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/include/private/ViewPlacementActiveModel.h +++ b/ios/library/WhirlyGlobe-MaplyComponent/include/private/ViewPlacementActiveModel.h @@ -1,5 +1,4 @@ -/* - * ViewPlacementGenerator.h +/* ViewPlacementGenerator.h * WhirlyGlobeLib * * Created by Steve Gifford on 7/25/12. @@ -15,12 +14,10 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ #import #import -#import "WhirlyVector.h" #import "Scene.h" #import "DataLayer.h" #import "LayerThread.h" diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseViewController.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseViewController.mm index f8b777d17d..908b77128b 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseViewController.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseViewController.mm @@ -305,7 +305,7 @@ - (void) loadSetup annotations = [NSMutableArray array]; // View placement manager - viewPlacementModel = ViewPlacementActiveModelRef(new ViewPlacementActiveModel()); + viewPlacementModel = std::make_shared(); renderControl->scene->addActiveModel(viewPlacementModel); // Apply layout fade option set before init to the newly-created manager @@ -1288,7 +1288,7 @@ - (float)currentMapScale if (!renderControl) return 0.0; - Point2f frameSize(renderControl->sceneRenderer->framebufferWidth,renderControl->sceneRenderer->framebufferHeight); + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSize(); if (frameSize.x() == 0) return MAXFLOAT; return (float)renderControl->visualView->currentMapScale(frameSize); @@ -1299,7 +1299,7 @@ - (float)heightForMapScale:(float)scale if (!renderControl) return 0.0; - Point2f frameSize(renderControl->sceneRenderer->framebufferWidth,renderControl->sceneRenderer->framebufferHeight); + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSize(); if (frameSize.x() == 0) return -1.0; return (float)renderControl->visualView->heightForMapScale(scale,frameSize); @@ -1449,7 +1449,7 @@ - (float)currentMapZoom:(MaplyCoordinate)coordinate if (!renderControl) return 0.0; - Point2f frameSize(renderControl->sceneRenderer->framebufferWidth,renderControl->sceneRenderer->framebufferHeight); + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSize(); if (frameSize.x() == 0) return MAXFLOAT; return (float)renderControl->visualView->currentMapZoom(frameSize,coordinate.y); @@ -1608,7 +1608,8 @@ - (CGSize)getFramebufferSize if (!renderControl || !renderControl->sceneRenderer) return CGSizeZero; - return CGSizeMake(renderControl->sceneRenderer->framebufferWidth,renderControl->sceneRenderer->framebufferHeight); + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSize(); + return CGSizeMake(frameSize.x(), frameSize.y()); } - (MaplyRenderType)getRenderType diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyGlobeRenderController.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyGlobeRenderController.mm index 8f9c91f328..f2e9c9122b 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyGlobeRenderController.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyGlobeRenderController.mm @@ -126,9 +126,9 @@ - (UIImage *)asImage:(MaplyRenderController *)renderControl // otherwise, use kCGImageAlphaPremultipliedLast CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, [_data bytes], [_data length], NULL); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - int framebufferWidth = renderControl->sceneRenderer->framebufferWidth; - int framebufferHeight = renderControl->sceneRenderer->framebufferHeight; - CGImageRef iref = CGImageCreate(framebufferWidth, framebufferHeight, 8, 32, framebufferWidth * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSize(); + CGImageRef iref = CGImageCreate(frameSize.x(), frameSize.y(), 8, 32, frameSize.x() * 4, colorspace, + kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, ref, NULL, true, kCGRenderingIntentDefault); // OpenGL ES measures data in PIXELS @@ -139,8 +139,8 @@ - (UIImage *)asImage:(MaplyRenderController *)renderControl // Set the scale parameter to your OpenGL ES view's contentScaleFactor // so that you get a high-resolution snapshot when its value is greater than 1.0 CGFloat scale = 1.0; - widthInPoints = framebufferWidth / scale; - heightInPoints = framebufferHeight / scale; + widthInPoints = frameSize.x() / scale; + heightInPoints = frameSize.y() / scale; UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale); } diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyRenderController.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyRenderController.mm index 57474b4fe3..145aa70493 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyRenderController.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyRenderController.mm @@ -867,7 +867,8 @@ - (CGSize)getFramebufferSize if (!sceneRenderer) return CGSizeZero; - return CGSizeMake(sceneRenderer->framebufferWidth,sceneRenderer->framebufferHeight); + const Point2f size = sceneRenderer->getFramebufferSize(); + return CGSizeMake(size.x(),size.y()); } // MARK: Snapshot protocol diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyViewController.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyViewController.mm index 318742361d..8eb3ae66d3 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyViewController.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyViewController.mm @@ -1632,11 +1632,13 @@ - (void)corners:(MaplyCoordinate *)corners if (!renderControl) return; - CGPoint screenCorners[4]; - screenCorners[0] = CGPointMake(0.0, 0.0); - screenCorners[1] = CGPointMake(renderControl->sceneRenderer->framebufferWidth,0.0); - screenCorners[2] = CGPointMake(renderControl->sceneRenderer->framebufferWidth,renderControl->sceneRenderer->framebufferHeight); - screenCorners[3] = CGPointMake(0.0, renderControl->sceneRenderer->framebufferHeight); + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSize(); + const CGPoint screenCorners[4] = { + CGPointMake(0.0f, 0.0f), + CGPointMake(frameSize.x(),0.0f), + CGPointMake(frameSize.x(),frameSize.y()), + CGPointMake(0.0f, frameSize.y()), + }; for (unsigned int ii=0;ii<4;ii++) { diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm index d9ddfb9901..15fb28d994 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm @@ -1176,12 +1176,16 @@ - (void)corners:(MaplyCoordinate *)corners forRot:(Eigen::Quaterniond)theRot vie { if (!renderControl) return; - - Point2f screenCorners[4]; - screenCorners[0] = Point2f(0.0, 0.0); - screenCorners[1] = Point2f(renderControl->sceneRenderer->framebufferWidth,0.0); - screenCorners[2] = Point2f(renderControl->sceneRenderer->framebufferWidth,renderControl->sceneRenderer->framebufferHeight); - screenCorners[3] = Point2f(0.0, renderControl->sceneRenderer->framebufferHeight); + + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSize(); + const Point2f frameSizeScaled = renderControl->sceneRenderer->getFramebufferSizeScaled(); + + const Point2f screenCorners[4] = { + Point2f(0.0, 0.0), + Point2f(frameSize.x(),0.0), + frameSize, + Point2f(0.0, frameSize.y()), + }; Eigen::Matrix4d modelTrans; Eigen::Affine3d trans(Eigen::Translation3d(0,0,-globeView->calcEarthZOffset())); @@ -1190,7 +1194,6 @@ - (void)corners:(MaplyCoordinate *)corners forRot:(Eigen::Quaterniond)theRot vie modelTrans = viewMat * modelMat; - auto frameSizeScaled = renderControl->sceneRenderer->getFramebufferSizeScaled(); for (unsigned int ii=0;ii<4;ii++) { Point3d hit; @@ -1548,7 +1551,7 @@ - (bool)screenPointFromGeo:(MaplyCoordinate)geoCoord screenPt:(CGPoint *)screenP } const auto adapter = renderControl->visualView->coordAdapter; - Point3d localPt = adapter->getCoordSystem()->geographicToLocal3d(GeoCoord(geoCoord.x,geoCoord.y)); + const Point3d localPt = adapter->getCoordSystem()->geographicToLocal3d(GeoCoord(geoCoord.x,geoCoord.y)); const Point3d displayPt = adapter->localToDisplay(localPt); const Point3f displayPtf = displayPt.cast(); @@ -1964,16 +1967,19 @@ - (int)getUsableGeoBoundsForView:(MaplyBoundingBox *)bboxes visual:(bool)visualB if (!renderControl) return 0; - float extentEps = visualBoxes ? FullExtentEps : 0.0; + const float extentEps = visualBoxes ? FullExtentEps : 0.0; - Point2f screenCorners[4]; - screenCorners[0] = Point2f(0.0, 0.0); - screenCorners[1] = Point2f(renderControl->sceneRenderer->framebufferWidth,0.0); - screenCorners[2] = Point2f(renderControl->sceneRenderer->framebufferWidth,renderControl->sceneRenderer->framebufferHeight); - screenCorners[3] = Point2f(0.0, renderControl->sceneRenderer->framebufferHeight); + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSize(); + const Point2f frameSizeScaled = renderControl->sceneRenderer->getFramebufferSizeScaled(); + + const Point2f screenCorners[4] = { + { 0.0, 0.0 }, + { frameSize.x(), 0.0 }, + frameSize, + { 0.0, frameSize.y() }, + }; - Eigen::Matrix4d modelTrans = globeView->calcFullMatrix(); - auto frameSizeScaled = renderControl->sceneRenderer->getFramebufferSizeScaled(); + const Eigen::Matrix4d modelTrans = globeView->calcFullMatrix(); Point3d corners[4]; bool cornerValid[4]; @@ -2162,11 +2168,9 @@ - (int)getUsableGeoBoundsForView:(MaplyBoundingBox *)bboxes visual:(bool)visualB } } else { // Check the poles - Point3d poles[2]; - poles[0] = Point3d(0,0,1); - poles[1] = Point3d(0,0,-1); + const Point3d poles[2] = { { 0, 0, 1 }, { 0, 0, -1 } }; - Eigen::Matrix4d modelAndViewNormalMat = modelTrans.inverse().transpose(); + const Eigen::Matrix4d modelAndViewNormalMat = modelTrans.inverse().transpose(); for (unsigned int ii=0;ii<2;ii++) { diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/MaplyTwoFingerTapDelegate.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/MaplyTwoFingerTapDelegate.mm index d4cd02c4d5..1afe51c9de 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/MaplyTwoFingerTapDelegate.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/MaplyTwoFingerTapDelegate.mm @@ -56,7 +56,8 @@ - (void)tapGesture:(id)sender const Eigen::Matrix4d theTransform = self.mapView->calcFullMatrix(); const CGPoint touchLoc = [tap locationInView:tap.view]; const Point2f touchLoc2f(touchLoc.x,touchLoc.y); - if (self.mapView->pointOnPlaneFromScreen(touchLoc2f, &theTransform, Point2f(sceneRenderer->framebufferWidth/wrapView.contentScaleFactor,sceneRenderer->framebufferHeight/wrapView.contentScaleFactor), &hit, true)) + const Point2f frameSize = sceneRenderer->getFramebufferSize(); + if (self.mapView->pointOnPlaneFromScreen(touchLoc2f, &theTransform, frameSize / wrapView.contentScaleFactor, &hit, true)) { const double newZ = curLoc.z() + (curLoc.z() - self.minZoom)/2.0; if (self.minZoom >= self.maxZoom || (self.minZoom < newZ && newZ < self.maxZoom)) diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/MaplyZoomGestureDelegate.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/MaplyZoomGestureDelegate.mm index 7a1394e2e2..c61a4d7b7a 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/MaplyZoomGestureDelegate.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/MaplyZoomGestureDelegate.mm @@ -60,16 +60,17 @@ - (void)tapGesture:(id)sender UIView *wrapView = (UIView *)tap.view; SceneRenderer *sceneRenderer = wrapView.renderer; - Point3d curLoc = _mapView->getLoc(); + const Point3d curLoc = _mapView->getLoc(); // NSLog(@"curLoc x:%f y:%f z:%f", curLoc.x(), curLoc.y(), curLoc.z()); // Just figure out where we tapped Point3d hit; - Eigen::Matrix4d theTransform = _mapView->calcFullMatrix(); - CGPoint touchLoc = [tap locationInView:tap.view]; - Point2f touchLoc2f(touchLoc.x,touchLoc.y); - if (_mapView->pointOnPlaneFromScreen(touchLoc2f, &theTransform, Point2f(sceneRenderer->framebufferWidth/wrapView.contentScaleFactor,sceneRenderer->framebufferHeight/wrapView.contentScaleFactor), &hit, true)) + const Eigen::Matrix4d theTransform = _mapView->calcFullMatrix(); + const CGPoint touchLoc = [tap locationInView:tap.view]; + const Point2f touchLoc2f(touchLoc.x,touchLoc.y); + const Point2f frameSize = sceneRenderer->getFramebufferSize(); + if (_mapView->pointOnPlaneFromScreen(touchLoc2f, &theTransform, frameSize/wrapView.contentScaleFactor, &hit, true)) { - double newZ = curLoc.z() - (curLoc.z() - _minZoom)/2.0; + const double newZ = curLoc.z() - (curLoc.z() - _minZoom)/2.0; Point2d newCenter; if (_minZoom >= _maxZoom || (_minZoom < newZ && newZ < _maxZoom)) { diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/rendering/ViewPlacementActiveModel.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/rendering/ViewPlacementActiveModel.mm index 1d51b2b2cb..8a807f6ac2 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/rendering/ViewPlacementActiveModel.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/rendering/ViewPlacementActiveModel.mm @@ -1,5 +1,4 @@ -/* - * ViewPlacementGenerator.mm +/* ViewPlacementActiveModel.mm * WhirlyGlobeLib * * Created by Steve Gifford on 7/25/12. @@ -15,7 +14,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ #import "ViewPlacementActiveModel.h" @@ -134,20 +132,20 @@ // Overall extents we'll look at. Everything else is tossed. // Note: This is too simple - Mbr frameMbr; - float marginX = frameInfo->sceneRenderer->framebufferWidth * 1.1; - float marginY = frameInfo->sceneRenderer->framebufferHeight * 1.1; - frameMbr.ll() = Point2f(0 - marginX,0 - marginY); - frameMbr.ur() = Point2f(frameInfo->sceneRenderer->framebufferWidth + marginX,frameInfo->sceneRenderer->framebufferHeight + marginY); - + const float margin = 0.1f; + const Mbr frameMbr = frameInfo->sceneRenderer->getFramebufferBound(margin); + std::vector modelAndViewMats; // modelAndViewNormalMats; - for (unsigned int offi=0;offioffsetMatrices.size();offi++) + modelAndViewMats.reserve(frameInfo->offsetMatrices.size()); + for (const auto &mat : frameInfo->offsetMatrices) + { + // Project the world location to the screen + modelAndViewMats.push_back(frameInfo->viewTrans4d * mat * frameInfo->modelTrans4d); + } + for (const auto &mat : frameInfo->offsetMatrices) { // Project the world location to the screen - Eigen::Matrix4d modelAndViewMat = frameInfo->viewTrans4d * frameInfo->offsetMatrices[offi] * frameInfo->modelTrans4d; -// Eigen::Matrix4d modelAndViewNormalMat = modelAndViewMat.inverse().transpose(); - modelAndViewMats.push_back(modelAndViewMat); -// modelAndViewNormalMats.push_back(modelAndViewNormalMat); + modelAndViewMats.push_back(frameInfo->viewTrans4d * mat * frameInfo->modelTrans4d); } std::set localViewSet; @@ -157,16 +155,14 @@ changedSinceUpdate = false; } - auto frameSizeScaled = frameInfo->sceneRenderer->getFramebufferSize(); + const auto frameSizeScaled = frameInfo->sceneRenderer->getFramebufferSize(); - for (std::set::iterator it = localViewSet.begin(); - it != localViewSet.end(); ++it) + for (const auto &viewInst : localViewSet) { - const ViewInstance &viewInst = *it; bool hidden = NO; Point2f screenPt; - if (!it->active) + if (!viewInst.active) continue; // Height above globe test diff --git a/ios/library/WhirlyGlobeLib/src/LayerViewWatcher.mm b/ios/library/WhirlyGlobeLib/src/LayerViewWatcher.mm index 66a03877f0..87d6632c6f 100644 --- a/ios/library/WhirlyGlobeLib/src/LayerViewWatcher.mm +++ b/ios/library/WhirlyGlobeLib/src/LayerViewWatcher.mm @@ -132,7 +132,7 @@ - (void)addWatcherTarget:(id)target selector:(SEL)selector minTime:(TimeInterval if (!lastViewState) { const auto __strong thread = layerThread; - if (thread.renderer->framebufferWidth != 0) + if (thread.renderer->getFramebufferSize().x() != 0) { lastViewState = view->makeViewState(thread.renderer); } @@ -189,7 +189,7 @@ - (void)viewUpdated:(View *)inView return; // The view has to be valid first - if (thread.renderer->framebufferWidth <= 0.0) + if (thread.renderer->getFramebufferSize().x() <= 0.0) { // Let's check back every so often [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(viewUpdated:) object:nil]; diff --git a/ios/library/WhirlyGlobeLib/src/SceneRendererMTL.mm b/ios/library/WhirlyGlobeLib/src/SceneRendererMTL.mm index 5d68d8ea09..9874fbe68d 100644 --- a/ios/library/WhirlyGlobeLib/src/SceneRendererMTL.mm +++ b/ios/library/WhirlyGlobeLib/src/SceneRendererMTL.mm @@ -57,14 +57,14 @@ { } -RenderTargetContainerMTL::RenderTargetContainerMTL(RenderTargetRef renderTarget) -: RenderTargetContainer(renderTarget) +RenderTargetContainerMTL::RenderTargetContainerMTL(RenderTargetRef renderTarget) : + RenderTargetContainer(std::move(renderTarget)) { } RenderTargetContainerRef WorkGroupMTL::makeRenderTargetContainer(RenderTargetRef renderTarget) { - return std::make_shared(renderTarget); + return std::make_shared(std::move(renderTarget)); } SceneRendererMTL::SceneRendererMTL(id mtlDevice,id mtlLibrary, float inScale) @@ -86,15 +86,15 @@ init(); // Calculation shaders - workGroups.push_back(WorkGroupRef(new WorkGroupMTL(WorkGroup::Calculation))); + workGroups.push_back(std::make_shared(WorkGroup::Calculation)); // Offscreen target render group - workGroups.push_back(WorkGroupRef(new WorkGroupMTL(WorkGroup::Offscreen))); + workGroups.push_back(std::make_shared(WorkGroup::Offscreen)); // Middle one for weird stuff - workGroups.push_back(WorkGroupRef(new WorkGroupMTL(WorkGroup::ReduceOps))); + workGroups.push_back(std::make_shared(WorkGroup::ReduceOps)); // Last workgroup is used for on screen rendering - workGroups.push_back(WorkGroupRef(new WorkGroupMTL(WorkGroup::ScreenRender))); + workGroups.push_back(std::make_shared(WorkGroup::ScreenRender)); - scale = inScale; + setScale(inScale); setupInfo.mtlDevice = mtlDevice; setupInfo.uniformBuff = setupInfo.heapManage.allocateBuffer(HeapManagerMTL::Drawable,sizeof(WhirlyKitShader::Uniforms)); setupInfo.lightingBuff = setupInfo.heapManage.allocateBuffer(HeapManagerMTL::Drawable,sizeof(WhirlyKitShader::Lighting)); @@ -137,9 +137,9 @@ defaultTarget->width = sizeX; defaultTarget->height = sizeY; defaultTarget->clearEveryFrame = true; - if (offscreen) { - framebufferWidth = sizeX; - framebufferHeight = sizeY; + if (offscreen) + { + setFramebufferSize(sizeX, sizeY); // Create the texture we'll use right here TextureMTLRef fbTexMTL = TextureMTLRef(new TextureMTL("Framebuffer Texture")); @@ -189,8 +189,7 @@ if (framebufferTex) return false; - framebufferWidth = sizeX; - framebufferHeight = sizeY; + setFramebufferSize(sizeX, sizeY); RenderTargetRef defaultTarget = renderTargets.back(); defaultTarget->width = sizeX; @@ -214,7 +213,7 @@ CopyIntoMtlFloat3(uniforms.eyePos,frameInfo->eyePos); CopyIntoMtlFloat3(uniforms.eyeVec,frameInfo->eyeVec); CopyIntoMtlFloat2(uniforms.screenSizeInDisplayCoords,Point2f(frameInfo->screenSizeInDisplayCoords.x(),frameInfo->screenSizeInDisplayCoords.y())); - Point2f frameSize(frameInfo->sceneRenderer->framebufferWidth,frameInfo->sceneRenderer->framebufferHeight); + const Point2f frameSize = frameInfo->sceneRenderer->getFramebufferSize(); CopyIntoMtlFloat2(uniforms.frameSize, frameSize); uniforms.globeMode = !coordAdapter->isFlat(); uniforms.frameCount = frameCount; @@ -468,7 +467,7 @@ const Eigen::Matrix4f viewTrans = Matrix4dToMatrix4f(viewTrans4d); // Set up a projection matrix - const Point2f frameSize(framebufferWidth,framebufferHeight); + const Point2f frameSize = getFramebufferSize(); const Eigen::Matrix4d projMat4d = theView->calcProjectionMatrix(frameSize,0.0); const Eigen::Matrix4d modelAndViewMat4d = viewTrans4d * modelTrans4d; @@ -521,11 +520,12 @@ frameCount++; - TimeInterval now = scene->getCurrentTime(); + const TimeInterval now = scene->getCurrentTime(); teardownInfo = NULL; - if (framebufferWidth <= 0 || framebufferHeight <= 0) + const Point2f frameSize = getFramebufferSize(); + if (frameSize.x() <= 0 || frameSize.y() <= 0) { // Process the scene even if the window isn't up processScene(now); @@ -557,7 +557,6 @@ Eigen::Matrix4f modelTrans = Matrix4dToMatrix4f(modelTrans4d); // Set up a projection matrix - Point2f frameSize(framebufferWidth,framebufferHeight); Eigen::Matrix4d projMat4d = theView->calcProjectionMatrix(frameSize,0.0); Eigen::Matrix4d modelAndViewMat4d = viewTrans4d * modelTrans4d; From fae8574c90de1caad04b093041148a7c13dd3548 Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Tue, 1 Feb 2022 11:17:18 -0800 Subject: [PATCH 2/4] Fix scaling error in globe `getUsableGeoBoundsForView` (which doesn't seem to be used anywhere) --- .../src/control/WhirlyGlobeViewController.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm index 15fb28d994..4d7ec21701 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm @@ -2178,10 +2178,14 @@ - (int)getUsableGeoBoundsForView:(MaplyBoundingBox *)bboxes visual:(bool)visualB if (CheckPointAndNormFacing(pt,pt.normalized(),modelTrans,modelAndViewNormalMat) < 0.0) continue; - Point2f screenPt = globeView->pointOnScreenFromSphere(pt, &modelTrans, frameSizeScaled); + const Point2f screenPt = globeView->pointOnScreenFromSphere(pt, &modelTrans, frameSizeScaled); + const Point2f frameSize = renderControl->sceneRenderer->getFramebufferSizeScaled(); - if (screenPt.x() < 0 || screenPt.y() < 0 || screenPt.x() > renderControl->sceneRenderer->framebufferWidth || screenPt.y() > renderControl->sceneRenderer->framebufferHeight) + if (screenPt.x() < 0 || screenPt.y() < 0 || + screenPt.x() > frameSize.x() || screenPt.y() > frameSize.y()) + { continue; + } // Include the pole and just do the whole area switch (ii) From e2fc64e4ed3c6ca50f3c2dbf41cce6be3261d502 Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Tue, 1 Feb 2022 13:12:19 -0800 Subject: [PATCH 3/4] Add a way to run code right after init instead of hoping `async` takes long enough. More cleanup. --- common/WhirlyGlobeLib/include/WhirlyKitView.h | 13 +++-- common/WhirlyGlobeLib/src/GlobeView.cpp | 6 +- common/WhirlyGlobeLib/src/SceneRenderer.cpp | 2 +- common/WhirlyGlobeLib/src/WhirlyKitView.cpp | 26 +++++---- .../testCases/BNGCustomMapTestCase.swift | 2 +- .../AutoTester/testCases/BNGTestCase.swift | 2 +- .../include/control/MaplyBaseViewController.h | 7 +++ .../private/MaplyBaseViewController_private.h | 2 +- .../src/control/MaplyBaseViewController.mm | 51 ++++++++++++++--- .../src/control/WhirlyGlobeViewController.mm | 15 ++++- .../src/gestures/GlobeDoubleTapDelegate.mm | 20 +++---- .../gestures/GlobeDoubleTapDragDelegate.mm | 1 + .../src/gestures/GlobeTwoFingerTapDelegate.mm | 4 +- ios/library/WhirlyGlobeLib/include/MTLView.h | 17 ++---- .../WhirlyGlobeLib/include/ViewWrapper.h | 24 +++++--- ios/library/WhirlyGlobeLib/src/MTLView.mm | 57 ++++++++++++------- 16 files changed, 160 insertions(+), 89 deletions(-) diff --git a/common/WhirlyGlobeLib/include/WhirlyKitView.h b/common/WhirlyGlobeLib/include/WhirlyKitView.h index 02a4cd5a27..ec90ba8421 100644 --- a/common/WhirlyGlobeLib/include/WhirlyKitView.h +++ b/common/WhirlyGlobeLib/include/WhirlyKitView.h @@ -135,15 +135,18 @@ class View : public DelayedDeletable /// Used by subclasses to notify all the watchers of updates virtual void runViewUpdates(); - double fieldOfView,imagePlaneSize,nearPlane,farPlane; - Point2d centerOffset; + double fieldOfView = 0.0; + double imagePlaneSize = 0.0; + double nearPlane = 0.001; + double farPlane = 10.0; + Point2d centerOffset = { 0, 0 }; std::vector offsetMatrices; /// The last time the position was changed - TimeInterval lastChangedTime; + TimeInterval lastChangedTime = 0.0; /// Display adapter and coordinate system we're working in - WhirlyKit::CoordSystemDisplayAdapter *coordAdapter; + WhirlyKit::CoordSystemDisplayAdapter *coordAdapter = nullptr; /// If set, we'll scale the near and far clipping planes as we get closer - bool continuousZoom; + bool continuousZoom = false; /// Called when positions are updated ViewWatcherSet watchers; diff --git a/common/WhirlyGlobeLib/src/GlobeView.cpp b/common/WhirlyGlobeLib/src/GlobeView.cpp index 539fbfd722..a492988017 100644 --- a/common/WhirlyGlobeLib/src/GlobeView.cpp +++ b/common/WhirlyGlobeLib/src/GlobeView.cpp @@ -225,11 +225,11 @@ Eigen::Matrix4d GlobeView::calcModelMatrix() const Point2d modelOff(0.0,0.0); if (centerOffset.x() != 0.0 || centerOffset.y() != 0.0) { // imagePlaneSize is actually half the image plane size in the horizontal - modelOff = Point2d(centerOffset.x() * imagePlaneSize, centerOffset.y() * imagePlaneSize) * (heightAboveGlobe+1.0)/nearPlane; + modelOff = (centerOffset * imagePlaneSize) * (heightAboveGlobe+1.0)/nearPlane; } - Eigen::Affine3d trans(Eigen::Translation3d(modelOff.x(),modelOff.y(),-calcEarthZOffset())); - Eigen::Affine3d rot(rotQuat); + const Eigen::Affine3d trans(Eigen::Translation3d(modelOff.x(),modelOff.y(),-calcEarthZOffset())); + const Eigen::Affine3d rot(rotQuat); return (trans * rot).matrix(); } diff --git a/common/WhirlyGlobeLib/src/SceneRenderer.cpp b/common/WhirlyGlobeLib/src/SceneRenderer.cpp index de41010062..c1746ce946 100644 --- a/common/WhirlyGlobeLib/src/SceneRenderer.cpp +++ b/common/WhirlyGlobeLib/src/SceneRenderer.cpp @@ -313,7 +313,7 @@ Mbr SceneRenderer::getFramebufferBound(float margin) const Point2f SceneRenderer::getFramebufferSizeScaled() const { - return Point2f(framebufferWidth/scale,framebufferHeight/scale); + return Point2f(framebufferWidth,framebufferHeight) / ((scale != 0) ? scale : 1.0f); } Mbr SceneRenderer::getFramebufferBoundScaled(float margin) const diff --git a/common/WhirlyGlobeLib/src/WhirlyKitView.cpp b/common/WhirlyGlobeLib/src/WhirlyKitView.cpp index 7c01ae9117..effe55707b 100644 --- a/common/WhirlyGlobeLib/src/WhirlyKitView.cpp +++ b/common/WhirlyGlobeLib/src/WhirlyKitView.cpp @@ -29,27 +29,31 @@ using namespace Eigen; namespace WhirlyKit { -View::View() : - coordAdapter(nullptr) +View::View() { fieldOfView = 60.0 / 360.0 * 2 * M_PI; // 60 degree field of view - nearPlane = 0.001; imagePlaneSize = nearPlane * std::tan(fieldOfView / 2.0f); - farPlane = 10.0; - centerOffset = Point2d(0.0,0.0); lastChangedTime = TimeGetCurrent(); - continuousZoom = false; } -View::View(const View &that) - : fieldOfView(that.fieldOfView), nearPlane(that.nearPlane), imagePlaneSize(that.imagePlaneSize), - farPlane(that.farPlane), lastChangedTime(that.lastChangedTime), continuousZoom(that.continuousZoom), - coordAdapter(that.coordAdapter) +View::View(const View &that) : + nearPlane(that.nearPlane), + farPlane(that.farPlane), + fieldOfView(that.fieldOfView), + imagePlaneSize(that.imagePlaneSize), + lastChangedTime(that.lastChangedTime), + continuousZoom(that.continuousZoom), + coordAdapter(that.coordAdapter), + centerOffset(that.centerOffset) { } - + void View::calcFrustumWidth(unsigned int frameWidth,unsigned int frameHeight,Point2d &ll,Point2d &ur,double & near,double &far) { + if (frameWidth == 0) + { + return; + } ll.x() = -imagePlaneSize; ur.x() = imagePlaneSize; const double ratio = ((double)frameHeight / (double)frameWidth); diff --git a/ios/apps/AutoTester/AutoTester/testCases/BNGCustomMapTestCase.swift b/ios/apps/AutoTester/AutoTester/testCases/BNGCustomMapTestCase.swift index 86c0c7ef3e..9bb211cbd6 100644 --- a/ios/apps/AutoTester/AutoTester/testCases/BNGCustomMapTestCase.swift +++ b/ios/apps/AutoTester/AutoTester/testCases/BNGCustomMapTestCase.swift @@ -21,7 +21,7 @@ class BNGCustomMapTestCase: MaplyTestCase { baseCase.setUpWithMap(mapVC) createBritishNationalOverlayLocal(mapVC) - DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak self] in + mapVC.addPostInitBlock { [weak self] in guard let self = self else { return } let bound = self.geoBound(Self.buildBritishNationalGrid(false)) let middle = MaplyCoordinate(x: (bound.ll.x + bound.ur.x) / 2.0, diff --git a/ios/apps/AutoTester/AutoTester/testCases/BNGTestCase.swift b/ios/apps/AutoTester/AutoTester/testCases/BNGTestCase.swift index fb7728c5d2..6a383806f5 100644 --- a/ios/apps/AutoTester/AutoTester/testCases/BNGTestCase.swift +++ b/ios/apps/AutoTester/AutoTester/testCases/BNGTestCase.swift @@ -26,7 +26,7 @@ class BNGTestCase: MaplyTestCase { bngCase.createBritishNationalOverlayLocal(globeVC) - DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak self] in + globeVC.addPostInitBlock { [weak self] in guard let self = self else { return } let bound = self.bngCase.geoBound(BNGCustomMapTestCase.buildBritishNationalGrid(false)) let middle = MaplyCoordinate(x: (bound.ll.x + bound.ur.x) / 2.0, diff --git a/ios/library/WhirlyGlobe-MaplyComponent/include/control/MaplyBaseViewController.h b/ios/library/WhirlyGlobe-MaplyComponent/include/control/MaplyBaseViewController.h index 3f6dde5cfb..9959b97399 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/include/control/MaplyBaseViewController.h +++ b/ios/library/WhirlyGlobe-MaplyComponent/include/control/MaplyBaseViewController.h @@ -41,6 +41,7 @@ #import "rendering/MaplyVertexAttribute.h" typedef double (^ZoomEasingBlock)(double z0,double z1,double t); +typedef void (__strong ^InitCompletionBlock)(void); /** When selecting multiple objects, one or more of these is returned. @@ -1572,4 +1573,10 @@ typedef double (^ZoomEasingBlock)(double z0,double z1,double t); /// Return the renderer type being used - (MaplyRenderType)getRenderType; +/** + Blocks to be called after the view is set up, or immediately if it is already set up. + Similar to `addPostSurfaceRunnable` on Android. +*/ +- (void)addPostInitBlock:(_Nonnull InitCompletionBlock)block; + @end diff --git a/ios/library/WhirlyGlobe-MaplyComponent/include/private/MaplyBaseViewController_private.h b/ios/library/WhirlyGlobe-MaplyComponent/include/private/MaplyBaseViewController_private.h index d12ff9fdb4..868df0589b 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/include/private/MaplyBaseViewController_private.h +++ b/ios/library/WhirlyGlobe-MaplyComponent/include/private/MaplyBaseViewController_private.h @@ -37,7 +37,7 @@ #import "FontTextureManager_iOS.h" #import "ViewWrapper.h" -@interface MaplyBaseViewController() +@interface MaplyBaseViewController() { @public MaplyRenderController *renderControl; diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseViewController.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseViewController.mm index 908b77128b..7be90bd119 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseViewController.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseViewController.mm @@ -17,7 +17,7 @@ */ #import "control/MaplyBaseViewController.h" -#import "MaplyBaseViewController_private.h" +#import "private/MaplyBaseViewController_private.h" #import "UIKit/NSData+Zlib.h" #import "MaplyTexture_private.h" @@ -115,11 +115,13 @@ @implementation MaplyBaseViewController { MaplyLocationTracker *_locationTracker; bool _layoutFade; + NSMutableArray *_postInitCalls; } - (instancetype)init{ self = [super init]; _layoutFade = false; + _postInitCalls = [NSMutableArray new]; return self; } @@ -169,14 +171,13 @@ - (ViewRef) loadSetup_view - (void)loadSetup_mtlView { SceneRendererMTL *renderMTL = (SceneRendererMTL *)renderControl->sceneRenderer.get(); - - WhirlyKitMTLView *mtlView = [[WhirlyKitMTLView alloc] initWithDevice:((RenderSetupInfoMTL *) renderMTL->getRenderSetupInfo())->mtlDevice]; + RenderSetupInfoMTL *setupInfo = (RenderSetupInfoMTL *) renderMTL->getRenderSetupInfo(); + + WhirlyKitMTLView *mtlView = [[WhirlyKitMTLView alloc] initWithDevice:setupInfo->mtlDevice]; + mtlView.preferredFramesPerSecond = (_frameInterval > 0) ? (60.0 / _frameInterval) : 120; + mtlView.wrapperDelegate = self; + wrapView = mtlView; - if (_frameInterval <= 0) - mtlView.preferredFramesPerSecond = 120; - else { - mtlView.preferredFramesPerSecond = 60 / _frameInterval; - } } - (MaplyBaseInteractionLayer *) loadSetup_interactionLayer @@ -426,11 +427,18 @@ - (void)viewWillDisappear:(BOOL)animated - (void)viewWillLayoutSubviews { - if (wrapView) { + if (wrapView) + { wrapView.frame = self.view.bounds; } } +- (void)viewDidLayoutSubviews +{ + // The layout hasn't actually run yet, it's only been kicked off + // See `layoutDidRun:` +} + - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; @@ -1672,4 +1680,29 @@ - (MaplyRemoteTileFetcher *)addTileFetcher:(NSString * __nonnull)name return renderControl ? [renderControl addTileFetcher:name] : nil; } +- (void)layoutDidRun +{ + // Layout complete, we can do stuff like `findHeightToViewBounds` now + for (InitCompletionBlock block in _postInitCalls) + { + block(); + } + _postInitCalls = nil; +} + +- (void)addPostInitBlock:(_Nonnull InitCompletionBlock)block +{ + if (block) + { + if (_postInitCalls) + { + [_postInitCalls addObject:block]; + } + else + { + block(); + } + } +} + @end diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm index 4d7ec21701..26ce563bef 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/WhirlyGlobeViewController.mm @@ -1527,13 +1527,22 @@ - (CGPoint)pointOnScreenFromGeo:(MaplyCoordinate)geoCoord - (CGPoint)pointOnScreenFromGeo:(MaplyCoordinate)geoCoord globeView:(GlobeView *)theView { if (!renderControl) - return CGPointMake(0.0, 0.0); - + { + return CGPointZero; + } + + const Point2f frameSizeScaled = renderControl->sceneRenderer->getFramebufferSizeScaled(); + if (frameSizeScaled.x() <= 0 || frameSizeScaled.y() <= 0) + { + // Called too early, wait until we're set up + return CGPointZero; + } + Point3d pt = theView->coordAdapter->localToDisplay(theView->coordAdapter->getCoordSystem()->geographicToLocal3d(GeoCoord(geoCoord.x,geoCoord.y))); Eigen::Matrix4d modelTrans = theView->calcFullMatrix(); - auto screenPt = theView->pointOnScreenFromSphere(pt, &modelTrans, renderControl->sceneRenderer->getFramebufferSizeScaled()); + auto screenPt = theView->pointOnScreenFromSphere(pt, &modelTrans, frameSizeScaled); return CGPointMake(screenPt.x(),screenPt.y()); } diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeDoubleTapDelegate.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeDoubleTapDelegate.mm index c022c5232b..8b29bc7ba1 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeDoubleTapDelegate.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeDoubleTapDelegate.mm @@ -1,6 +1,4 @@ -/* - * GlobeDoubleTapDelegate.mm - * +/* GlobeDoubleTapDelegate.mm * * Created by Steve Gifford on 2/7/14. * Copyright 2011-2022 mousebird consulting @@ -15,12 +13,12 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ #import "gestures/GlobeDoubleTapDelegate.h" #import "GlobeAnimateHeight.h" #import "ViewWrapper.h" +#import "SceneRenderer.h" using namespace WhirlyKit; using namespace WhirlyGlobe; @@ -54,19 +52,19 @@ - (void)tapGesture:(id)sender // Just figure out where we tapped Point3d hit; - Eigen::Matrix4d theTransform = globeView->calcFullMatrix(); - CGPoint touchLoc = [tap locationInView:tap.view]; - Point2f touchLoc2f(touchLoc.x,touchLoc.y); + const Eigen::Matrix4d theTransform = globeView->calcFullMatrix(); + const CGPoint touchLoc = [tap locationInView:tap.view]; + const Point2f touchLoc2f(touchLoc.x,touchLoc.y); auto frameSizeScaled = sceneRenderer->getFramebufferSizeScaled(); if (globeView->pointOnSphereFromScreen(touchLoc2f, theTransform, frameSizeScaled, hit, true)) { - double curH = globeView->getHeightAboveGlobe(); - double newH = curH / _zoomTapFactor; + const double curH = globeView->getHeightAboveGlobe(); + const double newH = curH / _zoomTapFactor; if (_minZoom < newH && newH < _maxZoom) { - auto animate = new AnimateViewHeight(globeView,newH,_zoomAnimationDuration); + auto animate = std::make_shared(globeView,newH,_zoomAnimationDuration); animate->setTiltDelegate(_tiltDelegate); - globeView->setDelegate(GlobeViewAnimationDelegateRef(animate)); + globeView->setDelegate(std::move(animate)); } } } diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeDoubleTapDragDelegate.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeDoubleTapDragDelegate.mm index dd1bfe7884..688c0359c4 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeDoubleTapDragDelegate.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeDoubleTapDragDelegate.mm @@ -23,6 +23,7 @@ #import "gestures/GlobeDoubleTapDragDelegate.h" #import "GlobeView.h" #import "ViewWrapper.h" +#import "SceneRenderer.h" using namespace WhirlyKit; using namespace WhirlyGlobe; diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeTwoFingerTapDelegate.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeTwoFingerTapDelegate.mm index 36004e0b9f..aa0a232cb0 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeTwoFingerTapDelegate.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/gestures/GlobeTwoFingerTapDelegate.mm @@ -1,7 +1,6 @@ /* * GlobeTwoFingerTapDelegate.mm * - * * Created by Steve Gifford on 2/7/14. * Copyright 2011-2022 mousebird consulting * @@ -21,6 +20,7 @@ #import "gestures/GlobeTwoFingerTapDelegate.h" #import "GlobeAnimateHeight.h" #import "ViewWrapper.h" +#import "SceneRenderer.h" using namespace WhirlyKit; using namespace WhirlyGlobe; @@ -51,7 +51,7 @@ - (void)tapGesture:(id)sender UITapGestureRecognizer *tap = sender; UIView *wrapView = (UIView *)tap.view; SceneRenderer *sceneRenderer = wrapView.renderer; - auto frameSizeScaled = sceneRenderer->getFramebufferSizeScaled(); + const auto frameSizeScaled = sceneRenderer->getFramebufferSizeScaled(); // Just figure out where we tapped Point3d hit; diff --git a/ios/library/WhirlyGlobeLib/include/MTLView.h b/ios/library/WhirlyGlobeLib/include/MTLView.h index e4c7a5f7a9..77c96e5b89 100644 --- a/ios/library/WhirlyGlobeLib/include/MTLView.h +++ b/ios/library/WhirlyGlobeLib/include/MTLView.h @@ -1,5 +1,4 @@ -/* - * MTLView.h +/* MTLView.h * WhirlyGlobeLib * * Created by Steve Gifford on 5/20/19. @@ -15,26 +14,18 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ #import #import - #import "ViewWrapper.h" -#import "SceneRendererMTL.h" -/** OpenGL View is a - base class for implementing an open GL rendering view. - This is modeled off of the example. We subclass this for - our own purposes. +/** Base class for implementing a Metal rendering view. + This is modeled off of the example. We subclass this for our own purposes. */ @interface WhirlyKitMTLView : MTKView /// Default init call -- (id)initWithDevice:(id)mtlDevice; - -/// We're only expecting this to be set once -@property (nonatomic) WhirlyKit::SceneRenderer *renderer; +- (id _Nullable )initWithDevice:(_Nonnull id)mtlDevice; @end diff --git a/ios/library/WhirlyGlobeLib/include/ViewWrapper.h b/ios/library/WhirlyGlobeLib/include/ViewWrapper.h index 8b5a2845fc..5bf9f006cc 100644 --- a/ios/library/WhirlyGlobeLib/include/ViewWrapper.h +++ b/ios/library/WhirlyGlobeLib/include/ViewWrapper.h @@ -1,5 +1,4 @@ -/* - * ViewWrapper.h +/* ViewWrapper.h * WhirlyGlobeLib * * Created by Steve Gifford on 5/15/19. @@ -15,21 +14,28 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ #import -#import "SceneRenderer.h" -/** OpenGL View is a - base class for implementing an open GL rendering view. - This is modeled off of the example. We subclass this for - our own purposes. +namespace WhirlyKit +{ + class SceneRenderer; +} + +@protocol ViewWrapperDelegateProtocol +- (void)layoutDidRun; +@end + +/** Base class for implementing a Metal rendering view. + This is modeled off of the example. We subclass this for our own purposes. */ @protocol WhirlyKitViewWrapper /// Renderer we're using -@property (nonatomic) WhirlyKit::SceneRenderer *renderer; +@property (nonatomic) WhirlyKit::SceneRenderer * _Nullable renderer; + +@property (nonatomic) NSObject * __weak _Nullable wrapperDelegate; /// True if we've got a displayLink turned on to animate. - (BOOL)isAnimating; diff --git a/ios/library/WhirlyGlobeLib/src/MTLView.mm b/ios/library/WhirlyGlobeLib/src/MTLView.mm index d49efadc5b..a1eca62aac 100644 --- a/ios/library/WhirlyGlobeLib/src/MTLView.mm +++ b/ios/library/WhirlyGlobeLib/src/MTLView.mm @@ -1,5 +1,4 @@ -/* - * MTLView.mm +/* MTLView.mm * WhirlyGlobeLib * * Created by Steve Gifford on 5/20/19. @@ -15,10 +14,11 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ #import "MTLView.h" +#import "WhirlyKitLog.h" +#import "SceneRendererMTL.h" using namespace WhirlyKit; @@ -30,13 +30,21 @@ @implementation WhirlyKitMTLView bool animating; } +// defined in WhirlyKitViewWrapper +@synthesize renderer; +@synthesize wrapperDelegate; + - (id)initWithDevice:(id)mtlDevice { - self = [super initWithFrame:CGRectZero device:mtlDevice]; + if (!(self = [super initWithFrame:CGRectZero device:mtlDevice])) + { + return nil; + } self.colorPixelFormat = MTLPixelFormatBGRA8Unorm; self.depthStencilPixelFormat = MTLPixelFormatDepth32Float; - if (@available(iOS 13.0, *)) { + if (@available(iOS 13.0, *)) + { self.depthStencilAttachmentTextureUsage = MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget; } self.framebufferOnly = true; @@ -51,18 +59,18 @@ - (void)setContentScaleFactor:(CGFloat)contentScaleFactor { super.contentScaleFactor = contentScaleFactor; - if (_renderer) - _renderer->setScale(contentScaleFactor); + if (renderer) + renderer->setScale(contentScaleFactor); } -- (void)setRenderer:(WhirlyKit::SceneRenderer *)renderer +- (void)setRenderer:(WhirlyKit::SceneRenderer *)inRenderer { - SceneRendererMTL *renderMTL = dynamic_cast(renderer); + SceneRendererMTL *renderMTL = dynamic_cast(inRenderer); if (!renderMTL) return; - _renderer = renderer; - _renderer->setScale(self.contentScaleFactor); + self->renderer = inRenderer; + self->renderer->setScale(self.contentScaleFactor); renderMTL->setup(self.frame.size.width, self.frame.size.height,false); } @@ -71,12 +79,23 @@ - (void)layoutSubviews { [super layoutSubviews]; - SceneRendererMTL *renderMTL = dynamic_cast(_renderer); - if (!renderMTL) - return; - - renderMTL->resize((int)self.frame.size.width*self.contentScaleFactor, - (int)self.frame.size.height*self.contentScaleFactor); + if (auto renderMTL = dynamic_cast(renderer)) + { + const CGSize size = self.frame.size; + const auto width = (int)(size.width * self.contentScaleFactor); + const auto height = (int)(size.height * self.contentScaleFactor); + if (width > 0 && height > 0) + { + if (renderMTL->resize(width, height)) + { + [self.wrapperDelegate layoutDidRun]; + } + } + else + { + wkLogLevel(Debug, "Ignoring empty view resize"); + } + } } - (id)getDrawable @@ -88,7 +107,7 @@ - (void)draw { [super draw]; - SceneRendererMTL *renderMTL = dynamic_cast(_renderer); + SceneRendererMTL *renderMTL = dynamic_cast(renderer); if (!renderMTL) return; @@ -125,7 +144,7 @@ - (void) stopAnimation - (void) teardown { - _renderer = nil; + self->renderer = nil; } @end From 886ed7aa7f91562322376ab52c659d988a98e0fc Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Tue, 1 Feb 2022 13:29:37 -0800 Subject: [PATCH 4/4] Update Android to match --- common/WhirlyGlobeLib/src/ParticleSystemDrawableGLES.cpp | 6 ++++-- .../WhirlyGlobeLib/src/WideVectorDrawableBuilderGLES.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/common/WhirlyGlobeLib/src/ParticleSystemDrawableGLES.cpp b/common/WhirlyGlobeLib/src/ParticleSystemDrawableGLES.cpp index 912a7a9c70..13a8aa47fe 100644 --- a/common/WhirlyGlobeLib/src/ParticleSystemDrawableGLES.cpp +++ b/common/WhirlyGlobeLib/src/ParticleSystemDrawableGLES.cpp @@ -229,6 +229,8 @@ void ParticleSystemDrawableGLES::drawTeardownTextures(RendererFrameInfo *frameIn void ParticleSystemDrawableGLES::drawSetupUniforms(RendererFrameInfo *frameInfo,Scene *scene,ProgramGLES *prog) { + const Point2f frameSize = frameInfo->sceneRenderer->getFramebufferSize(); + // Model/View/Projection matrix prog->setUniform(mvpMatrixNameID, frameInfo->mvpMat); prog->setUniform(mvpInvMatrixNameID, frameInfo->mvpInvMat); @@ -236,10 +238,10 @@ void ParticleSystemDrawableGLES::drawSetupUniforms(RendererFrameInfo *frameInfo, prog->setUniform(mvNormalMatrixNameID, frameInfo->viewModelNormalMat); prog->setUniform(mvpNormalMatrixNameID, frameInfo->mvpNormalMat); prog->setUniform(u_pMatrixNameID, frameInfo->projMat); - prog->setUniform(u_ScaleNameID, Point2f(2.f/(float)frameInfo->sceneRenderer->framebufferWidth,2.f/(float)frameInfo->sceneRenderer->framebufferHeight)); + prog->setUniform(u_ScaleNameID, Point2f(2.f/frameSize.x(),2.f/frameSize.y())); // Size of a single pixel - Point2f pixDispSize(frameInfo->screenSizeInDisplayCoords.x()/frameInfo->sceneRenderer->framebufferWidth,frameInfo->screenSizeInDisplayCoords.y()/frameInfo->sceneRenderer->framebufferHeight); + const Point2f pixDispSize = frameInfo->screenSizeInDisplayCoords.cast().cwiseQuotient(frameSize); // If this is present, the drawable wants to do something based where the viewer is looking prog->setUniform(u_EyeVecNameID, frameInfo->fullEyeVec); diff --git a/common/WhirlyGlobeLib/src/WideVectorDrawableBuilderGLES.cpp b/common/WhirlyGlobeLib/src/WideVectorDrawableBuilderGLES.cpp index 8d8c16fc0c..1f7ef62fb6 100644 --- a/common/WhirlyGlobeLib/src/WideVectorDrawableBuilderGLES.cpp +++ b/common/WhirlyGlobeLib/src/WideVectorDrawableBuilderGLES.cpp @@ -35,11 +35,12 @@ void WideVectorTweakerGLES::tweakForFrame(Drawable *inDraw,RendererFrameInfo *fr return; } - const double frameSize = std::min(frameInfo->sceneRenderer->framebufferWidth, frameInfo->sceneRenderer->framebufferHeight); + const Point2f frameSize = frameInfo->sceneRenderer->getFramebufferSize(); + const double frameSpan = std::min(frameSize.x(), frameSize.y()); const double screenSize = std::min(frameInfo->screenSizeInDisplayCoords.x(), frameInfo->screenSizeInDisplayCoords.y()); const double screenWidth = frameInfo->screenSizeInDisplayCoords.x(); - const double pixDispScale = screenSize / frameSize; - const double texScale = frameSize / (screenWidth * texRepeat); + const double pixDispScale = screenSize / frameSpan; + const double texScale = frameSpan / (screenWidth * texRepeat); const float zoom = (opacityExp || colorExp || widthExp) ? getZoom(*inDraw,*frameInfo->scene,0.0f) : 0.0f; Vector4f c = colorExp ? colorExp->evaluateF(zoom,color) : color.asRGBAVecF();