Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: rvsrvs/WhirlyGlobe
base: 347f2eb897
...
head fork: rvsrvs/WhirlyGlobe
compare: bba4285c5a
Checking mergeability… Don't worry, you can still create the pull request.
  • 5 commits
  • 25 files changed
  • 0 commit comments
  • 2 contributors
Commits on Dec 15, 2012
@mousebird mousebird Circles and lines now working correctly in Maply. fd79aef
@mousebird mousebird Cleaned up animation for Maply gestures. Locational methods now worki…
…ng in Maply Component.
479f053
@mousebird mousebird Fixed a compile problem. Fixed a retina display picking bug. f916fc2
Commits on Dec 16, 2012
Juan J. Collas Merge branch 'develop' of git://github.com/mousebird/WhirlyGlobe into…
… develop
f62b36f
Juan J. Collas Add support for loading an MBTiles file from the filesystem
Fix bug with 'northUp' always being true
Add setHeading:position: to WhirlyGlobeViewController
Add code to set the drawPriority of the tileLoader so multiple layers don't z-fight.
bba4285
Showing with 348 additions and 63 deletions.
  1. +3 −0  WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/MaplyBaseViewController.h
  2. +18 −3 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/MaplyViewController.h
  3. +3 −0  WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/WhirlyGlobeViewController.h
  4. +1 −1  WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/private/MaplyInteractionLayer_private.h
  5. +2 −2 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/private/MaplyQuadEarthWithMBTiles_private.h
  6. +11 −5 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/private/MaplyViewController_private.h
  7. +11 −3 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/MaplyBaseInteractionLayer.mm
  8. +12 −1 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/MaplyBaseViewController.mm
  9. +6 −4 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/MaplyQuadEarthWithMBTiles.mm
  10. +128 −10 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/MaplyViewController.mm
  11. +54 −1 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/WhirlyGlobeViewController.mm
  12. +2 −2 WhirlyGlobeSrc/WhirlyGlobeLib/WhirlyGlobeLib.xcodeproj/project.pbxproj
  13. +3 −0  WhirlyGlobeSrc/WhirlyGlobeLib/include/LayerThread.h
  14. +2 −1  WhirlyGlobeSrc/WhirlyGlobeLib/include/MaplyAnimateTranslateMomentum.h
  15. +6 −0 WhirlyGlobeSrc/WhirlyGlobeLib/include/MaplyPanDelegate.h
  16. +6 −0 WhirlyGlobeSrc/WhirlyGlobeLib/include/MaplyPinchDelegate.h
  17. +7 −1 WhirlyGlobeSrc/WhirlyGlobeLib/include/MaplyView.h
  18. +6 −0 WhirlyGlobeSrc/WhirlyGlobeLib/src/LayerThread.mm
  19. +7 −3 WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyAnimateTranslateMomentum.mm
  20. +38 −15 WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyPanDelegate.mm
  21. +7 −1 WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyPinchDelegate.mm
  22. +1 −1  WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyTapDelegate.mm
  23. +12 −2 WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyView.mm
  24. +1 −6 WhirlyGlobeSrc/WhirlyGlobeLib/src/QuadDisplayLayer.mm
  25. +1 −1  WhirlyGlobeSrc/WhirlyGlobeLib/src/ShapeLayer.mm
