From c346398f42eebf71f1add9db91c6799123e30f9a Mon Sep 17 00:00:00 2001 From: Steve Gifford Date: Tue, 30 Mar 2021 11:18:35 -0700 Subject: [PATCH 1/3] Label along line overlap working. --- common/WhirlyGlobeLib/src/LayoutManager.cpp | 26 +++++++++---------- .../AutoTester/testCases/AirwayTestCase.swift | 20 ++++++++++++++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/common/WhirlyGlobeLib/src/LayoutManager.cpp b/common/WhirlyGlobeLib/src/LayoutManager.cpp index 9aad1f0601..13925558d8 100644 --- a/common/WhirlyGlobeLib/src/LayoutManager.cpp +++ b/common/WhirlyGlobeLib/src/LayoutManager.cpp @@ -672,8 +672,9 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, // Center around the world point on the screen Point2f midRun; - if (!walk.nextPoint(layoutMbr.span().x()/2.0, &midRun, nullptr, false)) + if (!walk.nextPoint(resScale * layoutMbr.span().x()/2.0, &midRun, nullptr, false)) continue; + wkLogLevel(Debug, "midRun = (%f,%f)",midRun.x(),midRun.y()); Point2f worldScreenPt = midRun; Point3d worldPt(0.0,0.0,0.0); if (!textBuilder.screenToWorld(midRun, worldPt)) @@ -711,31 +712,30 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, // Translate the glyph into that position Affine2d transPlace(Translation2d((centerPt.x()-worldScreenPt.x())/2.0, - -(centerPt.y()-worldScreenPt.y())/2.0)); + (worldScreenPt.y()-centerPt.y())/2.0)); double ang = -1.0 * (atan2(norm.y(),norm.x()) - M_PI/2.0); Matrix2d screenRot = Eigen::Rotation2Dd(ang).matrix(); Matrix3d screenRotMat = Matrix3d::Identity(); for (unsigned ix=0;ix<2;ix++) for (unsigned iy=0;iy<2;iy++) screenRotMat(ix, iy) = screenRot(ix, iy); + Matrix3d overlapMat = transPlace.matrix() * screenRotMat * transOrigin.matrix(); Matrix3d scaleMat = Eigen::AlignedScaling3d(resScale,resScale,1.0); - Matrix3d overlapMat = transPlace.matrix() * screenRotMat * scaleMat * transOrigin.matrix(); -// Matrix3d overlapMat = transPlace.matrix() * transOrigin.matrix(); - layoutMats.push_back(transPlace.matrix() * screenRotMat * transOrigin.matrix()); -// layoutMats.push_back(transPlace.matrix() * transOrigin.matrix()); + Matrix3d testMat = screenRotMat * scaleMat * transOrigin.matrix(); + layoutMats.push_back(overlapMat); // Check for overlap Point2dVector objPts; objPts.reserve(4); for (unsigned int oi=0;oi<4;oi++) { - Point3d pt = overlapMat * Point3d(geom.coords[oi].x(),geom.coords[oi].y(),1.0); - Point2d objPt(pt.x()+worldScreenPt.x(),pt.y()+worldScreenPt.y()); + Point3d pt = testMat * Point3d(geom.coords[oi].x(),geom.coords[oi].y(),1.0); + Point2d objPt(pt.x()+centerPt.x(),pt.y()+centerPt.y()); objPts.push_back(objPt); } // if (!failed) { // wkLog(" Geometry %d",ig); // for (unsigned int ip=0;ip= MAXFLOAT) diff --git a/ios/apps/AutoTester/AutoTester/testCases/AirwayTestCase.swift b/ios/apps/AutoTester/AutoTester/testCases/AirwayTestCase.swift index 25fa603322..6a407a89ae 100644 --- a/ios/apps/AutoTester/AutoTester/testCases/AirwayTestCase.swift +++ b/ios/apps/AutoTester/AutoTester/testCases/AirwayTestCase.swift @@ -53,6 +53,7 @@ class AirwayTestCase: MaplyTestCase { let buildAirways = false let buildAirspaces = true let buildLineLabels = true + let buildCenterLabels = false func setupAirways(_ viewC: MaplyBaseViewController) { DispatchQueue.global(qos: .default).async { @@ -184,6 +185,7 @@ class AirwayTestCase: MaplyTestCase { // Put the airspace vectors together var airspaceVecs = [MaplyVectorObject]() var labels = [MaplyScreenLabel]() + var centerLabels = [MaplyScreenLabel]() for vec in vecObj.splitVectors() { var include = false if let highVal = vec.attributes?["US_HIGH"] as? Int { @@ -211,6 +213,18 @@ class AirwayTestCase: MaplyTestCase { labels.append(label) airspaceVecs.append(vec) } + + if buildCenterLabels { + // Add a label right in the middle, for debugging + let centerLabel = MaplyScreenLabel() + centerLabel.loc = vec.centroid() + centerLabel.text = name + centerLabel.layoutImportance = 2.0 + centerLabel.layoutPlacement = kMaplyLayoutCenter + if centerLabel.text != nil { + centerLabels.append(centerLabel) + } + } } } @@ -230,6 +244,12 @@ class AirwayTestCase: MaplyTestCase { ], mode: .any) } + if (!centerLabels.isEmpty) { + viewC.addScreenLabels(centerLabels, desc: [kMaplyFont: UIFont.boldSystemFont(ofSize: 48.0), + kMaplyTextColor: UIColor.red, + ], + mode: .any) + } } override func setUpWithGlobe(_ globeVC: WhirlyGlobeViewController) { From 3702065bc74c68c886444429beff1da11c872453 Mon Sep 17 00:00:00 2001 From: Steve Gifford Date: Tue, 30 Mar 2021 14:20:00 -0700 Subject: [PATCH 2/3] Release mode was causing a problem with screen object creation on iOS. --- .../include/LinearTextBuilder.h | 2 +- .../include/ScreenSpaceBuilder.h | 18 ++++++----- common/WhirlyGlobeLib/src/LayoutManager.cpp | 31 ++++++++++--------- common/WhirlyGlobeLib/src/MarkerManager.cpp | 4 +-- .../WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp | 25 +++++++-------- .../AutoTester/testCases/AirwayTestCase.swift | 2 +- .../src/control/MaplyBaseInteractionLayer.mm | 12 +++---- 7 files changed, 47 insertions(+), 47 deletions(-) diff --git a/common/WhirlyGlobeLib/include/LinearTextBuilder.h b/common/WhirlyGlobeLib/include/LinearTextBuilder.h index 3446174d79..396803cf46 100644 --- a/common/WhirlyGlobeLib/include/LinearTextBuilder.h +++ b/common/WhirlyGlobeLib/include/LinearTextBuilder.h @@ -42,7 +42,7 @@ class LinearWalker { /// Calculate the next point along the line given the distance /// Or return false if there wasn't anything left - bool nextPoint(double distance,Point2f *retPt,Point2f *norm,bool savePos=true); + bool nextPoint(double distance,Point2f *retPt=nullptr,Point2f *norm=nullptr,bool savePos=true); protected: VectorRing pts; diff --git a/common/WhirlyGlobeLib/include/ScreenSpaceBuilder.h b/common/WhirlyGlobeLib/include/ScreenSpaceBuilder.h index b36224a6b3..f4408cb18e 100644 --- a/common/WhirlyGlobeLib/include/ScreenSpaceBuilder.h +++ b/common/WhirlyGlobeLib/include/ScreenSpaceBuilder.h @@ -125,7 +125,7 @@ class ScreenSpaceBuilder /// Add a single screen space object void addScreenObject(const ScreenSpaceObject &screenObject, const Point3d &worldLoc, - const std::vector &geoms, + const std::vector *geoms, const std::vector *places = nullptr); /// Return the drawables constructed. Caller responsible for deletion. @@ -178,20 +178,22 @@ class ScreenSpaceBuilder class ScreenSpaceConvexGeometry { public: - ScreenSpaceConvexGeometry(); + EIGEN_MAKE_ALIGNED_OPERATOR_NEW; + + ScreenSpaceConvexGeometry() = default; /// Texture ID used for just this object std::vector texIDs; /// Program ID used to render this geometry - SimpleIdentity progID; + SimpleIdentity progID = EmptyIdentity; /// Color for the geometry - RGBAColor color; + RGBAColor color = RGBAColor::white(); /// Draw order - int64_t drawOrder; + int64_t drawOrder = BaseInfo::DrawOrderTiles; /// Draw priority - int drawPriority; + int drawPriority = -1; /// Render target - SimpleIdentity renderTargetID; + SimpleIdentity renderTargetID = EmptyIdentity; /// Vertex attributes applied to this piece of geometry SingleVertexAttributeSet vertexAttrs; @@ -247,7 +249,7 @@ class ScreenSpaceObject : public Identifiable void addGeometry(const ScreenSpaceConvexGeometry &geom); void addGeometry(const std::vector &geom); - std::vector getGeometry() const { return geometry; } + const std::vector *getGeometry() const { return &geometry; } // Get a program ID either from the drawable state or geometry SimpleIdentity getTypicalProgramID(); diff --git a/common/WhirlyGlobeLib/src/LayoutManager.cpp b/common/WhirlyGlobeLib/src/LayoutManager.cpp index 13925558d8..ca12b4f498 100644 --- a/common/WhirlyGlobeLib/src/LayoutManager.cpp +++ b/common/WhirlyGlobeLib/src/LayoutManager.cpp @@ -628,6 +628,10 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, // wkLog("----"); for (auto layoutObj : container.objs) { + layoutObj->newEnable = false; + layoutObj->obj.layoutModelPlaces.clear(); + layoutObj->obj.layoutPlaces.clear(); + // Layout along a shape if (!layoutObj->obj.layoutShape.empty()) { // Sometimes there are just a few instances @@ -646,7 +650,7 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, std::vector layoutModelInstances; auto runs = textBuilder.getScreenVecs(); -// unsigned int ri=0; + unsigned int ri=0; for (auto run: runs) { // wkLog("Run %d",ri++); @@ -674,7 +678,7 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, Point2f midRun; if (!walk.nextPoint(resScale * layoutMbr.span().x()/2.0, &midRun, nullptr, false)) continue; - wkLogLevel(Debug, "midRun = (%f,%f)",midRun.x(),midRun.y()); +// wkLogLevel(Info, "midRun = (%f,%f)",midRun.x(),midRun.y()); Point2f worldScreenPt = midRun; Point3d worldPt(0.0,0.0,0.0); if (!textBuilder.screenToWorld(midRun, worldPt)) @@ -740,7 +744,6 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, // } if (!overlapMan.checkObject(objPts)) { -// wkLog(" Failed"); failed = true; break; } @@ -749,7 +752,7 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, } if (!failed) { - layoutObj->obj.setRotation(textBuilder.getViewStateRotation()); +// layoutObj->obj.setRotation(textBuilder.getViewStateRotation()); layoutModelInstances.push_back(worldPt); layoutInstances.push_back(layoutMats); numInstances++; @@ -778,9 +781,6 @@ bool LayoutManager::runLayoutRules(PlatformThreadInfo *threadInfo, layoutObj->offset = Point2d(0.0,0.0); } else { isActive = false; - layoutObj->newEnable = false; - layoutObj->obj.layoutPlaces.clear(); - layoutObj->obj.layoutModelPlaces.clear(); } if (layoutObj->currentEnable != isActive) { @@ -1038,24 +1038,25 @@ void LayoutManager::updateLayout(PlatformThreadInfo *threadInfo,const ViewStateR //animObj.setDrawOrder(?) for (auto &geom : animObj.geometry) geom.progID = params.motionShaderID; - ssBuild.addScreenObject(animObj,animObj.worldLoc,animObj.geometry); + ssBuild.addScreenObject(animObj,animObj.worldLoc,&animObj.geometry); // And hold off on adding it // todo: slicing, is this ok? ScreenSpaceObject shortObj = layoutObj->obj; //shortObj.setDrawOrder(?) shortObj.setEnableTime(curTime+params.markerAnimationTime, 0.0); - ssBuild.addScreenObject(shortObj,shortObj.worldLoc,shortObj.geometry); + ssBuild.addScreenObject(shortObj,shortObj.worldLoc,&shortObj.geometry); } else { // It's boring, just add it if (layoutObj->newEnable) { // It's a single point placement if (layoutObj->obj.layoutShape.empty()) - ssBuild.addScreenObject(layoutObj->obj,layoutObj->obj.worldLoc,layoutObj->obj.geometry); + ssBuild.addScreenObject(layoutObj->obj,layoutObj->obj.worldLoc,&layoutObj->obj.geometry); else { // One or more placements along a path - for (unsigned int ii=0;iiobj.layoutPlaces.size();ii++) - ssBuild.addScreenObject(layoutObj->obj, layoutObj->obj.layoutModelPlaces[ii], layoutObj->obj.geometry, &layoutObj->obj.layoutPlaces[ii]); + for (unsigned int ii=0;iiobj.layoutPlaces.size();ii++) { + ssBuild.addScreenObject(layoutObj->obj, layoutObj->obj.layoutModelPlaces[ii], &layoutObj->obj.geometry, &layoutObj->obj.layoutPlaces[ii]); + } } } } @@ -1092,16 +1093,16 @@ void LayoutManager::updateLayout(PlatformThreadInfo *threadInfo,const ViewStateR //animObj.setDrawOrder(?) for (auto &geom : animObj.geometry) geom.progID = params.motionShaderID; - ssBuild.addScreenObject(animObj, animObj.worldLoc, animObj.geometry); + ssBuild.addScreenObject(animObj, animObj.worldLoc, &animObj.geometry); // Hold off on adding the new one ScreenSpaceObject shortObj = cluster.layoutObj; //shortObj.setDrawOrder(?) shortObj.setEnableTime(curTime+params.markerAnimationTime, 0.0); - ssBuild.addScreenObject(shortObj, shortObj.worldLoc, shortObj.geometry); + ssBuild.addScreenObject(shortObj, shortObj.worldLoc, &shortObj.geometry); } else - ssBuild.addScreenObject(cluster.layoutObj, cluster.layoutObj.worldLoc, cluster.layoutObj.geometry); + ssBuild.addScreenObject(cluster.layoutObj, cluster.layoutObj.worldLoc, &cluster.layoutObj.geometry); } ssBuild.flushChanges(changes, drawIDs); diff --git a/common/WhirlyGlobeLib/src/MarkerManager.cpp b/common/WhirlyGlobeLib/src/MarkerManager.cpp index 1fa51567a5..b93423d8cf 100644 --- a/common/WhirlyGlobeLib/src/MarkerManager.cpp +++ b/common/WhirlyGlobeLib/src/MarkerManager.cpp @@ -252,8 +252,8 @@ SimpleIdentity MarkerManager::addMarkers(const std::vector &markers,co // Handle the mask rendering if it's there if (marker->maskID != EmptyIdentity && marker->maskRenderTargetID != EmptyIdentity) { // Make a copy of the geometry, but target it to the mask render target - std::vector geom = shape->getGeometry(); - for (auto entry: geom) { + const std::vector *geom = shape->getGeometry(); + for (auto entry: *geom) { entry.vertexAttrs.insert(SingleVertexAttribute(a_maskNameID, renderer->getSlotForNameID(a_maskNameID), (int)marker->maskID)); entry.renderTargetID = marker->maskRenderTargetID; entry.progID = maskProgID; diff --git a/common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp b/common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp index bc781d8627..3ffe3d7fab 100644 --- a/common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp +++ b/common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp @@ -20,6 +20,7 @@ #import "ScreenSpaceBuilder.h" #import "ScreenSpaceDrawableBuilder.h" +#import "WhirlyKitLog.h" namespace WhirlyKit { @@ -342,7 +343,7 @@ void ScreenSpaceBuilder::addScreenObjects(std::vector &screen { ScreenSpaceObject &ssObj = screenObjects[ii]; - addScreenObject(ssObj,ssObj.worldLoc,ssObj.geometry); + addScreenObject(ssObj,ssObj.worldLoc,&ssObj.geometry); } } @@ -355,22 +356,23 @@ void ScreenSpaceBuilder::addScreenObjects(std::vector &scre { ScreenSpaceObject *ssObj = screenObjects[ii]; - addScreenObject(*ssObj, ssObj->worldLoc, ssObj->geometry); + addScreenObject(*ssObj, ssObj->worldLoc, &ssObj->geometry); } } void ScreenSpaceBuilder::addScreenObject(const ScreenSpaceObject &ssObj, const Point3d &worldLoc, - const std::vector &geoms, + const std::vector *geoms, const std::vector *places) { - for (unsigned int ii=0;iisize();ii++) { - ScreenSpaceConvexGeometry geom = geoms[ii]; + Eigen::Matrix3d placeMat = places->at(ii); + ScreenSpaceConvexGeometry geom = geoms->at(ii); // Apply a matrix to the geometry for a given version of the placement if (places) { for (auto &pt: geom.coords) { - auto pt2d = (*places)[ii] * Point3d(pt.x(),pt.y(),1.0); + Point3d pt2d = placeMat * Point3d(pt.x(),pt.y(),1.0); pt = Point2d(pt2d.x(),pt2d.y()); } } @@ -411,8 +413,9 @@ void ScreenSpaceBuilder::addScreenObject(const ScreenSpaceObject &ssObj, { Point3f dir3f(dir.x(),dir.y(),dir.z()); drawWrap->addVertex(coordAdapter,scale,startLoc, &dir3f, ssObj.rotation, Point2d(coord.x(),coord.y()), texCoord, &geom.color, &geom.vertexAttrs); - } else + } else { drawWrap->addVertex(coordAdapter,scale,startLoc, NULL, ssObj.rotation, Point2d(coord.x(),coord.y()), texCoord, &geom.color, &geom.vertexAttrs); + } } for (unsigned int jj=0;jjaddTri(0+baseVert, jj+1+baseVert, jj+2+baseVert); @@ -446,13 +449,7 @@ void ScreenSpaceBuilder::flushChanges(ChangeSet &changes,SimpleIDSet &drawIDs) } draws.clear(); } - -ScreenSpaceConvexGeometry::ScreenSpaceConvexGeometry() - : progID(EmptyIdentity), color(255,255,255,255), drawPriority(-1), renderTargetID(EmptyIdentity) - , drawOrder(BaseInfo::DrawOrderTiles) -{ -} - + ScreenSpaceObject::ScreenSpaceObject() : enable(true), startEnable(0.0), endEnable(0.0), worldLoc(0,0,0), endWorldLoc(0,0,0), startTime(0.0), endTime(0.0), offset(0,0), rotation(0), keepUpright(false), orderBy(-1) { diff --git a/ios/apps/AutoTester/AutoTester/testCases/AirwayTestCase.swift b/ios/apps/AutoTester/AutoTester/testCases/AirwayTestCase.swift index 6a407a89ae..2de380f744 100644 --- a/ios/apps/AutoTester/AutoTester/testCases/AirwayTestCase.swift +++ b/ios/apps/AutoTester/AutoTester/testCases/AirwayTestCase.swift @@ -240,7 +240,7 @@ class AirwayTestCase: MaplyTestCase { kMaplyTextLayoutSpacing: 100.0, // 100 pixels between // kMaplyTextLayoutSpacing: 0.0, // 100 pixels between // kMaplyTextLayoutRepeat: 4, // As many as fit - kMaplyTextLayoutDebug: true +// kMaplyTextLayoutDebug: true ], mode: .any) } diff --git a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseInteractionLayer.mm b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseInteractionLayer.mm index d85f03359d..11a26e4ed4 100644 --- a/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseInteractionLayer.mm +++ b/ios/library/WhirlyGlobe-MaplyComponent/src/control/MaplyBaseInteractionLayer.mm @@ -1004,7 +1004,7 @@ - (void)setupLayoutObject:(LayoutObject &)retObj asBestOfLayoutObjects:(const st if (topObject == nullptr || sorter(obj, topObject)) topObject = obj; - if (topObject == nullptr || topObject->obj.getGeometry().empty()) + if (topObject == nullptr || topObject->obj.getGeometry()->empty()) return; retObj.setWorldLoc(topObject->obj.getWorldLoc()); @@ -1012,15 +1012,15 @@ - (void)setupLayoutObject:(LayoutObject &)retObj asBestOfLayoutObjects:(const st if (topObject->obj.hasRotation()) retObj.setRotation(topObject->obj.getRotation()); - std::vector allGeometry = topObject->obj.getGeometry(); + const std::vector *allGeometry = topObject->obj.getGeometry(); - if (allGeometry.empty()) + if (allGeometry->empty()) return; - retObj.layoutPts = allGeometry.back().coords; - retObj.selectPts = allGeometry.back().coords; + retObj.layoutPts = allGeometry->back().coords; + retObj.selectPts = allGeometry->back().coords; - for (auto geometry : allGeometry) + for (auto geometry : *allGeometry) retObj.addGeometry(geometry); } From 2bca613f0fd7a14246a8cda2a8d15bd94eb9a61a Mon Sep 17 00:00:00 2001 From: Steve Gifford Date: Tue, 30 Mar 2021 14:26:53 -0700 Subject: [PATCH 3/3] Fixed screen space crash. --- common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp b/common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp index 3ffe3d7fab..2b00a64e6f 100644 --- a/common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp +++ b/common/WhirlyGlobeLib/src/ScreenSpaceBuilder.cpp @@ -367,10 +367,10 @@ void ScreenSpaceBuilder::addScreenObject(const ScreenSpaceObject &ssObj, { for (unsigned int ii=0;iisize();ii++) { - Eigen::Matrix3d placeMat = places->at(ii); ScreenSpaceConvexGeometry geom = geoms->at(ii); // Apply a matrix to the geometry for a given version of the placement if (places) { + Eigen::Matrix3d placeMat = places->at(ii); for (auto &pt: geom.coords) { Point3d pt2d = placeMat * Point3d(pt.x(),pt.y(),1.0); pt = Point2d(pt2d.x(),pt2d.y());