View
3  WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/MaplyBaseViewController.h
@@ -46,6 +46,9 @@
/// Add a quad tree paged earth layer with MapBox Tiles on top
- (MaplyViewControllerLayer *)addQuadEarthLayerWithMBTiles:(NSString *)name;
+/// Add a quad tree paged earth layer with MapBox Tiles on top from a specified path
+- (MaplyViewControllerLayer *)addQuadEarthLayerWithMBTilesPath:(NSString *)path;
+
/// Add a quad tree paged earth layer with
- (MaplyViewControllerLayer *)addQuadEarthLayerWithRemoteSource:(NSString *)baseURL imageExt:(NSString *)ext cache:(NSString *)cachdDir minZoom:(int)minZoom maxZoom:(int)maxZoom;
View
21 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/MaplyViewController.h
@@ -70,13 +70,28 @@
/// The radius of the earth is 1.0. Height above terrain is relative to that.
@property (nonatomic,assign) float height;
+/// Return the view extents. This is the box the view point is allowed to be within.
+- (void)getViewExtentsLL:(MaplyCoordinate *)ll ur:(MaplyCoordinate *)ur;
+
+/// Set the view extents. This is the box the view point is allowed to be within.
+- (void)setViewExtentsLL:(MaplyCoordinate)ll ur:(MaplyCoordinate)ur;
+
/// Animate to the given position over the given amount of time
-- (void)animateToPosition:(WGCoordinate)newPos time:(NSTimeInterval)howLong;
+- (void)animateToPosition:(MaplyCoordinate)newPos time:(NSTimeInterval)howLong;
/// Set the view to the given position immediately
-- (void)setPosition:(WGCoordinate)newPos;
+- (void)setPosition:(MaplyCoordinate)newPos;
/// Set position and height at the same time
-- (void)setPosition:(WGCoordinate)newPos height:(float)height;
+- (void)setPosition:(MaplyCoordinate)newPos height:(float)height;
+
+/// Get the current position and height
+- (void)getPosition:(WGCoordinate *)pos height:(float *)height;
+
+/// Return the min and max heights above the globe for zooming
+- (void)getZoomLimitsMin:(float *)minHeight max:(float *)maxHeight;
+
+/// Set the min and max heights above the globe for zooming
+- (void)setZoomLimitsMin:(float)minHeight max:(float)maxHeight;
@end
View
3  WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/WhirlyGlobeViewController.h
@@ -104,6 +104,9 @@
/// Get the current position and height
- (void)getPosition:(WGCoordinate *)pos height:(float *)height;
+/// Set heading about current position
+- (void) setHeading:(CGFloat) rotationHeading position:(WGCoordinate)newPos;
+
/// Add a spherical earth layer with the given set of base images
- (WGViewControllerLayer *)addSphericalEarthLayerWithImageSet:(NSString *)name;
View
2  WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/private/MaplyInteractionLayer_private.h
@@ -32,7 +32,7 @@
*/
@interface MaplyInteractionLayer : MaplyBaseInteractionLayer
{
- // The view controller, for various callbacks
+ /// The view controller, for various callbacks
NSObject<MaplyInteractionLayerDelegate> * __weak viewController;
}
View
4 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/private/MaplyQuadEarthWithMBTiles_private.h
@@ -22,9 +22,9 @@
@interface MaplyQuadEarthWithMBTiles : MaplyViewControllerLayer
-/// Set up a spherical earth layer with an MBTiles archive.
+/// Set up a spherical earth layer with an MBTiles archive from a specified path.
/// Returns nil on failure.
-- (id)initWithWithLayerThread:(WhirlyKitLayerThread *)layerThread scene:(WhirlyKit::Scene *)scene renderer:(WhirlyKitSceneRendererES *)renderer mbTiles:(NSString *)mbTilesName handleEdges:(bool)edges;
+- (id)initWithWithLayerThread:(WhirlyKitLayerThread *)layerThread scene:(WhirlyKit::Scene *)scene renderer:(WhirlyKitSceneRendererES *)renderer mbTilesPath:(NSString *)mbTilesPath handleEdges:(bool)edges;
/// Clean up any and all resources
- (void)cleanupLayers:(WhirlyKitLayerThread *)layerThread scene:(WhirlyKit::Scene *)scene;
View
16 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/private/MaplyViewController_private.h
@@ -24,21 +24,27 @@
@interface MaplyViewController()
{
- // Custom map scene
+ /// Custom map scene
Maply::MapScene *mapScene;
- // Maply view
+ /// Maply view
MaplyView *mapView;
- // Coordinate system and display adapter
+ /// Coordinate system and display adapter
WhirlyKit::SphericalMercatorDisplayAdapter *coordAdapter;
- // Our own interaction layer for adding and removing things
+ /// Our own interaction layer for adding and removing things
MaplyInteractionLayer *mapInteractLayer;
- // Gesture recognizers
+ /// Gesture recognizers
MaplyTapDelegate *tapDelegate;
MaplyPanDelegate *panDelegate;
MaplyPinchDelegate *pinchDelegate;
+
+ /// Bounding box for the viewer
+ MaplyCoordinate boundLL,boundUR;
+
+ /// Current view animation (kept around so it's not released)
+ NSObject *curAnimation;
}
@end
View
14 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/MaplyBaseInteractionLayer.mm
@@ -39,6 +39,7 @@ void SampleGreatCircle(MaplyCoordinate startPt,MaplyCoordinate endPt,float heigh
Point3f p1 = coordAdapter->localToDisplay(coordAdapter->getCoordSystem()->geographicToLocal(GeoCoord(endPt.x,endPt.y)));
// Note: Dumb approach. Switch to an adaptive sampling
+ bool isFlat = coordAdapter->isFlat();
int numSamples = 300;
for (unsigned int ii=0;ii<=numSamples;ii++)
{
@@ -46,14 +47,18 @@ void SampleGreatCircle(MaplyCoordinate startPt,MaplyCoordinate endPt,float heigh
float t = (ii/(float)numSamples);
Point3f pt = (p1-p0)*t + p0;
// This puts us on the surface of the sphere
- pt.normalize();
+ if (!isFlat)
+ pt.normalize();
// Parabolic curve
float b = 4*height;
float a = -b;
float thisHeight = a*(t*t) + b*t;
- pt *= 1.0+thisHeight;
+ if (isFlat)
+ pt.z() = thisHeight;
+ else
+ pt *= 1.0+thisHeight;
pts.push_back(pt);
}
}
@@ -484,7 +489,10 @@ - (void)addShapesLayerThread:(NSArray *)argArray
{
MaplyCoordinate3d &coord = coords[ii];
Point3f pt = coordAdapter->localToDisplay(coordAdapter->getCoordSystem()->geographicToLocal(GeoCoord(coord.x,coord.y)));
- pt *= (1.0+coord.z);
+ if (coordAdapter->isFlat())
+ pt.z() = coord.z;
+ else
+ pt *= (1.0+coord.z);
newLin.pts.push_back(pt);
}
newLin.lineWidth = lin.lineWidth;
View
13 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/MaplyBaseViewController.mm
@@ -267,7 +267,18 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
- (MaplyViewControllerLayer *)addQuadEarthLayerWithMBTiles:(NSString *)name
{
- MaplyViewControllerLayer *newLayer = (MaplyViewControllerLayer *)[[MaplyQuadEarthWithMBTiles alloc] initWithWithLayerThread:layerThread scene:scene renderer:sceneRenderer mbTiles:name handleEdges:(sceneRenderer.zBufferMode == zBufferOn)];
+ NSString *infoPath = [[NSBundle mainBundle] pathForResource:name ofType:@"mbtiles"];
+ if (!infoPath)
+ {
+ return nil;
+ }
+
+ return [self addQuadEarthLayerWithMBTilesPath:infoPath];
+}
+
+- (MaplyViewControllerLayer *)addQuadEarthLayerWithMBTilesPath:(NSString *)path
+{
+ MaplyViewControllerLayer *newLayer = (MaplyViewControllerLayer *)[[MaplyQuadEarthWithMBTiles alloc] initWithWithLayerThread:layerThread scene:scene renderer:sceneRenderer mbTilesPath:path handleEdges:(sceneRenderer.zBufferMode == zBufferOn)];
if (!newLayer)
return nil;
View
10 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/MaplyQuadEarthWithMBTiles.mm
@@ -19,6 +19,7 @@
*/
#import "MaplyQuadEarthWithMBTiles_private.h"
+#import "LayerThread.h"
@implementation MaplyQuadEarthWithMBTiles
{
@@ -27,23 +28,24 @@ @implementation MaplyQuadEarthWithMBTiles
WhirlyKitMBTileQuadSource *dataSource;
}
-- (id)initWithWithLayerThread:(WhirlyKitLayerThread *)layerThread scene:(WhirlyKit::Scene *)scene renderer:(WhirlyKitSceneRendererES *)renderer mbTiles:(NSString *)mbName handleEdges:(bool)edges
+- (id)initWithWithLayerThread:(WhirlyKitLayerThread *)layerThread scene:(WhirlyKit::Scene *)scene renderer:(WhirlyKitSceneRendererES *)renderer mbTilesPath:(NSString *)mbPathName handleEdges:(bool)edges
{
self = [super init];
if (self)
{
- NSString *infoPath = [[NSBundle mainBundle] pathForResource:mbName ofType:@"mbtiles"];
- if (!infoPath)
+ if ([[NSFileManager defaultManager] fileExistsAtPath:mbPathName] == NO)
{
self = nil;
return nil;
}
- dataSource = [[WhirlyKitMBTileQuadSource alloc] initWithPath:infoPath];
+ dataSource = [[WhirlyKitMBTileQuadSource alloc] initWithPath:mbPathName];
tileLoader = [[WhirlyKitQuadTileLoader alloc] initWithDataSource:dataSource];
tileLoader.coverPoles = true;
quadLayer = [[WhirlyKitQuadDisplayLayer alloc] initWithDataSource:dataSource loader:tileLoader renderer:renderer];
tileLoader.ignoreEdgeMatching = !edges;
[layerThread addLayer:quadLayer];
+
+ tileLoader.drawPriority = [layerThread activeLayers] - 1;
}
return self;
View
138 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/MaplyViewController.mm
@@ -63,7 +63,7 @@ - (void)dealloc
- (WhirlyKitView *) loadSetup_view
{
- coordAdapter = new SphericalMercatorDisplayAdapter(0.0, GeoCoord(-180.0,-90.0), GeoCoord(180.0,90.0));
+ coordAdapter = new SphericalMercatorDisplayAdapter(0.0, GeoCoord::CoordFromDegrees(-180.0,-90.0), GeoCoord::CoordFromDegrees(180.0,90.0));
mapView = [[MaplyView alloc] initWithCoordAdapater:coordAdapter];
mapView.continuousZoom = true;
@@ -92,7 +92,12 @@ - (void) loadSetup
// Wire up the gesture recognizers
tapDelegate = [MaplyTapDelegate tapDelegateForView:glView mapView:mapView];
panDelegate = [MaplyPanDelegate panDelegateForView:glView mapView:mapView];
+ boundLL = MaplyCoordinateMakeWithDegrees(-180.0,-90.0);
+ boundUR = MaplyCoordinateMakeWithDegrees(180.0,90.0);
+ [self setViewExtentsLL:boundLL ur:boundUR];
pinchDelegate = [MaplyPinchDelegate pinchDelegateForView:glView mapView:mapView];
+ pinchDelegate.minZoom = [mapView minHeightAboveSurface];
+ pinchDelegate.maxZoom = [mapView maxHeightAboveSurface];
}
- (void)viewWillAppear:(BOOL)animated
@@ -120,27 +125,140 @@ - (void)registerForEvents
#pragma mark - Interaction
+/// Return the view extents. This is the box the view point is allowed to be within.
+- (void)getViewExtentsLL:(MaplyCoordinate *)ll ur:(MaplyCoordinate *)ur
+{
+ *ll = boundLL;
+ *ur = boundUR;
+}
+
+/// Set the view extents. This is the box the view point is allowed to be within.
+- (void)setViewExtentsLL:(MaplyCoordinate)ll ur:(MaplyCoordinate)ur
+{
+ CoordSystemDisplayAdapter *adapter = mapView.coordAdapter;
+ CoordSystem *coordSys = adapter->getCoordSystem();
+ boundLL = ll; boundUR = ur;
+
+ // Convert the bounds to a rectangle in local coordinates
+ Point3f bounds3d[4];
+ Point2f bounds[4];
+ bounds3d[0] = adapter->localToDisplay(coordSys->geographicToLocal(GeoCoord(ll.x,ll.y)));
+ bounds3d[1] = adapter->localToDisplay(coordSys->geographicToLocal(GeoCoord(ur.x,ll.y)));
+ bounds3d[2] = adapter->localToDisplay(coordSys->geographicToLocal(GeoCoord(ur.x,ur.y)));
+ bounds3d[3] = adapter->localToDisplay(coordSys->geographicToLocal(GeoCoord(ll.x,ur.y)));
+ for (unsigned int ii=0;ii<4;ii++)
+ bounds[ii] = Point2f(bounds3d[ii].x(),bounds3d[ii].y());
+ [panDelegate setBounds:bounds];
+}
+
// Internal animation handler
-- (void)animateToPoint:(GeoCoord)whereGeo time:(NSTimeInterval)howLong
+- (void)animateToPoint:(Point3f)newLoc time:(NSTimeInterval)howLong
{
- // note: fill this in
+ [mapView cancelAnimation];
+
+ MaplyAnimateViewTranslation *animTrans = [[MaplyAnimateViewTranslation alloc] initWithView:mapView translate:newLoc howLong:howLong];
+ curAnimation = animTrans;
+ mapView.delegate = animTrans;
}
// External facing version of rotateToPoint
- (void)animateToPosition:(MaplyCoordinate)newPos time:(NSTimeInterval)howLong
{
- // Note: fill this in
+ // Snap to the bounds
+ if (newPos.x > boundUR.x) newPos.x = boundUR.x;
+ if (newPos.y > boundUR.y) newPos.y = boundUR.y;
+ if (newPos.x < boundLL.x) newPos.x = boundLL.x;
+ if (newPos.y < boundLL.y) newPos.y = boundLL.y;
+
+ Point3f loc = mapView.coordAdapter->localToDisplay(mapView.coordAdapter->getCoordSystem()->geographicToLocal(GeoCoord(newPos.x,newPos.y)));
+ loc.z() = mapView.loc.z();
+ [self animateToPoint:loc time:howLong];
+}
+
+// This version takes a height as well
+- (void)animateToPosition:(MaplyCoordinate)newPos height:(float)newHeight time:(NSTimeInterval)howLong
+{
+ if (pinchDelegate)
+ {
+ if (newHeight < pinchDelegate.minZoom)
+ newHeight = pinchDelegate.minZoom;
+ if (newHeight > pinchDelegate.maxZoom)
+ newHeight = pinchDelegate.maxZoom;
+ }
+
+ // Snap to the bounds
+ if (newPos.x > boundUR.x) newPos.x = boundUR.x;
+ if (newPos.y > boundUR.y) newPos.y = boundUR.y;
+ if (newPos.x < boundLL.x) newPos.x = boundLL.x;
+ if (newPos.y < boundLL.y) newPos.y = boundLL.y;
+
+ Point3f loc = mapView.coordAdapter->localToDisplay(mapView.coordAdapter->getCoordSystem()->geographicToLocal(GeoCoord(newPos.x,newPos.y)));
+ loc.z() = newHeight;
+
+ [self animateToPoint:loc time:howLong];
}
// External facing set position
- (void)setPosition:(MaplyCoordinate)newPos
{
- // Note: fill this in
+ Point3f loc = mapView.loc;
+ [self setPosition:newPos height:loc.z()];
}
- (void)setPosition:(MaplyCoordinate)newPos height:(float)height
{
- // Note: fill this in
+ [mapView cancelAnimation];
+
+ if (pinchDelegate)
+ {
+ if (height < pinchDelegate.minZoom)
+ height = pinchDelegate.minZoom;
+ if (height > pinchDelegate.maxZoom)
+ height = pinchDelegate.maxZoom;
+ }
+
+ // Snap to the bounds
+ if (newPos.x > boundUR.x) newPos.x = boundUR.x;
+ if (newPos.y > boundUR.y) newPos.y = boundUR.y;
+ if (newPos.x < boundLL.x) newPos.x = boundLL.x;
+ if (newPos.y < boundLL.y) newPos.y = boundLL.y;
+
+ Point3f loc = mapView.coordAdapter->localToDisplay(mapView.coordAdapter->getCoordSystem()->geographicToLocal(GeoCoord(newPos.x,newPos.y)));
+ loc.z() = height;
+ mapView.loc = loc;
+}
+
+- (void)getPosition:(WGCoordinate *)pos height:(float *)height
+{
+ Point3f loc = mapView.loc;
+ GeoCoord geoCoord = mapView.coordAdapter->getCoordSystem()->localToGeographic(loc);
+ pos->x = geoCoord.x(); pos->y = geoCoord.y();
+ *height = loc.z();
+}
+
+/// Return the min and max heights above the globe for zooming
+- (void)getZoomLimitsMin:(float *)minHeight max:(float *)maxHeight
+{
+ if (pinchDelegate)
+ {
+ *minHeight = pinchDelegate.minZoom;
+ *minHeight = pinchDelegate.maxZoom;
+ }
+}
+
+/// Set the min and max heights above the globe for zooming
+- (void)setZoomLimitsMin:(float)minHeight max:(float)maxHeight
+{
+ if (pinchDelegate)
+ {
+ pinchDelegate.minZoom = minHeight;
+ pinchDelegate.maxZoom = maxHeight;
+ Point3f loc = mapView.loc;
+ if (mapView.heightAboveSurface < minHeight)
+ mapView.loc = Point3f(loc.x(),loc.y(),minHeight);
+ if (mapView.heightAboveSurface > maxHeight)
+ mapView.loc = Point3f(loc.x(),loc.y(),maxHeight);
+ }
}
// Called back on the main thread after the interaction thread does the selection
@@ -152,15 +270,15 @@ - (void)handleSelection:(MaplyTapMessage *)msg didSelect:(NSObject *)selectedObj
if (delegate && [delegate respondsToSelector:@selector(maplyViewController:didSelect:)])
[delegate maplyViewController:self didSelect:selectedObj];
} else {
+ MaplyCoordinate coord;
+ coord.x = msg.whereGeo.lon();
+ coord.y = msg.whereGeo.lat();
// The user didn't select anything, let the delegate know.
if (delegate && [delegate respondsToSelector:@selector(maplyViewController:didTapAt:)])
{
- MaplyCoordinate coord;
- coord.x = msg.whereGeo.lon();
- coord.y = msg.whereGeo.lat();
[delegate maplyViewController:self didTapAt:coord];
}
- [self animateToPoint:msg.whereGeo time:1.0];
+ [self animateToPosition:coord time:1.0];
}
}
View
55 WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/src/WhirlyGlobeViewController.mm
@@ -21,6 +21,7 @@
#import <WhirlyGlobe.h>
#import "WhirlyGlobeViewController.h"
#import "WhirlyGlobeViewController_private.h"
+#import "GlobeMath.h"
using namespace Eigen;
using namespace WhirlyKit;
@@ -262,7 +263,7 @@ - (void)rotateToPoint:(GeoCoord)whereGeo time:(NSTimeInterval)howLong
// Construct a quaternion to rotate from where we are to where
// the user tapped
- Eigen::Quaternionf newRotQuat = [globeView makeRotationToGeoCoord:whereGeo keepNorthUp:YES];
+ Eigen::Quaternionf newRotQuat = [globeView makeRotationToGeoCoord:whereGeo keepNorthUp:[self keepNorthUp]];
// Rotate to the given position over time
animateRotation = [[AnimateViewRotation alloc] initWithView:globeView rot:newRotQuat howLong:howLong];
@@ -338,6 +339,58 @@ - (void)getPosition:(WGCoordinate *)pos height:(float *)height
pos->x = geoCoord.lon(); pos->y = geoCoord.lat();
}
+// Set heading about current position
+- (void) setHeading:(CGFloat) rotationHeading position:(WGCoordinate)newPos
+{
+ CoordSystemDisplayAdapter *coordAdapter = scene->getCoordAdapter();
+ Eigen::Quaternionf startQuat = [globeView rotQuat];
+ Eigen::Quaternionf northQuat;
+ {
+// Point3f worldLoc = GeoCoordSystem::LocalToGeocentricish(GeoCoord(newPos.x,newPos.y));
+
+ //calculate north Quaternion
+ Point3f localPt = coordAdapter->getCoordSystem()->geographicToLocal(GeoCoord(newPos.x,newPos.y));
+ Point3f worldLoc = coordAdapter->normalForLocal(localPt);
+
+ // Let's rotate to where they tapped over a 1sec period
+ Vector3f curUp = [globeView currentUp];
+
+ // The rotation from where we are to where we tapped
+ Eigen::Quaternionf endRot;
+ endRot = QuatFromTwoVectors(worldLoc,curUp);
+ Eigen::Quaternionf curRotQuat = startQuat;
+ Eigen::Quaternionf newRotQuat = curRotQuat * endRot;
+
+
+
+ if ( YES )
+ {
+ // We'd like to keep the north pole pointed up
+ // So we look at where the north pole is going
+ Vector3f northPole = (newRotQuat * Vector3f(0,0,1)).normalized();
+ if (northPole.y() != 0.0)
+ {
+ // Then rotate it back on to the YZ axis
+ // This will keep it upward
+ float ang = atanf(northPole.x()/northPole.y());
+ // However, the pole might be down now
+ // If so, rotate it back up
+ if (northPole.y() < 0.0)
+ ang += M_PI;
+ Eigen::AngleAxisf upRot(ang,worldLoc);
+ newRotQuat = newRotQuat * upRot;
+ }
+ }
+ northQuat = newRotQuat;
+
+ }
+
+ Vector3f axis = [globeView currentUp];
+ Eigen::AngleAxisf rotQuat(rotationHeading, axis);
+ Eigen::Quaternionf newRotQuat = northQuat * rotQuat;
+ [globeView setRotQuat:newRotQuat];
+}
+
// Called back on the main thread after the interaction thread does the selection
- (void)handleSelection:(WhirlyGlobeTapMessage *)msg didSelect:(NSObject *)selectedObj
{
View
4 WhirlyGlobeSrc/WhirlyGlobeLib/WhirlyGlobeLib.xcodeproj/project.pbxproj
@@ -1771,7 +1771,7 @@
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_OPTIMIZATION_LEVEL = 0;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_THUMB_SUPPORT = YES;
"GCC_THUMB_SUPPORT[arch=armv6]" = NO;
GCC_VERSION = com.apple.compilers.llvmgcc42;
@@ -1794,7 +1794,7 @@
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_C_LANGUAGE_STANDARD = c99;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_THUMB_SUPPORT = YES;
"GCC_THUMB_SUPPORT[arch=armv6]" = NO;
GCC_VERSION = com.apple.compilers.llvmgcc42;
View
3  WhirlyGlobeSrc/WhirlyGlobeLib/include/LayerThread.h
@@ -67,6 +67,9 @@
/// Remove the given layer.
- (void)removeLayer:(NSObject<WhirlyKitLayer> *)layer;
+/// Return count of layers.
+- (NSInteger)activeLayers;
+
/// Add a C++ object to be deleted after the thread has stopped
/// Always clal this from the main thread before you cancel the layer thread
- (void)addThingToDelete:(WhirlyKit::DelayedDeletable *)thing;
View
3  WhirlyGlobeSrc/WhirlyGlobeLib/include/MaplyAnimateTranslateMomentum.h
@@ -33,9 +33,10 @@
float maxTime;
CFTimeInterval startDate;
WhirlyKit::Point3f org;
+ std::vector<WhirlyKit::Point2f> bounds;
}
/// Initialize with a velocity and negative acceleration (to slow down)
-- (id)initWithView:(MaplyView *)globeView velocity:(float)velocity accel:(float)acceleration dir:(Eigen::Vector3f)dir;
+- (id)initWithView:(MaplyView *)globeView velocity:(float)velocity accel:(float)acceleration dir:(Eigen::Vector3f)dir bounds:(std::vector<WhirlyKit::Point2f> &)bounds;
@end
View
6 WhirlyGlobeSrc/WhirlyGlobeLib/include/MaplyPanDelegate.h
@@ -19,6 +19,7 @@
*/
#import <Foundation/Foundation.h>
+#import <vector>
#import "MaplyView.h"
@interface MaplyPanDelegate : NSObject <UIGestureRecognizerDelegate>
@@ -33,9 +34,14 @@
/// Viewer location when we started panning
WhirlyKit::Point3f startLoc;
CGPoint lastTouch;
+ /// Boundary quad that we're to stay within
+ std::vector<WhirlyKit::Point2f> bounds;
}
/// Create a pinch gesture and a delegate and wire them up to the given UIView
+ (MaplyPanDelegate *)panDelegateForView:(UIView *)view mapView:(MaplyView *)mapView;
+/// Set the bounding rectangle
+- (void)setBounds:(WhirlyKit::Point2f *)bounds;
+
@end
View
6 WhirlyGlobeSrc/WhirlyGlobeLib/include/MaplyPinchDelegate.h
@@ -23,11 +23,17 @@
@interface MaplyPinchDelegate : NSObject <UIGestureRecognizerDelegate>
{
+ /// Minimum allowable zoom level
+ float minZoom;
+ /// Maximum allowable zoom level
+ float maxZoom;
/// If we're zooming, where we started
float startZ;
MaplyView *mapView;
}
+@property (nonatomic,assign) float minZoom,maxZoom;
+
/// Create a pinch gesture and a delegate and wire them up to the given UIView
+ (MaplyPinchDelegate *)pinchDelegateForView:(UIView *)view mapView:(MaplyView *)mapView;
View
8 WhirlyGlobeSrc/WhirlyGlobeLib/include/MaplyView.h
@@ -65,11 +65,17 @@
/// Height above the plane
- (float)heightAboveSurface;
+/// Minimum valid height above plane
+- (float)minHeightAboveSurface;
+
+/// Maximum valid height above plane
+- (float)maxHeightAboveSurface;
+
/** Given a location on the screen and the screen size, figure out where we touched
the plane. Returns true if we hit and where.
Returns false if we didn't, which can only happened if we're turned away.
*/
-- (bool)pointOnPlaneFromScreen:(CGPoint)pt transform:(const Eigen::Matrix4f *)transform frameSize:(const WhirlyKit::Point2f &)frameSize hit:(WhirlyKit::Point3f *)hit;
+- (bool)pointOnPlaneFromScreen:(CGPoint)pt transform:(const Eigen::Matrix4f *)transform frameSize:(const WhirlyKit::Point2f &)frameSize hit:(WhirlyKit::Point3f *)hit clip:(bool)clip;
/** From a world location in 3D, figure the projection to the screen.
Returns a point within the frame.
View
6 WhirlyGlobeSrc/WhirlyGlobeLib/src/LayerThread.mm
@@ -91,6 +91,12 @@ - (void)removeLayerThread:(NSObject<WhirlyKitLayer> *)layer
}
}
+/// Return count of layers.
+- (NSInteger)activeLayers
+{
+ return [layers count];
+}
+
- (void)addThingToDelete:(WhirlyKit::DelayedDeletable *)thing
{
thingsToDelete.push_back(thing);
View
10 WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyAnimateTranslateMomentum.mm
@@ -25,7 +25,7 @@
@implementation MaplyAnimateTranslateMomentum
-- (id)initWithView:(MaplyView *)mapView velocity:(float)inVel accel:(float)inAcc dir:(Vector3f)inDir
+- (id)initWithView:(MaplyView *)mapView velocity:(float)inVel accel:(float)inAcc dir:(Vector3f)inDir bounds:(std::vector<WhirlyKit::Point2f> &)inBounds
{
if ((self = [super init]))
{
@@ -47,6 +47,8 @@ - (id)initWithView:(MaplyView *)mapView velocity:(float)inVel accel:(float)inAcc
startDate = 0;
} else
maxTime = MAXFLOAT;
+
+ bounds = inBounds;
}
return self;
@@ -59,7 +61,7 @@ - (void)updateView:(MaplyView *)mapView
if (startDate == 0.0)
return;
- float sinceStart = CFAbsoluteTime() - startDate;
+ float sinceStart = CFAbsoluteTimeGetCurrent() - startDate;
if (sinceStart > maxTime)
{
@@ -71,7 +73,9 @@ - (void)updateView:(MaplyView *)mapView
// Calculate the distance
float dist = (velocity + 0.5 * acceleration * sinceStart) * sinceStart;
Point3f newLoc = org + dir * dist;
- mapView.loc = newLoc;
+
+ if (bounds.empty() || PointInPolygon(Point2f(newLoc.x(),newLoc.y()), bounds))
+ mapView.loc = newLoc;
}
View
53 WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyPanDelegate.mm
@@ -56,6 +56,25 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni
return TRUE;
}
+- (void)setBounds:(WhirlyKit::Point2f *)inBounds
+{
+ bounds.clear();
+ for (unsigned int ii=0;ii<4;ii++)
+ bounds.push_back(inBounds[ii]);
+}
+
+// Bounds check on a single point
+- (bool)withinBounds:(Point3f &)loc
+{
+ if (bounds.empty())
+ return true;
+
+ return PointInPolygon(Point2f(loc.x(),loc.y()), bounds);
+}
+
+// How long we'll animate the gesture ending
+static const float AnimLen = 1.0;
+
// Called for pan actions
- (void)panAction:(id)sender
{
@@ -79,7 +98,7 @@ - (void)panAction:(id)sender
startTransform = [mapView calcFullMatrix];
[mapView pointOnPlaneFromScreen:[pan locationOfTouch:0 inView:pan.view] transform:&startTransform
frameSize:Point2f(sceneRender.framebufferWidth,sceneRender.framebufferHeight)
- hit:&startOnPlane];
+ hit:&startOnPlane clip:false];
startLoc = [mapView loc];
panning = YES;
}
@@ -96,41 +115,45 @@ - (void)panAction:(id)sender
lastTouch = touchPt;
[mapView pointOnPlaneFromScreen:touchPt transform:&startTransform
frameSize:Point2f(sceneRender.framebufferWidth,sceneRender.framebufferHeight)
- hit:&hit];
+ hit:&hit clip:false];
// Note: Just doing a translation for now. Won't take angle into account
Point3f newLoc = startOnPlane - hit + startLoc;
- [mapView setLoc:newLoc];
+
+ // We'll do a hard stop if we're not within the bounds
+ // Note: Should do an intersection instead
+ if ([self withinBounds:newLoc])
+ {
+ [mapView setLoc:newLoc];
+ }
}
}
break;
case UIGestureRecognizerStateEnded:
if (panning)
{
- panning = NO;
- break;
-
// We'll use this to get two points in model space
CGPoint vel = [pan velocityInView:glView];
CGPoint touch0 = lastTouch;
- CGPoint touch1 = touch0; touch1.x += vel.x; touch1.y += vel.y;
+ CGPoint touch1 = touch0; touch1.x += AnimLen*vel.x; touch1.y += AnimLen*vel.y;
Point3f model_p0,model_p1;
Eigen::Matrix4f modelMat = [mapView calcFullMatrix];
- [mapView pointOnPlaneFromScreen:touch0 transform:&modelMat frameSize:Point2f(sceneRender.framebufferWidth,sceneRender.framebufferHeight) hit:&model_p0];
- [mapView pointOnPlaneFromScreen:touch1 transform:&modelMat frameSize:Point2f(sceneRender.framebufferWidth,sceneRender.framebufferHeight) hit:&model_p1];
+ [mapView pointOnPlaneFromScreen:touch0 transform:&modelMat frameSize:Point2f(sceneRender.framebufferWidth/glView.contentScaleFactor,sceneRender.framebufferHeight/glView.contentScaleFactor) hit:&model_p0 clip:false];
+ [mapView pointOnPlaneFromScreen:touch1 transform:&modelMat frameSize:Point2f(sceneRender.framebufferWidth/glView.contentScaleFactor,sceneRender.framebufferHeight/glView.contentScaleFactor) hit:&model_p1 clip:false];
// This will give us a direction
Point2f dir(model_p1.x()-model_p0.x(),model_p1.y()-model_p0.y());
dir *= -1.0;
- float modelVel = dir.norm();
+ float len = dir.norm();
+ float modelVel = len / AnimLen;
dir.normalize();
-
- // The acceleration (to slow it down)
- float drag = -1.5;
- // Kick off a little movement at the end
- translateDelegate = [[MaplyAnimateTranslateMomentum alloc] initWithView:mapView velocity:modelVel accel:drag dir:Point3f(dir.x(),dir.y(),0.0)];
+ // Caluclate the acceleration based on how far we'd like it to go
+ float accel = - modelVel / (AnimLen * AnimLen);
+
+ // Kick off a little movement at the end
+ translateDelegate = [[MaplyAnimateTranslateMomentum alloc] initWithView:mapView velocity:modelVel accel:accel dir:Point3f(dir.x(),dir.y(),0.0) bounds:bounds];
mapView.delegate = translateDelegate;
panning = NO;
View
8 WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyPinchDelegate.mm
@@ -24,12 +24,15 @@
@implementation MaplyPinchDelegate
+@synthesize minZoom,maxZoom;
+
- (id)initWithMapView:(MaplyView *)inView
{
if ((self = [super init]))
{
mapView = inView;
startZ = 0.0;
+ minZoom = maxZoom = -1.0;
}
return self;
@@ -61,11 +64,14 @@ - (void)pinchGesture:(id)sender
case UIGestureRecognizerStateBegan:
// Store the starting Z for comparison
startZ = mapView.loc.z();
+ [mapView cancelAnimation];
break;
case UIGestureRecognizerStateChanged:
{
Point3f curLoc = mapView.loc;
- [mapView setLoc:Point3f(curLoc.x(),curLoc.y(),startZ/pinch.scale)];
+ float newZ = startZ/pinch.scale;
+ if (minZoom >= maxZoom || (minZoom < newZ && newZ < maxZoom))
+ [mapView setLoc:Point3f(curLoc.x(),curLoc.y(),newZ)];
}
break;
default:
View
2  WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyTapDelegate.mm
@@ -65,7 +65,7 @@ - (void)tapAction:(id)sender
Point3f hit;
Eigen::Matrix4f theTransform = [mapView calcFullMatrix];
CGPoint touchLoc = [tap locationOfTouch:0 inView:tap.view];
- if ([mapView pointOnPlaneFromScreen:touchLoc transform:&theTransform frameSize:Point2f(sceneRender.framebufferWidth,sceneRender.framebufferHeight) hit:&hit])
+ if ([mapView pointOnPlaneFromScreen:touchLoc transform:&theTransform frameSize:Point2f(sceneRender.framebufferWidth/glView.contentScaleFactor,sceneRender.framebufferHeight/glView.contentScaleFactor) hit:&hit clip:true])
{
MaplyTapMessage *msg = [[MaplyTapMessage alloc] init];
[msg setTouchLoc:touchLoc];
View
14 WhirlyGlobeSrc/WhirlyGlobeLib/src/MaplyView.mm
@@ -72,16 +72,26 @@ - (float)heightAboveSurface
return loc.z();
}
+- (float)minHeightAboveSurface
+{
+ return nearPlane;
+}
+
+- (float)maxHeightAboveSurface
+{
+ return farPlane;
+}
+
- (void)setLoc:(WhirlyKit::Point3f)newLoc
{
loc = newLoc;
[self runViewUpdates];
}
-- (bool)pointOnPlaneFromScreen:(CGPoint)pt transform:(const Eigen::Matrix4f *)transform frameSize:(const Point2f &)frameSize hit:(Point3f *)hit
+- (bool)pointOnPlaneFromScreen:(CGPoint)pt transform:(const Eigen::Matrix4f *)transform frameSize:(const Point2f &)frameSize hit:(Point3f *)hit clip:(bool)clip
{
// Back Project the screen point into model space
- Point3f screenPt = [self pointUnproject:Point2f(pt.x,pt.y) width:frameSize.x() height:frameSize.y() clip:true];
+ Point3f screenPt = [self pointUnproject:Point2f(pt.x,pt.y) width:frameSize.x() height:frameSize.y() clip:clip];
// Run the screen point and the eye point (origin) back through
// the model matrix to get a direction and origin in model space
View
7 WhirlyGlobeSrc/WhirlyGlobeLib/src/QuadDisplayLayer.mm
@@ -66,12 +66,7 @@ static float calcImportance(WhirlyKitViewState *viewState,Point3f eyeVec,Point3f
if (boost::math::isnan(area))
area = 0.0;
-
- // if (area > 10000.0)
- // {
- // NSLog(@"Got one");
- // }
-
+
return std::abs(area);
}
View
2  WhirlyGlobeSrc/WhirlyGlobeLib/src/ShapeLayer.mm
@@ -433,7 +433,7 @@ - (void)makeGeometryWithBuilder:(WhirlyKit::ShapeDrawableBuilder *)regBuilder tr
if (geoLoc.y() < -M_PI/2.0) geoLoc.y() = -M_PI/2.0;
if (geoLoc.y() > M_PI/2.0) geoLoc.y() = M_PI/2.0;
- Point3f spherePt = coordAdapter->localToDisplay(Point3f(geoLoc.lon(),geoLoc.lat(),0.0));
+ Point3f spherePt = FakeGeocentricDisplayAdapter::LocalToDisplay(Point3f(geoLoc.lon(),geoLoc.lat(),0.0));
Point3f thisPt = dispPt + spherePt * radius;
norms.push_back(spherePt);

No commit comments for this range

Something went wrong with that request. Please try again.