├── Everest.jpg ├── CesiumKitTests ├── en.lproj │ └── InfoPlist.strings └── CesiumKitTests-Info.plist ├── CurrentStatus.jpg ├── CesiumKitStatus.xlsx ├── CesiumKit ├── Assets │ └── Textures │ │ ├── moonSmall.jpg │ │ ├── waterNormals.jpg │ │ ├── waterNormalsSmall.jpg │ │ └── SkyBox │ │ ├── tycho2t3_80_mx.jpg │ │ ├── tycho2t3_80_my.jpg │ │ ├── tycho2t3_80_mz.jpg │ │ ├── tycho2t3_80_px.jpg │ │ ├── tycho2t3_80_py.jpg │ │ └── tycho2t3_80_pz.jpg ├── CesiumKit-Prefix.pch ├── Core │ ├── EncodedCartesian3.swift │ ├── Offset.swift │ ├── GeometryType.swift │ ├── RectangleWithLevel.swift │ ├── Orientation.swift │ ├── Intersect.swift │ ├── Intersectable.swift │ ├── HeightmapStructure.swift │ ├── Destination.swift │ ├── Interval.swift │ ├── OrbitType.swift │ ├── KeyboardEventModifier.swift │ ├── TimeStandard.swift │ ├── TerrainQuantization.swift │ ├── LeapSecond.swift │ ├── Spherical.swift │ ├── Visibility.swift │ ├── ClockStep.swift │ ├── ClockRange.swift │ ├── QuadtreeNode.swift │ ├── MapProjection.swift │ ├── Ray.swift │ ├── PixelFormat.swift │ ├── HeadingPitchRange.swift │ ├── Credit.swift │ ├── Queue.swift │ ├── TimeConstants.swift │ ├── ScreenSpaceEventType.swift │ ├── GeographicProjection.swift │ ├── MergeSort.swift │ └── CartesianType.swift ├── Scene │ ├── GroundPrimitive.swift │ ├── CameraEvent.swift │ ├── ImageryState.swift │ ├── SceneTransitioner.swift │ ├── Pass.swift │ ├── BingMapsAPI.swift │ ├── HeightReference.swift │ ├── BlendFunction.swift │ ├── LabelStyle.swift │ ├── QuadtreeOccluders.swift │ ├── BingMapsStyle.swift │ ├── VerticalOrigin.swift │ ├── TerrainState.swift │ ├── HorizontalOrigin.swift │ ├── TileDiscardPolicy.swift │ ├── EnvironmentState.swift │ ├── NeverTileDiscardPolicy.swift │ ├── BlendEquation.swift │ ├── FrustumCommands.swift │ ├── CameraEventType.swift │ ├── SceneMode.swift │ ├── TileLoadState.swift │ ├── CullingVolume.swift │ ├── ImageryLayerUniformMap.swift │ ├── MaterialType.swift │ ├── Imagery.swift │ ├── ImageryLayerFeatureInfo.swift │ ├── TileReplacementQueue.swift │ ├── OffscreenQuadPrimitive.swift │ ├── BlendingState.swift │ ├── TileImagery.swift │ └── FXAA.swift ├── Platform │ ├── Extensions │ │ └── CFRange+Comparison.swift │ ├── CesiumError.swift │ ├── DebugLog.swift │ ├── String+HMAC.swift │ ├── GlyphDescriptor.swift │ ├── LocalStorage.swift │ ├── QueueManager.swift │ ├── String.swift │ ├── Crypto.swift │ ├── Array.swift │ ├── ImageExtensions.swift │ └── Data+ArrayView.swift ├── Renderer │ ├── Command.swift │ ├── BufferSyncState.swift │ ├── CullFace.swift │ ├── Imagebuffer.swift │ ├── PixelFormat.swift │ ├── ColorMask.swift │ ├── TextureUsage.swift │ ├── WindingOrder.swift │ ├── CubeMap.swift │ ├── UniformBufferProvider.swift │ ├── RenderPass.swift │ ├── VertexType.swift │ ├── IndexDatatype.swift │ ├── VertexDescriptor.swift │ ├── Sampler.swift │ ├── DepthTest.swift │ ├── PassState.swift │ ├── UniformMap.swift │ ├── RenderPipeline.swift │ ├── Buffer.swift │ ├── ClearCommand.swift │ ├── Framebuffer.swift │ ├── ComputeCommand.swift │ └── ComputeEngine.swift ├── Info.plist └── Shaders │ ├── UniformStructs.metal │ └── TextRenderer.metal ├── CesiumKit.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── CesiumKit.xcscheme ├── CommonCrypto ├── macosx.modulemap ├── iphoneos.modulemap ├── iphonesimulator.modulemap ├── Config.xcconfig └── Info.plist ├── getDependencies.sh ├── .gitignore ├── CesiumKit-Bridging-Header.h ├── CREDITS.md ├── CesiumKit.h ├── CesiumKitRunner OSX ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist └── CesiumViewController.swift ├── CesiumKitRunner ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── CesiumViewController.swift ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.xib ├── Info.plist └── AppDelegate.swift └── README.md /Everest.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/Everest.jpg -------------------------------------------------------------------------------- /CesiumKitTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /CurrentStatus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CurrentStatus.jpg -------------------------------------------------------------------------------- /CesiumKitStatus.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKitStatus.xlsx -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/moonSmall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/moonSmall.jpg -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/waterNormals.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/waterNormals.jpg -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/waterNormalsSmall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/waterNormalsSmall.jpg -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_mx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_mx.jpg -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_my.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_my.jpg -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_mz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_mz.jpg -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_px.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_px.jpg -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_py.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_py.jpg -------------------------------------------------------------------------------- /CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_pz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tokyovigilante/CesiumKit/HEAD/CesiumKit/Assets/Textures/SkyBox/tycho2t3_80_pz.jpg -------------------------------------------------------------------------------- /CesiumKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CommonCrypto/macosx.modulemap: -------------------------------------------------------------------------------- 1 | module CommonCrypto [system] { 2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/CommonCrypto/CommonCrypto.h" 3 | export * 4 | } 5 | -------------------------------------------------------------------------------- /CommonCrypto/iphoneos.modulemap: -------------------------------------------------------------------------------- 1 | module CommonCrypto [system] { 2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h" 3 | export * 4 | } 5 | -------------------------------------------------------------------------------- /CesiumKit/CesiumKit-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /CesiumKit/Core/EncodedCartesian3.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EncodedCartesian3.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 8/09/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | struct EncodedCartesian3 { 10 | } -------------------------------------------------------------------------------- /CommonCrypto/iphonesimulator.modulemap: -------------------------------------------------------------------------------- 1 | module CommonCrypto [system] { 2 | header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h" 3 | export * 4 | } 5 | -------------------------------------------------------------------------------- /CesiumKit/Scene/GroundPrimitive.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GroundPrimitive.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 12/11/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class GroundPrimitive { 12 | 13 | } -------------------------------------------------------------------------------- /CesiumKit/Core/Offset.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Offset.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 7/05/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol Offset { 12 | var offset: Cartesian3 { get } 13 | } -------------------------------------------------------------------------------- /CesiumKit/Core/GeometryType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GeometryType.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 6/03/15. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | enum GeometryType { 10 | case none, 11 | triangles, 12 | lines, 13 | polylines 14 | } 15 | -------------------------------------------------------------------------------- /CesiumKit/Scene/CameraEvent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CameraEvent.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/03/2015. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | struct CameraEvent { 10 | let type: CameraEventType 11 | let modifier: KeyboardEventModifier? 12 | } -------------------------------------------------------------------------------- /getDependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdir -p CesiumKit/Platform/Dependencies 4 | cd ./CesiumKit/Platform/Dependencies 5 | 6 | echo "Cleanup..." 7 | rm -rf * 8 | 9 | echo "Cloning glsl-optimizer" 10 | git clone https://github.com/tokyovigilante/glsl-optimizer --depth 1 11 | 12 | echo "Ready to build CesiumKit" 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | CesiumKit.xcodeproj/project.xcworkspace/xcshareddata/ 3 | CesiumKit.xcodeproj/project.xcworkspace/xcuserdata/ 4 | CesiumKit.xcodeproj/xcuserdata/ 5 | CesiumKit/.DS_Store 6 | CesiumKit/Core/.DS_Store 7 | CesiumKit/Platform/.DS_Store 8 | CesiumKitRunner/.DS_Store 9 | build/ 10 | CesiumKit/Platform/Dependencies 11 | -------------------------------------------------------------------------------- /CesiumKit-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // CesiumKit-Bridging-Header.h 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 15/09/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | -------------------------------------------------------------------------------- /CesiumKit/Core/RectangleWithLevel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RectangleWithLevel.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 30/4/17. 6 | // Copyright © 2017 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct RectangleWithLevel { 12 | var level: Int 13 | var west: Double 14 | var south: Double 15 | var east: Double 16 | var north: Double 17 | } 18 | -------------------------------------------------------------------------------- /CesiumKit/Core/Orientation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Orientation.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/04/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum Orientation { 12 | case headingPitchRoll (heading: Double, pitch: Double, roll: Double) 13 | 14 | case directionUp (direction: Cartesian3, up: Cartesian3) 15 | } -------------------------------------------------------------------------------- /CREDITS.md: -------------------------------------------------------------------------------- 1 | CesiumKit Credits 2 | ================= 3 | 4 | Based on [Cesium](http://cesiumjs.org) by AGI 5 | 6 | Uses Regex class and Array extensions from the [Dollar ($wift)](https://github.com/ankurp/Dollar.swift) framework 7 | 8 | Uses [SwiftRegex extensions](https://github.com/johnno1962/SwiftRegex) by John Holdsworth 9 | 10 | Uses [AlamoFire](https://github.com/Alamofire/Alamofire) nextworking classes from Mattt Thompson -------------------------------------------------------------------------------- /CesiumKit/Scene/ImageryState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageryState.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 16/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | enum ImageryState { 10 | case unloaded, 11 | transitioning, 12 | received, 13 | textureLoaded, 14 | reprojected, 15 | ready, 16 | failed, 17 | invalid, 18 | placeHolder 19 | } 20 | 21 | -------------------------------------------------------------------------------- /CesiumKit/Platform/Extensions/CFRange+Comparison.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CFRange+Comparison.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 22/05/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension CFRange: Equatable {} 12 | 13 | public func == (lhs: CFRange, rhs: CFRange) -> Bool { 14 | return lhs.location == rhs.location && lhs.length == rhs.length 15 | } -------------------------------------------------------------------------------- /CesiumKit/Scene/SceneTransitioner.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneTransitioner.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 30/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | class SceneTransitioner { 10 | // FIXME: SceneTransitioner 11 | weak var owner: Scene? 12 | 13 | init (owner: Scene, projection: MapProjection) { 14 | 15 | self.owner = owner 16 | } 17 | } -------------------------------------------------------------------------------- /CesiumKit/Renderer/Command.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Command.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 10/10/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol Command { 12 | var pass: Pass { get } 13 | 14 | var boundingVolume: BoundingVolume? { get } 15 | } 16 | 17 | extension Command { 18 | var boundingVolume: BoundingVolume? { return nil } 19 | } -------------------------------------------------------------------------------- /CesiumKit/Renderer/BufferSyncState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BufferSyncState.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 24/04/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum BufferSyncState: Int { 12 | case zero = 0, one = 1, two = 2 13 | 14 | static let count = 3 15 | 16 | func advance() -> BufferSyncState { 17 | return BufferSyncState(rawValue: (self.rawValue + 1) % 3)! 18 | } 19 | } -------------------------------------------------------------------------------- /CesiumKit/Platform/CesiumError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Errors.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 18/06/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum CesiumError: Error, CustomDebugStringConvertible { 12 | 13 | case invalidProjectionInput 14 | 15 | var debugDescription: String { 16 | switch self { 17 | case .invalidProjectionInput: 18 | return "Invalid Cartesian projection point" 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/CullFace.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CullFace.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 17/09/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | enum CullFace { 12 | case none 13 | case front 14 | case back 15 | 16 | func toMetal() -> MTLCullMode { 17 | switch self { 18 | case .none: 19 | return .none 20 | case .front: 21 | return .front 22 | case .back: 23 | return .back 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CesiumKit/Platform/DebugLog.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DebugLog.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 18/06/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum LogLevel: UInt { 12 | case debug = 0, 13 | info, 14 | warning, 15 | error, 16 | critical 17 | } 18 | 19 | private var _loglevel: LogLevel = .info 20 | 21 | public func logPrint(_ level: LogLevel, _ logString: String) { 22 | if level.rawValue >= _loglevel.rawValue { 23 | print(logString) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CesiumKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // CesiumKit.h 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 17/03/15. 6 | // Copyright (c) 2015 Ryan Walklin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for CesiumKit. 12 | FOUNDATION_EXPORT double CesiumKitVersionNumber; 13 | 14 | //! Project version string for CesiumKit. 15 | FOUNDATION_EXPORT const unsigned char CesiumKitVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/Imagebuffer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageBuffer.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 16/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | /// raw image data, default 32-bit RGBA 10 | class Imagebuffer { 11 | let array: [UInt8] 12 | let width: Int 13 | let height: Int 14 | let bytesPerPixel: Int 15 | 16 | init(array: [UInt8], width: Int, height: Int, bytesPerPixel bpp: Int = 4) { 17 | self.array = array 18 | self.width = width 19 | self.height = height 20 | self.bytesPerPixel = bpp 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /CesiumKitRunner OSX/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CesiumKitRunner OSX 4 | // 5 | // Created by Ryan Walklin on 1/08/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | func applicationDidFinishLaunching(_ aNotification: Notification) { 15 | // Insert code here to initialize your application 16 | } 17 | 18 | func applicationWillTerminate(_ aNotification: Notification) { 19 | // Insert code here to tear down your application 20 | } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/PixelFormat.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PixelFormat.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 3/01/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | public enum PixelFormat: UInt { 12 | 13 | case invalid = 0 14 | 15 | case a8Unorm = 1 16 | case r8Unorm = 10 17 | 18 | case rgba8Unorm = 70 19 | case bgra8Unorm = 80 20 | 21 | case depth32Float = 252 22 | case stencil8 = 253 23 | case depth32FloatStencil8 = 260 24 | 25 | public func toMetal () -> MTLPixelFormat { 26 | return MTLPixelFormat(rawValue: self.rawValue)! 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /CesiumKit/Core/Intersect.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Intersect.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 6/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * This enumerated type is used in determining where, relative to the frustum, an 13 | * object is located. The object can either be fully contained within the frustum (INSIDE), 14 | * partially inside the frustum and partially outside (INTERSECTING), or somwhere entirely 15 | * outside of the frustum's 6 planes (OUTSIDE). 16 | * 17 | * @exports Intersect 18 | */ 19 | enum Intersect: Int { 20 | case outside = -1, intersecting, inside 21 | } 22 | 23 | -------------------------------------------------------------------------------- /CesiumKit/Core/Intersectable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BoundingVolume.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 15/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // Protocol for bounding volumes 12 | 13 | protocol BoundingVolume { 14 | 15 | var center: Cartesian3 { get } 16 | 17 | func intersectPlane(_ plane: Plane) -> Intersect 18 | 19 | func isOccluded (_ occluder: Occluder) -> Bool 20 | 21 | func distanceSquaredTo(_ cartesian: Cartesian3) -> Double 22 | 23 | func computePlaneDistances(_ position: Cartesian3, direction: Cartesian3) -> Interval 24 | 25 | } 26 | -------------------------------------------------------------------------------- /CesiumKit/Core/HeightmapStructure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeightmapStructure.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 26/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * The default structure of a heightmap, as given to {@link HeightmapTessellator.computeVertices}. 13 | * 14 | * @constant 15 | */ 16 | struct HeightmapStructure { 17 | var heightScale = 1.0 18 | var heightOffset = 0.0 19 | var elementsPerHeight = 1 20 | var stride = 1 21 | var elementMultiplier = 256.0 22 | var isBigEndian = false 23 | var lowestEncodedHeight = 0 24 | var highestEncodedHeight = 256 * 256 - 1 25 | } 26 | -------------------------------------------------------------------------------- /CesiumKit/Scene/Pass.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Pass.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 17/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | /** 10 | * The render pass for a command. 11 | * 12 | * @private 13 | */ 14 | enum Pass: Int { 15 | // Commands are executed in order by pass up to the translucent pass. 16 | // Translucent geometry needs special handling (sorting/OIT). Overlays 17 | // are also special (they're executed last, they're not sorted by frustum). 18 | case environment = 0, 19 | compute, 20 | offscreenQuad, 21 | globe, 22 | ground, 23 | opaque, 24 | translucent, 25 | overlay, 26 | overlayText 27 | 28 | static let count = 8 29 | } 30 | -------------------------------------------------------------------------------- /CommonCrypto/Config.xcconfig: -------------------------------------------------------------------------------- 1 | // 2 | // Config.xcconfig 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 13/04/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | MODULEMAP_FILE[sdk=iphoneos*] = $(SRCROOT)/CCommonCrypto/iphoneos.modulemap 10 | MODULEMAP_FILE[sdk=iphonesimulator*] = $(SRCROOT)/CCommonCrypto/iphonesimulator.modulemap 11 | MODULEMAP_FILE[sdk=macosx*] = $(SRCROOT)/CCommonCrypto/macosx.modulemap 12 | MODULEMAP_FILE[sdk=appletvos*] = $(SRCROOT)/CommonCrypto/appletvos.modulemap 13 | MODULEMAP_FILE[sdk=appletvsimulator*] = $(SRCROOT)/CCommonCrypto/appletvsimulator.modulemap 14 | MODULEMAP_FILE[sdk=watchos*] = $(SRCROOT)/CCommonCrypto/watchos.modulemap 15 | MODULEMAP_FILE[sdk=watchsimulator*] = $(SRCROOT)/CCommonCrypto/watchsimulator.modulemap 16 | -------------------------------------------------------------------------------- /CesiumKit/Core/Destination.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Destination.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/04/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum Destination { 12 | case cartesian(Cartesian3) 13 | 14 | case rectangle(Rectangle) 15 | 16 | var cartesian: Cartesian3? { 17 | switch self { 18 | case let .cartesian(cartesian): 19 | return cartesian 20 | default: 21 | return nil 22 | } 23 | } 24 | 25 | var rectangle: Rectangle? { 26 | switch self { 27 | case let .rectangle(rectangle): 28 | return rectangle 29 | default: 30 | return nil 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CesiumKitTests/CesiumKitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /CesiumKit/Scene/BingMapsAPI.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * Object for setting and retrieving the default BingMaps API key. 3 | * 4 | * @namespace 5 | * @alias BingMapsApi 6 | */ 7 | 8 | class BingMapsAPI { 9 | 10 | class func getKey(_ key: String?) -> String { 11 | if key != nil { 12 | return key! 13 | } 14 | logPrint(.warning, "This application is using CesiumKit's default Bing Maps key. Please create a new key for the application as soon as possible and prior to deployment by visiting https://www.bingmapsportal.com, and provide your key to CesiumKit by setting the BingMapsImageryProvider.Key property before constructing the CesiumWidget or any other object that uses the Bing Maps API.") 15 | return "AqJZu2hZlN7PoYUQRF4YoTwknbXwuK5vVK9f7STen3t9sHrdOlIA49rpI-swOOLt" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/ColorMask.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorMask.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 5/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Metal 11 | 12 | struct ColorMask { 13 | var red = true 14 | var green = true 15 | var blue = true 16 | var alpha = true 17 | 18 | func description() -> String { 19 | return (red ? "r" : "x") + (green ? "g" : "x") + (blue ? "b" : "x") + (alpha ? "a" : "x") 20 | } 21 | 22 | func toMetal() -> MTLColorWriteMask { 23 | let writeMask: MTLColorWriteMask = [(red ? .red : MTLColorWriteMask()), (green ? .green : MTLColorWriteMask()), (blue ? .blue : MTLColorWriteMask()), (alpha ? .alpha : MTLColorWriteMask())] 24 | return writeMask 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CesiumKit/Platform/String+HMAC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+HMAC.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 13/04/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension String { 12 | var md5: String { 13 | return HMAC.hash(self, algo: .md5) 14 | } 15 | 16 | var sha1: String { 17 | return HMAC.hash(self, algo: .sha1) 18 | } 19 | 20 | var sha224: String { 21 | return HMAC.hash(self, algo: .sha224) 22 | } 23 | 24 | var sha256: String { 25 | return HMAC.hash(self, algo: .sha256) 26 | } 27 | 28 | var sha384: String { 29 | return HMAC.hash(self, algo: .sha384) 30 | } 31 | 32 | var sha512: String { 33 | return HMAC.hash(self, algo: .sha512) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/TextureUsage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextureUsage.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 4/01/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import Metal 12 | 13 | public struct TextureUsage: OptionSet { 14 | 15 | public let rawValue: UInt 16 | public init(rawValue: UInt) { self.rawValue = rawValue } 17 | 18 | static let Unknown = TextureUsage(rawValue: 0) 19 | static let ShaderRead = TextureUsage(rawValue: 1) 20 | static let ShaderWrite = TextureUsage(rawValue: 1 << 1) 21 | static let RenderTarget = TextureUsage(rawValue: 1 << 2) 22 | static let PixelFormatView = TextureUsage(rawValue: 1 << 3) 23 | 24 | func toMetal () -> MTLTextureUsage { 25 | return MTLTextureUsage(rawValue: self.rawValue) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CesiumKit/Core/Interval.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Interval.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 7/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | /** 10 | * Represents the closed interval [start, stop]. 11 | * @alias Interval 12 | * @constructor 13 | * 14 | * @param {Number} [start=0.0] The beginning of the interval. 15 | * @param {Number} [stop=0.0] The end of the interval. 16 | */ 17 | struct Interval: Equatable { 18 | /** 19 | * The beginning of the interval. 20 | * @type {Number} 21 | * @default 0.0 22 | */ 23 | var start = 0.0 24 | /** 25 | * The end of the interval. 26 | * @type {Number} 27 | * @default 0.0 28 | */ 29 | var stop = 0.0 30 | } 31 | 32 | func == (lhs: Interval, rhs: Interval) -> Bool { 33 | return lhs.start == rhs.start && lhs.stop == rhs.stop 34 | } 35 | -------------------------------------------------------------------------------- /CesiumKit/Scene/HeightReference.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeightReference.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 12/11/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Represents the position relative to the terrain. 13 | * 14 | * @namespace 15 | * @alias HeightReference 16 | */ 17 | enum HeightReference { 18 | 19 | /** 20 | * The position is absolute. 21 | * @type {Number} 22 | * @constant 23 | */ 24 | case none 25 | 26 | /** 27 | * The position is clamped to the terrain. 28 | * @type {Number} 29 | * @constant 30 | */ 31 | case clampToGround 32 | 33 | /** 34 | * The position height is the height above the terrain. 35 | * @type {Number} 36 | * @constant 37 | */ 38 | case relativeToGround 39 | 40 | } 41 | -------------------------------------------------------------------------------- /CesiumKit/Scene/BlendFunction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlendFunction.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 25/10/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | /** 11 | * Determines how blending factors are computed. 12 | * 13 | */ 14 | 15 | enum BlendFunction: UInt { 16 | case zero 17 | case one 18 | case sourceColor 19 | case oneMinusSourceColor 20 | case sourceAlpha 21 | case oneMinusSourceAlpha 22 | case destinationColor 23 | case oneMinusDestinationColor 24 | case destinationAlpha 25 | case oneMinusDestinationAlpha 26 | case sourceAlphaSaturated 27 | case blendColor 28 | case oneMinusBlendColor 29 | case blendAlpha 30 | case oneMinusBlendAlpha 31 | 32 | func toMetal() -> MTLBlendFactor { 33 | return MTLBlendFactor(rawValue: self.rawValue)! 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /CesiumKit/Platform/GlyphDescriptor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GlyphDescriptor.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 22/02/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreGraphics 11 | 12 | struct GlyphDescriptor: Codable { 13 | 14 | enum CodingKeys: String, CodingKey { 15 | case topLeft = "tl" 16 | case bottomRight = "br" 17 | } 18 | 19 | var topLeft: GlyphPoint 20 | 21 | var bottomRight: GlyphPoint 22 | 23 | init (topLeftTexCoord: CGPoint, bottomRightTexCoord: CGPoint) { 24 | topLeft = GlyphPoint(x: Double(topLeftTexCoord.x), y: Double(topLeftTexCoord.y)) 25 | bottomRight = GlyphPoint(x: Double(bottomRightTexCoord.x), y: Double(bottomRightTexCoord.y)) 26 | } 27 | } 28 | 29 | struct GlyphPoint: Codable { 30 | var x: Double 31 | var y: Double 32 | } 33 | 34 | -------------------------------------------------------------------------------- /CesiumKit/Scene/LabelStyle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LabelStyle.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 31/01/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Describes how to draw a label. 13 | * 14 | * @namespace 15 | * @alias LabelStyle 16 | * 17 | * @see Label#style 18 | */ 19 | public enum LabelStyle { 20 | /** 21 | * Fill the text of the label, but do not outline. 22 | * 23 | * @type {Number} 24 | * @constant 25 | */ 26 | case fill 27 | 28 | /** 29 | * Outline the text of the label, but do not fill. 30 | * 31 | * @type {Number} 32 | * @constant 33 | */ 34 | case outline 35 | 36 | /** 37 | * Fill and outline the text of the label. 38 | * 39 | * @type {Number} 40 | * @constant 41 | */ 42 | case fillAndOutline 43 | } 44 | -------------------------------------------------------------------------------- /CesiumKit/Platform/LocalStorage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocalStorage.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 1/03/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Functions to store support files on device 12 | class LocalStorage { 13 | 14 | // Singleton 15 | static let sharedInstance = LocalStorage() 16 | 17 | func getAppSupportURL () -> URL { 18 | #if os(OSX) 19 | return FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0].appendingPathComponent(getExecutableName()) 20 | #elseif os(iOS) 21 | return FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] 22 | #endif 23 | } 24 | 25 | func getExecutableName () -> String { 26 | return ProcessInfo.processInfo.processName 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /CesiumKit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /CesiumKit/Core/OrbitType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OrbitType.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 20/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum OrbitType { 12 | 13 | case circular 14 | 15 | case elliptical 16 | 17 | case parabolic 18 | 19 | case hyperbolic 20 | 21 | static func fromEccentricity(_ eccentricity: Double, tolerance: Double) -> OrbitType { 22 | assert(eccentricity >= 0, "eccentricity cannot be negative.") 23 | 24 | if eccentricity <= tolerance { 25 | return .circular 26 | } else if eccentricity < 1.0 - tolerance { 27 | return .elliptical 28 | } else if eccentricity <= 1.0 + tolerance { 29 | return .parabolic 30 | } else { 31 | return .hyperbolic 32 | } 33 | } 34 | 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /CesiumKit/Core/KeyboardEventModifier.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyboardEventModifier.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/03/2015. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | 10 | /** 11 | * This enumerated type is for representing keyboard modifiers. These are keys 12 | * that are held down in addition to other event types. 13 | * 14 | * @namespace 15 | * @alias KeyboardEventModifier 16 | */ 17 | public enum KeyboardEventModifier: Int { 18 | /** 19 | * Represents the shift key being held down. 20 | * 21 | * @type {Number} 22 | * @constant 23 | */ 24 | case shift = 0, 25 | 26 | /** 27 | * Represents the control key being held down. 28 | * 29 | * @type {Number} 30 | * @constant 31 | */ 32 | ctrl, 33 | 34 | /** 35 | * Represents the alt key being held down. 36 | * 37 | * @type {Number} 38 | * @constant 39 | */ 40 | alt, 41 | 42 | count 43 | } 44 | -------------------------------------------------------------------------------- /CesiumKit/Core/TimeStandard.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimeStandard.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 10/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Provides the type of time standards which JulianDate can take as input. 13 | * 14 | * @namespace 15 | * @alias TimeStandard 16 | * 17 | * @see JulianDate 18 | */ 19 | public enum TimeStandard { 20 | /** 21 | * Represents the coordinated Universal Time (UTC) time standard. 22 | * 23 | * UTC is related to TAI according to the relationship 24 | * UTC = TAI - deltaT where deltaT is the number of leap 25 | * seconds which have been introduced as of the time in TAI. 26 | * 27 | */ 28 | case utc 29 | 30 | /** 31 | * Represents the International Atomic Time (TAI) time standard. 32 | * TAI is the principal time standard to which the other time standards are related. 33 | */ 34 | case tai 35 | } 36 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/WindingOrder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindingOrder.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 17/09/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | /** 12 | * Winding order defines the order of vertices for a triangle to be considered front-facing. 13 | * 14 | * @namespace 15 | * @alias WindingOrder 16 | */ 17 | enum WindingOrder { 18 | /** 19 | * 0x0900. Vertices are in clockwise order. 20 | * 21 | * @type {Number} 22 | * @constant 23 | */ 24 | case clockwise, // WebGL: CW 25 | 26 | /** 27 | * 0x0901. Vertices are in counter-clockwise order. 28 | * 29 | * @type {Number} 30 | * @constant 31 | */ 32 | counterClockwise // WebGL: CCW 33 | 34 | func toMetal() -> MTLWinding { 35 | switch self { 36 | case .clockwise: 37 | return .clockwise 38 | case .counterClockwise: 39 | return .counterClockwise 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /CesiumKit/Scene/QuadtreeOccluders.swift: -------------------------------------------------------------------------------- 1 | // 2 | // QuadtreeOccluders.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/09/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | /** 10 | * A set of occluders that can be used to test quadtree tiles for occlusion. 11 | * 12 | * @alias QuadtreeOccluders 13 | * @constructor 14 | * @private 15 | * 16 | * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid that potentially occludes tiles. 17 | */ 18 | class QuadtreeOccluders { 19 | 20 | /** 21 | * Gets the {@link EllipsoidalOccluder} that can be used to determine if a point is 22 | * occluded by an {@link Ellipsoid}. 23 | * @type {EllipsoidalOccluder} 24 | * @memberof QuadtreeOccluders.prototype 25 | */ 26 | let ellipsoid: EllipsoidalOccluder 27 | 28 | init(ellipsoid: Ellipsoid, cameraPosition: Cartesian3 = Cartesian3.zero) { 29 | self.ellipsoid = EllipsoidalOccluder(ellipsoid: ellipsoid, cameraPosition: cameraPosition) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CommonCrypto/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2016 Test Toast. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /CesiumKit/Scene/BingMapsStyle.swift: -------------------------------------------------------------------------------- 1 | /** 2 | * The types of imagery provided by Bing Maps. 3 | * 4 | * @namespace 5 | * @alias BingMapsStyle 6 | * 7 | * @see BingMapsImageryProvider 8 | */ 9 | 10 | public enum BingMapsStyle: String { 11 | /** 12 | * Aerial imagery. 13 | * 14 | * @type {String} 15 | * @constant 16 | */ 17 | case Aerial = "Aerial", 18 | 19 | /** 20 | * Aerial imagery with a road overlay. 21 | * 22 | * @type {String} 23 | * @constant 24 | */ 25 | AerialWithLabels = "AerialWithLabels", 26 | 27 | /** 28 | * Roads without additional imagery. 29 | * 30 | * @type {String} 31 | * @constant 32 | */ 33 | Road = "Road", 34 | 35 | /** 36 | * Ordnance Survey imagery 37 | * 38 | * @type {String} 39 | * @constant 40 | */ 41 | OrdnanceSurvey = "OrdnanceSurvey", 42 | 43 | /** 44 | * Collins Bart imagery. 45 | * 46 | * @type {String} 47 | * @constant 48 | */ 49 | CollinsBart = "CollinsBart" 50 | } 51 | -------------------------------------------------------------------------------- /CesiumKit/Core/TerrainQuantization.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TerrainQuantization.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 25/04/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | /** 10 | * This enumerated type is used to determine how the vertices of the terrain mesh are compressed. 11 | * 12 | * @exports TerrainQuantization 13 | * 14 | * @private 15 | */ 16 | import Foundation 17 | 18 | enum TerrainQuantization { 19 | /** 20 | * The vertices are not compressed. 21 | * 22 | * @type {Number} 23 | * @constant 24 | */ 25 | case none 26 | 27 | /** 28 | * The vertices are compressed to 12 bits. 29 | * 30 | * @type {Number} 31 | * @constant 32 | */ 33 | case bits12 34 | 35 | var define: String { 36 | switch self { 37 | case .bits12: 38 | return "QUANTIZATION_BITS12" 39 | case .none: 40 | return "" 41 | } 42 | } 43 | 44 | var enabled: Bool { 45 | return self == .bits12 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/CubeMap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CubeMap.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 22/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct CubeMapSources { 12 | let sources: [CGImage] 13 | } 14 | 15 | extension CubeMapSources { 16 | 17 | var positiveX: CGImage { 18 | return sources[0] 19 | } 20 | 21 | var negativeX: CGImage { 22 | return sources[1] 23 | } 24 | 25 | var positiveY: CGImage { 26 | return sources[2] 27 | } 28 | 29 | var negativeY: CGImage { 30 | return sources[3] 31 | } 32 | 33 | var positiveZ: CGImage { 34 | return sources[4] 35 | } 36 | 37 | var negativeZ: CGImage { 38 | return sources[5] 39 | } 40 | 41 | } 42 | 43 | class CubeMap { 44 | 45 | class func loadImagesForSources (_ sources: [String]) -> CubeMapSources { 46 | return CubeMapSources(sources: sources.flatMap { $0.loadImageForCubeMapSource() }) 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /CesiumKit/Core/LeapSecond.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeapSecond.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 19/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Describes a single leap second, which is constructed from a {@link JulianDate} and a 13 | * numerical offset representing the number of seconds TAI is ahead of the UTC time standard. 14 | * @alias LeapSecond 15 | * @constructor 16 | * 17 | * @param {JulianDate} [date] A Julian date representing the time of the leap second. 18 | * @param {Number} [offset] The cumulative number of seconds that TAI is ahead of UTC at the provided date. 19 | */ 20 | struct LeapSecond { 21 | 22 | /** 23 | * Gets or sets the date at which this leap second occurs. 24 | * @type {JulianDate} 25 | */ 26 | let julianDate: JulianDate 27 | 28 | /** 29 | * Gets or sets the cumulative number of seconds between the UTC and TAI time standards at the time 30 | * of this leap second. 31 | * @type {Number} 32 | */ 33 | let offset: Int 34 | 35 | } -------------------------------------------------------------------------------- /CesiumKit/Scene/VerticalOrigin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VerticalOrigin.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 31/01/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | /** 13 | * The vertical location of an origin relative to an object, e.g., a {@link Billboard}. 14 | * For example, the vertical origin is used to display a billboard above or below (in 15 | * screen space) of the actual position. 16 | * 17 | * @namespace 18 | * @alias VerticalOrigin 19 | * 20 | * @see Billboard#verticalOrigin 21 | */ 22 | public enum VerticalOrigin { 23 | /** 24 | * The origin is at the vertical center of the object. 25 | * 26 | * @type {Number} 27 | * @constant 28 | */ 29 | case center 30 | 31 | /** 32 | * The origin is at the bottom of the object. 33 | * 34 | * @type {Number} 35 | * @constant 36 | */ 37 | case bottom 38 | 39 | /** 40 | * The origin is at the top of the object. 41 | * 42 | * @type {Number} 43 | * @constant 44 | */ 45 | case top 46 | } 47 | -------------------------------------------------------------------------------- /CesiumKit/Core/Spherical.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Spherical.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 9/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * A set of curvilinear 3-dimensional coordinates. 13 | * 14 | * @alias Spherical 15 | * @constructor 16 | * 17 | * @param {Number} [clock=0.0] The angular coordinate lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. 18 | * @param {Number} [cone=0.0] The angular coordinate measured from the positive z-axis and toward the negative z-axis. 19 | * @param {Number} [magnitude=1.0] The linear coordinate measured from the origin. 20 | */ 21 | // FIXME: Packable 22 | struct Spherical/*: Packable*/ { 23 | var clock: Double = 0.0 24 | var cone: Double = 0.0 25 | var magnitude: Double = 1.0 26 | 27 | static let packedLength: Int = 3; 28 | 29 | func pack(_ array: inout [Float], startingIndex: Int) { 30 | } 31 | 32 | static func unpack(_ array: [Float], startingIndex: Int) -> Spherical { 33 | return Spherical() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /CesiumKit/Core/Visibility.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Visibility.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 15/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * This enumerated type is used in determining to what extent an object, the occludee, 13 | * is visible during horizon culling. An occluder may fully block an occludee, in which case 14 | * it has no visibility, may partially block an occludee from view, or may not block it at all, 15 | * leading to full visibility. 16 | * 17 | * @exports Visibility 18 | */ 19 | enum Visibility: Int { 20 | /** 21 | * Represents that no part of an object is visible. 22 | * 23 | * @type {Number} 24 | * @constant 25 | */ 26 | case none = -1, 27 | 28 | /** 29 | * Represents that part, but not all, of an object is visible 30 | * 31 | * @type {Number} 32 | * @constant 33 | */ 34 | partial, 35 | 36 | /** 37 | * Represents that an object is visible in its entirety. 38 | * 39 | * @type {Number} 40 | * @constant 41 | */ 42 | full 43 | } 44 | -------------------------------------------------------------------------------- /CesiumKit/Scene/TerrainState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TerrainState.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 16/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | enum TerrainState: Int, CustomStringConvertible { 10 | 11 | case failed = 0, 12 | unloaded, 13 | receiving, 14 | received, 15 | transforming, 16 | transformed, 17 | buffering, 18 | ready 19 | 20 | var description: String { 21 | get { 22 | switch self { 23 | case .failed: 24 | return "Failed" 25 | case .unloaded: 26 | return "Unloaded" 27 | case .receiving: 28 | return "Receiving" 29 | case .received: 30 | return "Received" 31 | case .transforming: 32 | return "Transforming" 33 | case .transformed: 34 | return "Transformed" 35 | case .buffering: 36 | return "Buffering" 37 | case .ready: 38 | return "Ready" 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /CesiumKit/Scene/HorizontalOrigin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalOrigin.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 31/01/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * The horizontal location of an origin relative to an object, e.g., a {@link Billboard}. 13 | * For example, the horizontal origin is used to display a billboard to the left or right (in 14 | * screen space) of the actual position. 15 | * 16 | * @namespace 17 | * @alias HorizontalOrigin 18 | * 19 | * @see Billboard#horizontalOrigin 20 | */ 21 | 22 | public enum HorizontalOrigin { 23 | /** 24 | * The origin is at the horizontal center of the object. 25 | * 26 | * @type {Number} 27 | * @constant 28 | */ 29 | case center 30 | 31 | /** 32 | * The origin is on the left side of the object. 33 | * 34 | * @type {Number} 35 | * @constant 36 | */ 37 | case left 38 | /** 39 | * The origin is on the right side of the object. 40 | * 41 | * @type {Number} 42 | * @constant 43 | */ 44 | case right 45 | } 46 | -------------------------------------------------------------------------------- /CesiumKit/Shaders/UniformStructs.metal: -------------------------------------------------------------------------------- 1 | // 2 | // UniformStructs.metal 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 27/03/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | 12 | struct AutomaticUniform 13 | { 14 | float3x3 czm_a_viewRotation; 15 | float3x3 czm_a_temeToPseudoFixed; 16 | float3 czm_a_sunDirectionEC; 17 | float3 czm_a_sunDirectionWC; 18 | float3 czm_a_moonDirectionEC; 19 | float3 czm_a_viewerPositionWC; 20 | float czm_a_morphTime; 21 | float czm_a_fogDensity; 22 | float czm_a_frameNumber; 23 | }; 24 | 25 | struct FrustumUniform 26 | { 27 | float4x4 czm_f_viewportOrthographic; 28 | float4x4 czm_f_viewportTransformation; 29 | float4x4 czm_f_projection; 30 | float4x4 czm_f_inverseProjection; 31 | float4x4 czm_f_view; 32 | float4x4 czm_f_modelView; 33 | float4x4 czm_f_modelView3D; 34 | float4x4 czm_f_inverseModelView; 35 | float4x4 czm_f_modelViewProjection; 36 | float4 czm_f_viewport; 37 | float3x3 czm_f_normal; 38 | float3x3 czm_f_normal3D; 39 | float2 czm_f_entireFrustum; 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/UniformBufferProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BufferProvider.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 10/06/2015. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Metal 11 | 12 | open class UniformBufferProvider { 13 | 14 | let bufferSize: Int 15 | 16 | fileprivate var _buffers = [Buffer]() 17 | 18 | let deallocationBlock: UniformMapDeallocBlock? 19 | 20 | init? (device: MTLDevice, bufferSize: Int, deallocationBlock: UniformMapDeallocBlock?) { 21 | 22 | self.bufferSize = bufferSize 23 | self.deallocationBlock = deallocationBlock 24 | 25 | for _ in 0.. Buffer { 35 | return _buffers[index.rawValue] 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /CesiumKit/Scene/TileDiscardPolicy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TileDiscardPolicy.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 24/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import CoreGraphics 10 | 11 | /** 12 | * A policy for discarding tile images according to some criteria. This type describes an 13 | * interface and is not intended to be instantiated directly. 14 | * 15 | * @alias TileDiscardPolicy 16 | * @constructor 17 | * 18 | * @see DiscardMissingTileImagePolicy 19 | * @see NeverTileDiscardPolicy 20 | */ 21 | public protocol TileDiscardPolicy { 22 | 23 | /** 24 | * Determines if the discard policy is ready to process images. 25 | * @function 26 | * 27 | * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. 28 | */ 29 | var isReady: Bool { get } 30 | 31 | /** 32 | * Given a tile image, decide whether to discard that image. 33 | * @function 34 | * 35 | * @param {Image} image An image to test. 36 | * @returns {Boolean} True if the image should be discarded; otherwise, false. 37 | */ 38 | func shouldDiscardImage (_ image: CGImage) -> Bool 39 | } 40 | -------------------------------------------------------------------------------- /CesiumKitRunner OSX/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /CesiumKit/Scene/EnvironmentState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EnvironmentState.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 1/05/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // Keeps track of the state of a frame. FrameState is the state across 12 | // the primitives of the scene. This state is for internally keeping track 13 | // of celestial and environment effects that need to be updated/rendered in 14 | // a certain order as well as updating/tracking framebuffer usage. 15 | struct EnvironmentState { 16 | var skyBoxCommand: DrawCommand! = nil 17 | var skyAtmosphereCommand: DrawCommand! = nil 18 | var sunDrawCommand: DrawCommand! = nil 19 | var sunComputeCommand: ComputeCommand! = nil 20 | var moonCommand: DrawCommand! = nil 21 | 22 | var isSunVisible: Bool = false 23 | var isMoonVisible: Bool = false 24 | var isSkyAtmosphereVisible: Bool = false 25 | 26 | var clearGlobeDepth: Bool = false 27 | var useDepthPlane: Bool = false 28 | 29 | var originalFramebuffer: Framebuffer! = nil 30 | var useGlobeDepthFramebuffer: Bool = false 31 | var useOIT: Bool = false 32 | var useFXAA: Bool = false 33 | } -------------------------------------------------------------------------------- /CesiumKit/Core/ClockStep.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ClockStep.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 11/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Constants to determine how much time advances with each call 13 | * to {@link Clock#tick}. 14 | * 15 | * @namespace 16 | * @alias ClockStep 17 | * 18 | * @see Clock 19 | * @see ClockRange 20 | */ 21 | public enum ClockStep { 22 | 23 | /** 24 | * {@link Clock#tick} advances the current time by a fixed step, 25 | * which is the number of seconds specified by {@link Clock#multiplier}. 26 | * 27 | * @type {Number} 28 | * @constant 29 | */ 30 | case tickDependent 31 | 32 | /** 33 | * {@link Clock#tick} advances the current time by the amount of system 34 | * time elapsed since the previous call multiplied by {@link Clock#multiplier}. 35 | * 36 | * @type {Number} 37 | * @constant 38 | */ 39 | case systemClockMultiplier 40 | 41 | /** 42 | * {@link Clock#tick} sets the clock to the current system time; 43 | * ignoring all other settings. 44 | * 45 | * @type {Number} 46 | * @constant 47 | */ 48 | case systemClock 49 | } 50 | -------------------------------------------------------------------------------- /CesiumKit/Scene/NeverTileDiscardPolicy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NeverTileDiscardPolicy.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 31/01/15. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * A {@link TileDiscardPolicy} specifying that tile images should never be discard. 13 | * 14 | * @alias NeverTileDiscardPolicy 15 | * @constructor 16 | * 17 | * @see DiscardMissingTileImagePolicy 18 | */ 19 | public class NeverTileDiscardPolicy: TileDiscardPolicy { 20 | 21 | public init () { 22 | 23 | } 24 | 25 | /** 26 | * Determines if the discard policy is ready to process images. 27 | * @returns True if the discard policy is ready to process images; otherwise, false. 28 | */ 29 | public var isReady: Bool { 30 | get { 31 | return true 32 | } 33 | } 34 | 35 | /** 36 | * Given a tile image, decide whether to discard that image. 37 | * 38 | * @param {Image|Promise} image An image, or a promise that will resolve to an image. 39 | * @returns A promise that will resolve to true if the tile should be discarded. 40 | */ 41 | public func shouldDiscardImage (_ image: CGImage) -> Bool { 42 | return false 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /CesiumKit/Platform/QueueManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // QueueManager.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 1/01/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | private let _maxConcurrentNetworkRequests = 12 12 | 13 | class QueueManager { 14 | 15 | static let sharedInstance = QueueManager() 16 | 17 | let processorQueue: DispatchQueue 18 | 19 | let networkQueue: OperationQueue 20 | 21 | let upsampleQueue: DispatchQueue 22 | 23 | let resourceLoadQueue: DispatchQueue 24 | 25 | let fontAtlasQueue: DispatchQueue 26 | 27 | init () { 28 | processorQueue = DispatchQueue(label: "com.testtoast.CesiumKit.processorQueue") 29 | upsampleQueue = DispatchQueue(label: "com.testtoast.CesiumKit.upsampleQueue") 30 | resourceLoadQueue = DispatchQueue(label: "com.testtoast.CesiumKit.textureLoadQueue") 31 | fontAtlasQueue = DispatchQueue(label: "com.testtoast.CesiumKit.fontAtlasQueue") 32 | 33 | networkQueue = OperationQueue() 34 | networkQueue.qualityOfService = .utility 35 | networkQueue.isSuspended = false 36 | networkQueue.maxConcurrentOperationCount = _maxConcurrentNetworkRequests 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /CesiumKit/Scene/BlendEquation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlendEquation.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 25/10/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | /** 12 | * Determines how two pixels' values are combined. 13 | * 14 | * @namespace 15 | * @alias BlendEquation 16 | */ 17 | enum BlendEquation: UInt { 18 | /** 19 | * 0x8006. Pixel values are added componentwise. This is used in additive blending for translucency. 20 | * 21 | * @type {Number} 22 | * @constant 23 | */ 24 | case add // WebGL: FUNC_ADD 25 | 26 | /** 27 | * 0x800A. Pixel values are subtracted componentwise (source - destination). This is used in alpha blending for translucency. 28 | * 29 | * @type {Number} 30 | * @constant 31 | */ 32 | case subtract // WebGL: FUNC_SUBTRACT 33 | 34 | /** 35 | * 0x800B. Pixel values are subtracted componentwise (destination - source). 36 | * 37 | * @type {Number} 38 | * @constant 39 | */ 40 | case reverseSubtract // WebGL: FUNC_REVERSE_SUBTRACT 41 | 42 | case min 43 | case max 44 | 45 | // No min and max like in ColladaFX GLES2 profile 46 | 47 | func toMetal() -> MTLBlendOperation { 48 | return MTLBlendOperation(rawValue: self.rawValue)! 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /CesiumKit/Core/ClockRange.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ClockRange.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 11/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Constants used by {@link Clock#tick} to determine behavior 13 | * when {@link Clock#startTime} or {@link Clock#stopTime} is reached. 14 | * 15 | * @namespace 16 | * @alias ClockRange 17 | * 18 | * @see Clock 19 | * @see ClockStep 20 | */ 21 | public enum ClockRange { 22 | 23 | /** 24 | * {@link Clock#tick} will always advances the clock in its current direction. 25 | * 26 | * @type {Number} 27 | * @constant 28 | */ 29 | case unbounded 30 | 31 | /** 32 | * When {@link Clock#startTime} or {@link Clock#stopTime} is reached, 33 | * {@link Clock#tick} will not advance {@link Clock#currentTime} any further. 34 | * 35 | * @type {Number} 36 | * @constant 37 | */ 38 | case clamped 39 | 40 | /** 41 | * When {@link Clock#stopTime} is reached, {@link Clock#tick} will advance 42 | * {@link Clock#currentTime} to the opposite end of the interval. When 43 | * time is moving backwards, {@link Clock#tick} will not advance past 44 | * {@link Clock#startTime} 45 | * 46 | * @type {Number} 47 | * @constant 48 | */ 49 | case loopStop 50 | } 51 | -------------------------------------------------------------------------------- /CesiumKit/Scene/FrustumCommands.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FrustumCommands.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 16/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | 10 | /** 11 | * Defines a list of commands whose geometry are bound by near and far distances from the camera. 12 | * @alias FrustumCommands 13 | * @constructor 14 | * 15 | * @param {Number} [near=0.0] The lower bound or closest distance from the camera. 16 | * @param {Number} [far=0.0] The upper bound or farthest distance from the camera. 17 | * 18 | * @private 19 | */ 20 | class FrustumCommands { 21 | var near = 0.0 22 | var far = 0.0 23 | 24 | var commands = Array<[DrawCommand]>() 25 | 26 | let opaqueUniformBufferProvider: UniformBufferProvider 27 | let transparentUniformBufferProvider: UniformBufferProvider 28 | 29 | init (near: Double = 0.0, far: Double = 0.0, opaqueUniformBufferProvider: UniformBufferProvider, transparentUniformBufferProvider: UniformBufferProvider) { 30 | self.near = near 31 | self.far = far 32 | self.opaqueUniformBufferProvider = opaqueUniformBufferProvider 33 | self.transparentUniformBufferProvider = transparentUniformBufferProvider 34 | removeAll() 35 | } 36 | 37 | func removeAll() { 38 | commands = (0.. Intersect { 37 | var intersecting = false 38 | 39 | for plane in planes { 40 | let result = boundingVolume.intersectPlane(Plane(fromCartesian4: plane)) 41 | if result == .outside { 42 | return result 43 | } else if result == .intersecting { 44 | intersecting = true 45 | } 46 | } 47 | return intersecting ? Intersect.intersecting : Intersect.inside 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /CesiumKit/Core/QuadtreeNode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // QuadtreeNode.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 30/4/17. 6 | // Copyright © 2017 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class QuadtreeNode { 12 | 13 | let tilingScheme: TilingScheme 14 | 15 | let parent: QuadtreeNode? 16 | 17 | let level: Int 18 | 19 | let x: Int 20 | 21 | let y: Int 22 | 23 | let extent: Rectangle 24 | 25 | var rectangles = [RectangleWithLevel]() 26 | 27 | lazy var nw: QuadtreeNode = { 28 | return QuadtreeNode(tilingScheme: self.tilingScheme, parent: self, level: self.level + 1, x: self.x * 2, y: self.y * 2) 29 | }() 30 | 31 | lazy var ne: QuadtreeNode = { 32 | return QuadtreeNode(tilingScheme: self.tilingScheme, parent: self, level: self.level + 1, x: self.x * 2 + 1, y: self.y * 2) 33 | }() 34 | 35 | lazy var sw: QuadtreeNode = { 36 | return QuadtreeNode(tilingScheme: self.tilingScheme, parent: self, level: self.level + 1, x: self.x * 2, y: self.y * 2 + 1) 37 | }() 38 | 39 | lazy var se: QuadtreeNode = { 40 | return QuadtreeNode(tilingScheme: self.tilingScheme, parent: self, level: self.level + 1, x: self.x * 2 + 1, y: self.y * 2 + 1) 41 | }() 42 | 43 | init (tilingScheme: TilingScheme, parent: QuadtreeNode?, level: Int, x: Int, y: Int) { 44 | self.tilingScheme = tilingScheme 45 | self.parent = parent 46 | self.level = level 47 | self.x = x 48 | self.y = y 49 | 50 | extent = tilingScheme.tileXYToRectangle(x: x, y: y, level: level) 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /CesiumKitRunner/CesiumViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CesiumViewController.swift 3 | // CesiumKitRunner 4 | // 5 | // Created by Ryan Walklin on 10/12/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MetalKit 11 | 12 | class CesiumViewController: UIViewController { 13 | 14 | private var _cesiumKitController: CesiumKitController! = nil 15 | 16 | @IBOutlet var _metalView: MTKView! 17 | 18 | override func viewDidLoad() { 19 | 20 | super.viewDidLoad() 21 | 22 | view.contentScaleFactor = UIScreen.mainScreen().nativeScale 23 | 24 | _cesiumKitController = CesiumKitController(view: _metalView) 25 | _metalView.delegate = _cesiumKitController 26 | _cesiumKitController.startRendering() 27 | } 28 | 29 | /*override func touchesBegan(touches: Set, withEvent event: UIEvent) { 30 | // propagate to CesiumKit 31 | globe?.eventHandler.handleTouchStart(touches, screenScaleFactor: Double(view.contentScaleFactor)) 32 | } 33 | 34 | override func touchesMoved(touches: Set, withEvent event: UIEvent) { 35 | globe?.eventHandler.handleTouchMove(touches, screenScaleFactor: Double(view.contentScaleFactor)) 36 | } 37 | 38 | override func touchesEnded(touches: Set, withEvent event: UIEvent) { 39 | globe?.eventHandler.handleTouchEnd(touches) 40 | } 41 | 42 | override func touchesCancelled(touches: Set!, withEvent event: UIEvent!) { 43 | 44 | }*/ 45 | 46 | override func prefersStatusBarHidden() -> Bool { 47 | return true 48 | } 49 | } 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/IndexDatatype.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndexDatatype.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 20/09/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | /** 12 | * Constants for WebGL index datatypes. These corresponds to the 13 | * type parameter of {@link http://www.khronos.org/opengles/sdk/docs/man/xhtml/glDrawElements.xml|drawElements}. 14 | * 15 | * @namespace 16 | * @alias IndexDatatype 17 | */ 18 | enum IndexDatatype: UInt { 19 | case unsignedShort 20 | case unsignedInt 21 | 22 | var metalIndexType: MTLIndexType { 23 | return MTLIndexType(rawValue: self.rawValue)! 24 | } 25 | 26 | /** 27 | * Returns the size, in bytes, of the corresponding datatype. 28 | * 29 | * @param {IndexDatatype} indexDatatype The index datatype to get the size of. 30 | * @returns {Number} The size in bytes. 31 | * 32 | * @example 33 | * // Returns 2 34 | * var size = Cesium.IndexDatatype.getSizeInBytes(Cesium.IndexDatatype.UNSIGNED_SHORT); 35 | */ 36 | var elementSize: Int { 37 | switch (self) { 38 | case .unsignedShort: 39 | return MemoryLayout.size 40 | case .unsignedInt: 41 | return MemoryLayout.size 42 | } 43 | } 44 | 45 | static func createIntegerIndexArrayFromData (_ data: Data, numberOfVertices: Int, byteOffset: Int, length: Int) -> [Int] { 46 | if numberOfVertices > Math.SixtyFourKilobytes { 47 | return data.getUInt32Array(byteOffset, elementCount: length).map { Int($0) } 48 | } else { 49 | return data.getUInt16Array(byteOffset, elementCount: length).map { Int($0) } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /CesiumKit/Core/MapProjection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MapProjection.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 11/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol MapProjection { 12 | 13 | var ellipsoid: Ellipsoid { get } 14 | var semimajorAxis: Double { get } 15 | var oneOverSemimajorAxis: Double { get } 16 | 17 | init (ellipsoid: Ellipsoid) 18 | 19 | /** 20 | * Converts geodetic ellipsoid coordinates, in radians, to the equivalent 21 | * X, Y, Z coordinates expressed in meters and returned in a {@link Cartesian3}. The height 22 | * is copied unmodified to the Z coordinate. 23 | * 24 | * @memberof WebMercatorProjection 25 | * 26 | * @param {Cartographic} cartographic The cartographic coordinates in radians. 27 | * @param {Cartesian3} [result] The instance to which to copy the result, or undefined if a 28 | * new instance should be created. 29 | * @returns {Cartesian3} The equivalent web mercator X, Y, Z coordinates, in meters. 30 | */ 31 | func project(_ cartographic: Cartographic) -> Cartesian3 32 | 33 | /** 34 | * Converts X, Y coordinates, expressed in meters, to a {@link Cartographic} 35 | * containing geodetic ellipsoid coordinates. The Z coordinate is copied unmodified to the 36 | * height. 37 | * 38 | * @memberof WebMercatorProjection 39 | * 40 | * @param {Cartesian3} cartesian The web mercator coordinates in meters. 41 | * @param {Cartographic} [result] The instance to which to copy the result, or undefined if a 42 | * new instance should be created. 43 | * @returns {Cartographic} The equivalent cartographic coordinates. 44 | */ 45 | func unproject(_ cartesian: Cartesian3) -> Cartographic 46 | 47 | } 48 | -------------------------------------------------------------------------------- /CesiumKitRunner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /CesiumKit/Core/Ray.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Ray.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 24/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | /** 10 | * Represents a ray that extends infinitely from the provided origin in the provided direction. 11 | * @alias Ray 12 | * @constructor 13 | * 14 | * @param {Cartesian3} [origin=Cartesian3.ZERO] The origin of the ray. 15 | * @param {Cartesian3} [direction=Cartesian3.ZERO] The direction of the ray. 16 | */ 17 | 18 | struct Ray { 19 | /** 20 | * The origin of the ray. 21 | * @type {Cartesian3} 22 | * @default {@link Cartesian3.ZERO} 23 | */ 24 | var origin: Cartesian3 25 | 26 | /** 27 | * The direction of the ray. 28 | * @type {Cartesian3} 29 | */ 30 | var direction: Cartesian3 31 | 32 | init(origin: Cartesian3 = Cartesian3.zero, direction: Cartesian3 = Cartesian3.zero) { 33 | 34 | if direction == Cartesian3.zero { 35 | self.direction = direction.normalize() 36 | } 37 | else { 38 | self.direction = direction 39 | } 40 | self.origin = origin 41 | } 42 | 43 | /** 44 | * Computes the point along the ray given by r(t) = o + t*d, 45 | * where o is the origin of the ray and d is the direction. 46 | * 47 | * @param {Number} t A scalar value. 48 | * @param {Cartesian3} [result] The object in which the result will be stored. 49 | * @returns The modified result parameter, or a new instance if none was provided. 50 | * 51 | * @example 52 | * //Get the first intersection point of a ray and an ellipsoid. 53 | * var intersection = Cesium.IntersectionTests.rayEllipsoid(ray, ellipsoid); 54 | * var point = Ray.getPoint(ray, intersection.start); 55 | */ 56 | func getPoint(_ t: Double) -> Cartesian3 { 57 | return direction.multiplyBy(scalar: t).add(origin) 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /CesiumKitRunner OSX/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Test Toast. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | NSAppTransportSecurity 34 | 35 | NSExceptionDomains 36 | 37 | dev.virtualearth.net 38 | 39 | 40 | NSIncludesSubdomains 41 | 42 | 43 | NSExceptionAllowsInsecureHTTPLoads 44 | 45 | 46 | NSExceptionMinimumTLSVersion 47 | TLSv1.1 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/VertexDescriptor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VertexDescriptor.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 31/05/2015. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Metal 11 | 12 | let VertexDescriptorFirstBufferOffset = 3 // auto = 0, frustum = 1, manual = 2 13 | 14 | struct VertexAttributes { 15 | var buffer: Buffer? 16 | let bufferIndex: Int 17 | let index: Int 18 | let format: VertexType 19 | let offset: Int 20 | let size: Int 21 | let normalize: Bool 22 | } 23 | 24 | class VertexDescriptor { 25 | 26 | let metalDescriptor: MTLVertexDescriptor 27 | 28 | init (attributes: [VertexAttributes]) { 29 | 30 | metalDescriptor = MTLVertexDescriptor() 31 | 32 | let bufferIndex = attributes.first?.bufferIndex ?? 1 33 | // Set up layout descriptor 34 | metalDescriptor.layouts[bufferIndex].stepFunction = .perVertex 35 | metalDescriptor.layouts[bufferIndex].stepRate = 1 36 | 37 | 38 | // Verify all attribute names are unique 39 | var uniqueIndices = [Bool](repeating: false, count: attributes.count) 40 | for (index, va) in attributes.enumerated() { 41 | if uniqueIndices[index] { 42 | assertionFailure("Index \(index) is used by more than one attribute.") 43 | } 44 | uniqueIndices[index] = true 45 | addAttribute(va) 46 | } 47 | } 48 | 49 | fileprivate func addAttribute(_ attribute: VertexAttributes) { 50 | let index = attribute.index 51 | metalDescriptor.attributes[index].bufferIndex = attribute.bufferIndex 52 | metalDescriptor.attributes[index].format = attribute.format.metalVertexFormat 53 | metalDescriptor.attributes[index].offset = attribute.offset 54 | 55 | metalDescriptor.layouts[attribute.bufferIndex].stride += attribute.size 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/Sampler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Sampler.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 16/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | class Sampler { 12 | let state: MTLSamplerState 13 | 14 | init? (context: Context, wrapS: TextureWrap = .clampToEdge, wrapT: TextureWrap = .clampToEdge, minFilter: TextureMinMagFilter = .linear, magFilter: TextureMinMagFilter = .linear, mipMagFilter: TextureMipFilter = .notMipmapped, maximumAnisotropy: Int = 1) { 15 | 16 | let descriptor = MTLSamplerDescriptor() 17 | descriptor.minFilter = minFilter.toMetal() 18 | descriptor.magFilter = magFilter.toMetal() 19 | descriptor.mipFilter = mipMagFilter.toMetal() 20 | descriptor.sAddressMode = wrapS.toMetal() 21 | descriptor.tAddressMode = wrapT.toMetal() 22 | descriptor.maxAnisotropy = maximumAnisotropy 23 | 24 | guard let state = context.createSamplerState(descriptor) else { 25 | logPrint(.error, "cannot create sampler state") 26 | return nil 27 | } 28 | self.state = state 29 | } 30 | } 31 | 32 | enum TextureWrap: UInt { 33 | 34 | case clampToEdge 35 | case mirrorClampToEdge 36 | case `repeat` 37 | case mirrorRepeat 38 | case clampToZero 39 | 40 | func toMetal() -> MTLSamplerAddressMode { 41 | return MTLSamplerAddressMode(rawValue: self.rawValue)! 42 | } 43 | } 44 | 45 | enum TextureMinMagFilter: UInt { 46 | 47 | case nearest 48 | case linear 49 | 50 | func toMetal() -> MTLSamplerMinMagFilter { 51 | return MTLSamplerMinMagFilter(rawValue: self.rawValue)! 52 | } 53 | } 54 | 55 | enum TextureMipFilter: UInt { 56 | 57 | case notMipmapped 58 | case nearest 59 | case linear 60 | 61 | func toMetal() -> MTLSamplerMipFilter { 62 | return MTLSamplerMipFilter(rawValue: self.rawValue)! 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /CesiumKitRunner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarHidden 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | UIInterfaceOrientationPortraitUpsideDown 40 | UIInterfaceOrientationPortrait 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationLandscapeRight 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationPortrait 48 | 49 | NSAppTransportSecurity 50 | 51 | NSAllowsArbitraryLoads 52 | 53 | NSExceptionMinimumTLSVersion 54 | TLSv1.0 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /CesiumKit/Scene/ImageryLayerUniformMap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageryLayerUniformMap.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/02/15. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import simd 11 | 12 | private struct ImageryLayerUniformStruct: UniformStruct { 13 | var viewportOrthographic = float4x4() 14 | var textureDimensions = float2() 15 | } 16 | 17 | class ImageryLayerUniformMap: NativeUniformMap { 18 | 19 | var textureDimensions: Cartesian2 { 20 | get { 21 | return Cartesian2(simd: simd_double(_uniformStruct.textureDimensions)) 22 | } 23 | set { 24 | _uniformStruct.textureDimensions = newValue.floatRepresentation 25 | } 26 | } 27 | 28 | var viewportOrthographic: Matrix4 { 29 | get { 30 | return Matrix4(simd: double4x4([ 31 | simd_double(_uniformStruct.viewportOrthographic[0]), 32 | simd_double(_uniformStruct.viewportOrthographic[1]), 33 | simd_double(_uniformStruct.viewportOrthographic[2]), 34 | simd_double(_uniformStruct.viewportOrthographic[3]) 35 | ])) 36 | } 37 | set { 38 | _uniformStruct.viewportOrthographic = newValue.floatRepresentation 39 | } 40 | } 41 | 42 | var texture : Texture? 43 | 44 | var uniformBufferProvider: UniformBufferProvider! = nil 45 | 46 | let uniformDescriptors: [UniformDescriptor] = [ 47 | UniformDescriptor(name: "u_viewportOrthographic", type: .floatMatrix4, count: 1), 48 | UniformDescriptor(name: "u_textureDimensions", type: .floatVec2, count: 1) 49 | ] 50 | 51 | fileprivate var _uniformStruct = ImageryLayerUniformStruct() 52 | 53 | lazy var uniformUpdateBlock: UniformUpdateBlock = { buffer in 54 | buffer.write(from: &self._uniformStruct, length: MemoryLayout.size) 55 | return [self.texture!] 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CesiumKit 2 | ========= 3 | 4 | iOS/OS X port of the [Cesium](http://cesiumjs.org) WebGL virtual globe project. 5 | 6 | Status 7 | ------ 8 | OS X and iOS Metal renderers are largely complete, with support for FXAA, terrain, lighting, water effects and text rendering. 9 | The only currently-implemented image providers are the Bing Maps provider (with Web Mercator reprojection) and the TileCoordinate provider for debugging, however these can be layered. 10 | Current efforts are focused on implementing camera controls and touch-based inputs. 11 | I'm eventually hoping for near complete globe support with CZML interoperability with cesium.js. 12 | Community contributions and feedback are welcome. 13 | 14 | ![](https://github.com/tokyovigilante/CesiumKit/blob/master/CurrentStatus.jpg) 15 | 16 | Testing 17 | ------- 18 | Requires Swift 3.0/Xcode 8.0 GM beta and an iOS 9 device with a minimum A7 processor, or OS X 10.11 with a compatible GPU. 19 | 20 | Run the getDependencies.sh script to pull down PMJSON, glsl-optimizer and Alamofire from Github. Then build and run either the iOS or OS X test runner target. 21 | At the moment the only external API are global object creation and render calls and minimal camera control. I'm hoping to keep things simple for implementation, but am looking into touch-based controls as a high priority now. 22 | 23 | Licence 24 | ------- 25 | 26 | [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). 27 | 28 | Credits 29 | ------- 30 | 31 | CesiumKit is based on the [Cesium WebGL Virtual Globe and Map Engine](http://cesiumjs.org) by AGI. 32 | GLSL->Metal shader real-time translation performed by the [glsl-optimizer library](https://github.com/aras-p/glsl-optimizer) by Brian Paul, Aras Pranckevičius and Unity Technologies. 33 | JSON parsing performed using the [PMJSON library](https://github.com/postmates/PMJSON) by Postmates. 34 | 35 | Feedback 36 | -------- 37 | [ryan@testtoast.com](mailto:ryan@testtoast.com) 38 | 39 | ![](https://github.com/tokyovigilante/CesiumKit/blob/master/Everest.jpg) 40 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/DepthTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DepthTest.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 17/09/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | /** 12 | * Determines the function used to compare two depths for the depth test. 13 | * 14 | * @namespace 15 | * @alias DepthFunction 16 | */ 17 | enum DepthFunction: UInt { 18 | /** 19 | * 0x200. The depth test never passes. 20 | * 21 | * @type {Number} 22 | * @constant 23 | */ 24 | case never, 25 | 26 | /** 27 | * 0x201. The depth test passes if the incoming depth is less than the stored depth. 28 | * 29 | * @type {Number} 30 | * @constant 31 | */ 32 | less, 33 | 34 | /** 35 | * 0x202. The depth test passes if the incoming depth is equal to the stored depth. 36 | * 37 | * @type {Number} 38 | * @constant 39 | */ 40 | equal, 41 | 42 | /** 43 | * 0x203. The depth test passes if the incoming depth is less than or equal to the stored depth. 44 | * 45 | * @type {Number} 46 | * @constant 47 | */ 48 | lessOrEqual, // LEQUAL 49 | 50 | /** 51 | * 0x204. The depth test passes if the incoming depth is greater than the stored depth. 52 | * 53 | * @type {Number} 54 | * @constant 55 | */ 56 | greater, 57 | 58 | /** 59 | * 0x0205. The depth test passes if the incoming depth is not equal to the stored depth. 60 | * 61 | * @type {Number} 62 | * @constant 63 | */ 64 | notEqual, // NOTEQUAL 65 | 66 | /** 67 | * 0x206. The depth test passes if the incoming depth is greater than or equal to the stored depth. 68 | * 69 | * @type {Number} 70 | * @constant 71 | */ 72 | greaterOrEqual, // GEQUAL 73 | 74 | /** 75 | * 0x207. The depth test always passes. 76 | * 77 | * @type {Number} 78 | * @constant 79 | */ 80 | always 81 | 82 | func toMetal() -> MTLCompareFunction { 83 | return MTLCompareFunction(rawValue: self.rawValue)! 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /CesiumKit/Shaders/TextRenderer.metal: -------------------------------------------------------------------------------- 1 | // 2 | // TextRenderer.metal 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 26/02/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | 12 | struct Vertex 13 | { 14 | float4 position [[ attribute(0) ]]; 15 | float2 texCoords [[ attribute(1) ]]; 16 | }; 17 | 18 | struct TransformedVertex 19 | { 20 | float4 position [[ position ]]; 21 | float2 texCoords; 22 | }; 23 | 24 | struct Uniforms 25 | { 26 | float4x4 u_modelMatrix; 27 | float4x4 u_viewProjectionMatrix; 28 | float4 u_foregroundColor; 29 | }; 30 | 31 | vertex TransformedVertex text_vertex_shade(Vertex inVert [[stage_in]], constant Uniforms &uniforms [[buffer(2)]]) 32 | { 33 | TransformedVertex outVert; 34 | outVert.position = uniforms.u_viewProjectionMatrix * uniforms.u_modelMatrix * float4(inVert.position); 35 | outVert.texCoords = inVert.texCoords; 36 | return outVert; 37 | } 38 | 39 | fragment half4 text_fragment_shade(TransformedVertex vert [[stage_in]], constant Uniforms &uniforms [[buffer(2)]], sampler samplr [[sampler(0)]], texture2d texture [[texture(0)]]) 40 | { 41 | float4 color = uniforms.u_foregroundColor; 42 | // Outline of glyph is the isocontour with value 50% 43 | float edgeDistance = 0.5; 44 | // Sample the signed-distance field to find distance from this fragment to the glyph outline 45 | float sampleDistance = texture.sample(samplr, vert.texCoords).r; 46 | // Use local automatic gradients to find anti-aliased anisotropic edge width, cf. Gustavson 2012 47 | float edgeWidth = 0.75 * length(float2(dfdx(sampleDistance), dfdy(sampleDistance))); 48 | //float edgeWidth = fwidth(sampleDistance); 49 | // Smooth the glyph edge by interpolating across the boundary in a band with the width determined above 50 | float insideness = smoothstep(edgeDistance - edgeWidth, edgeDistance + edgeWidth, sampleDistance); 51 | return half4(color.r, color.g, color.b, insideness); 52 | //return half4(color.r, color.g, color.b, 1.0); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /CesiumKit/Core/PixelFormat.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PixelFormat.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 20/07/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import OpenGLES 10 | 11 | enum PixelFormat: Int { 12 | /** 13 | * 0x1902. A pixel format containing a depth value. 14 | * 15 | * @type {Number} 16 | * @constant 17 | */ 18 | case DepthComponent = 0x1902, 19 | 20 | /** 21 | * 0x84F9. A pixel format containing a depth and stencil value, most often used with {@link PixelDatatype.UNSIGNED_INT_24_8_WEBGL}. 22 | * 23 | * @type {Number} 24 | * @constant 25 | */ 26 | DepthStencil = 0x84F9, 27 | 28 | /** 29 | * 0x1906. A pixel format containing an alpha channel. 30 | * 31 | * @type {Number} 32 | * @constant 33 | */ 34 | Alpha = 0x1906, 35 | 36 | /** 37 | * 0x1907. A pixel format containing red, green, and blue channels. 38 | * 39 | * @type {Number} 40 | * @constant 41 | */ 42 | RGB = 0x1907, 43 | 44 | /** 45 | * 0x1908. A pixel format containing red, green, blue, and alpha channels. 46 | * 47 | * @type {Number} 48 | * @constant 49 | */ 50 | RGBA = 0x1908, 51 | 52 | /** 53 | * 0x1909. A pixel format containing a luminance (intensity) channel. 54 | * 55 | * @type {Number} 56 | * @constant 57 | */ 58 | Luminance = 0x1909, 59 | 60 | /** 61 | * 0x190A. A pixel format containing luminance (intensity) and alpha channels. 62 | * 63 | * @type {Number} 64 | * @constant 65 | * @default 0x190A 66 | */ 67 | LuminanceAlpha = 0x190A 68 | 69 | func isColorFormat() -> Bool { 70 | return self == PixelFormat.Alpha || 71 | self == PixelFormat.RGB || 72 | self == PixelFormat.RGBA || 73 | self == PixelFormat.Luminance || 74 | self == PixelFormat.LuminanceAlpha 75 | } 76 | 77 | func isDepthFormat() -> Bool { 78 | return self == PixelFormat.DepthComponent || 79 | self == PixelFormat.DepthStencil 80 | } 81 | } -------------------------------------------------------------------------------- /CesiumKit/Renderer/PassState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PassState.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 15/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | /** 12 | * The state for a particular rendering pass. This is used to supplement the state 13 | * in a command being executed. 14 | * 15 | * @private 16 | */ 17 | class PassState { 18 | /** 19 | * The context used to execute commands for this pass. 20 | * 21 | * @type {Context} 22 | */ 23 | weak var context: Context! = nil 24 | 25 | /** 26 | * The framebuffer to render to. This framebuffer is used unless a {@link DrawCommand} 27 | * or {@link ClearCommand} explicitly define a framebuffer, which is used for off-screen 28 | * rendering. 29 | * 30 | * @type {Framebuffer} 31 | * @default undefined 32 | */ 33 | var framebuffer: Framebuffer! = nil 34 | 35 | /** 36 | * When defined, this overrides the blending property of a {@link DrawCommand}'s render state. 37 | * This is used to, for example, to allow the renderer to turn off blending during the picking pass. 38 | *

39 | * When this is undefined, the {@link DrawCommand}'s property is used. 40 | *

41 | * 42 | * @type {Boolean} 43 | * @default undefined 44 | */ 45 | var blendingEnabled: Bool? = nil 46 | 47 | /** 48 | * When defined, this overrides the scissor test property of a {@link DrawCommand}'s render state. 49 | * This is used to, for example, to allow the renderer to scissor out the pick region during the picking pass. 50 | *

51 | * When this is undefined, the {@link DrawCommand}'s property is used. 52 | *

53 | * 54 | * @type {Object} 55 | * @default undefined 56 | */ 57 | var scissorTest: RenderState.ScissorTest? = nil 58 | 59 | /** 60 | * The viewport used when one is not defined by a {@link DrawCommand}'s render state. 61 | * @type {BoundingRectangle} 62 | * @default undefined 63 | */ 64 | var viewport: Cartesian4? = nil 65 | 66 | } 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/UniformMap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UniformMap.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 27/02/15. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | protocol UniformStruct { 10 | 11 | } 12 | 13 | typealias UniformUpdateBlock = ((_ buffer: Buffer) -> [Texture]) 14 | 15 | typealias UniformMapDeallocBlock = (UniformBufferProvider) -> Void 16 | 17 | struct UniformDescriptor { 18 | let name: String 19 | let type: UniformDataType 20 | let count: Int 21 | 22 | func declaration () -> String { 23 | var declaration = "\(type.metalDeclaration) \(name)" 24 | 25 | if count == 1 { 26 | declaration += ";" 27 | } else { 28 | declaration += "[\(count)];" 29 | } 30 | 31 | return declaration 32 | } 33 | } 34 | 35 | protocol UniformMap: class { 36 | 37 | var uniformBufferProvider: UniformBufferProvider! { get set } 38 | 39 | var uniformDescriptors: [UniformDescriptor] { get } 40 | } 41 | 42 | protocol NativeUniformMap: class, UniformMap { 43 | 44 | var uniformUpdateBlock: UniformUpdateBlock { get } 45 | 46 | func generateMetalUniformStruct () -> String 47 | } 48 | 49 | extension NativeUniformMap { 50 | 51 | func generateMetalUniformStruct () -> String { 52 | 53 | let prefix = "struct xlatMtlShaderUniform {\n" 54 | let suffix = "};\n" 55 | let uniformDefinitions = uniformDescriptors.reduce(prefix) { $0 + " \($1.declaration())\n" } 56 | 57 | return uniformDefinitions + suffix 58 | } 59 | } 60 | 61 | protocol LegacyUniformMap: class, UniformMap { 62 | 63 | var uniforms: [String: UniformFunc] { get } 64 | 65 | func indexForUniform(_ name: String) -> UniformIndex? 66 | 67 | func uniform(_ index: UniformIndex) -> UniformFunc 68 | 69 | func textureForUniform (_ uniform: UniformSampler) -> Texture? 70 | } 71 | 72 | extension LegacyUniformMap { 73 | 74 | func indexForUniform(_ name: String) -> UniformIndex? { 75 | return uniforms.index(forKey: name) 76 | } 77 | 78 | func uniform(_ index: UniformIndex) -> UniformFunc { 79 | return uniforms[index].1 80 | } 81 | 82 | func textureForUniform (_ uniform: UniformSampler) -> Texture? { 83 | return nil 84 | } 85 | 86 | } 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /CesiumKit/Platform/String.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/11/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum ObjectSourceReferenceType { 12 | case bundleResource 13 | case networkURL 14 | case filePath 15 | } 16 | 17 | extension String { 18 | subscript (r: Range) -> String { 19 | get { 20 | let startIndex = self.characters.index(self.startIndex, offsetBy: r.lowerBound) 21 | let endIndex = self.characters.index(self.startIndex, offsetBy: r.upperBound - r.lowerBound) 22 | 23 | return String(self[startIndex.. String { 28 | return self.replacingOccurrences(of: existingString, with: newString, options: .literal, range: nil) 29 | } 30 | 31 | func indexOf(_ findStr:String, startIndex: String.Index? = nil) -> String.Index? { 32 | return self.range(of: findStr, options: [], range: nil, locale: nil)?.lowerBound 33 | } 34 | 35 | } 36 | // FIXME: move to cubemap 37 | extension String { 38 | var referenceType: ObjectSourceReferenceType { 39 | if self.hasPrefix("/") { 40 | return .filePath 41 | } else if self.hasPrefix("http") { 42 | return .networkURL 43 | } 44 | return .bundleResource 45 | } 46 | 47 | 48 | func urlForSource () -> URL? { 49 | switch self.referenceType { 50 | case .bundleResource: 51 | let bundle = Bundle(identifier: "com.testtoast.CesiumKit") ?? Bundle.main 52 | return bundle.url(forResource: (self as NSString).deletingPathExtension, withExtension: (self as NSString).pathExtension) 53 | case .filePath: 54 | return URL(fileURLWithPath: self, isDirectory: false) 55 | case .networkURL: 56 | return URL(string: self) 57 | } 58 | } 59 | 60 | func loadImageForCubeMapSource () -> CGImage? { 61 | 62 | guard let sourceURL = urlForSource() else { 63 | return nil 64 | } 65 | do { 66 | let data = try Data(contentsOf: sourceURL, options: []) 67 | return CGImage.from(data) 68 | } catch { 69 | return nil 70 | } 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /CesiumKit/Core/HeadingPitchRange.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeadingPitchRange.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 15/03/15. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Defines a heading angle, pitch angle an range in a local frame. 13 | * Heading is the rotation from the local north direction where a positive angle is increasing eastward. 14 | * Pitch is the rotation from the local xy-plane. Positive pitch angles are above the plane. Negative pitch 15 | * angles are below the plane. Range is the distance from the center of the frame. 16 | * @alias HeadingPitchRange 17 | * @constructor 18 | * 19 | * @param {Number} [heading=0.0] The heading angle in radians. 20 | * @param {Number} [pitch=0.0] The pitch angle in radians. 21 | * @param {Number} [range=0.0] The distance from the center in meters. 22 | */ 23 | 24 | public struct HeadingPitchRange { 25 | 26 | /** 27 | * Heading is the rotation from the local north direction where a positive angle is increasing eastward. 28 | * @type {Number} 29 | */ 30 | public var heading: Double = 0.0 31 | 32 | /** 33 | * Pitch is the rotation from the local xy-plane. Positive pitch angles 34 | * are above the plane. Negative pitch angles are below the plane. 35 | * @type {Number} 36 | */ 37 | public var pitch: Double = 0.0 38 | 39 | /** 40 | * Range is the distance from the center of the local frame. 41 | * @type {Number} 42 | */ 43 | public var range: Double = 0.0 44 | 45 | public init (heading: Double = 0.0, pitch: Double = 0.0, range: Double = 0.0) { 46 | self.heading = heading 47 | self.pitch = pitch 48 | self.range = range 49 | } 50 | } 51 | 52 | extension HeadingPitchRange: Offset { 53 | 54 | public var offset: Cartesian3 { 55 | let pitch = Math.clamp(self.pitch, min: -.pi/2, max: .pi/2) 56 | let heading = Math.zeroToTwoPi(self.heading) - .pi/2 57 | 58 | let pitchQuat = Quaternion(axis: Cartesian3.unitY, angle: -pitch) 59 | let headingQuat = Quaternion(axis: Cartesian3.unitZ, angle: -heading) 60 | let rotQuat = headingQuat.multiply(pitchQuat) 61 | let rotMatrix = Matrix3(quaternion: rotQuat) 62 | 63 | let offset = rotMatrix 64 | .multiplyByVector(Cartesian3.unitX) 65 | .negate() 66 | .multiplyBy(scalar: range) 67 | return offset 68 | } 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /CesiumKit/Platform/Crypto.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Crypto.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 13/04/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CommonCrypto 11 | 12 | public struct HMAC { 13 | 14 | static func hash(_ inp: String, algo: HMACAlgo) -> String { 15 | if let stringData = inp.data(using: String.Encoding.utf8, allowLossyConversion: false) { 16 | return hexStringFromBuffer(digest(stringData, algo: algo)) 17 | } 18 | return "" 19 | } 20 | 21 | fileprivate static func digest(_ input: Data, algo: HMACAlgo) -> [UInt8] { 22 | let digestLength = algo.digestLength() 23 | var hash = [UInt8](repeating: 0, count: digestLength) 24 | input.withUnsafeBytes { (pointer: UnsafePointer) in 25 | switch algo { 26 | case .md5: 27 | CC_MD5(pointer, UInt32(input.count), &hash) 28 | break 29 | case .sha1: 30 | CC_SHA1(pointer, UInt32(input.count), &hash) 31 | break 32 | case .sha224: 33 | CC_SHA224(pointer, UInt32(input.count), &hash) 34 | break 35 | case .sha256: 36 | CC_SHA256(pointer, UInt32(input.count), &hash) 37 | break 38 | case .sha384: 39 | CC_SHA384(pointer, UInt32(input.count), &hash) 40 | break 41 | case .sha512: 42 | CC_SHA512(pointer, UInt32(input.count), &hash) 43 | break 44 | } 45 | } 46 | return hash 47 | } 48 | 49 | fileprivate static func hexStringFromBuffer(_ input: [UInt8]) -> String { 50 | return input.reduce("") { $0 + String(format:"%02x", $1) } 51 | } 52 | } 53 | 54 | enum HMACAlgo { 55 | case md5, sha1, sha224, sha256, sha384, sha512 56 | 57 | func digestLength() -> Int { 58 | var result: CInt = 0 59 | switch self { 60 | case .md5: 61 | result = CC_MD5_DIGEST_LENGTH 62 | case .sha1: 63 | result = CC_SHA1_DIGEST_LENGTH 64 | case .sha224: 65 | result = CC_SHA224_DIGEST_LENGTH 66 | case .sha256: 67 | result = CC_SHA256_DIGEST_LENGTH 68 | case .sha384: 69 | result = CC_SHA384_DIGEST_LENGTH 70 | case .sha512: 71 | result = CC_SHA512_DIGEST_LENGTH 72 | } 73 | return Int(result) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /CesiumKitRunner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // AppDelegate.swift 4 | // CesiumKitRunner 5 | // 6 | // Created by Ryan Walklin on 10/12/14. 7 | // Copyright (c) 2014 Test Toast. All rights reserved. 8 | // 9 | 10 | import UIKit 11 | import CesiumKit 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | var window: UIWindow? 17 | 18 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | //if let view = self.window?.rootViewController?.view as? MetalView { 26 | // view.render = false 27 | //} 28 | } 29 | 30 | func applicationDidEnterBackground(application: UIApplication) { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | func applicationWillEnterForeground(application: UIApplication) { 36 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 37 | } 38 | 39 | func applicationDidBecomeActive(application: UIApplication) { 40 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 41 | //if let view = self.window?.rootViewController?.view as? MetalView { 42 | // view.render = true 43 | //} 44 | } 45 | 46 | func applicationWillTerminate(application: UIApplication) { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /CesiumKit/Core/Credit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Credit.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 12/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | private var _nextCreditId = 0 10 | private var _creditToId = [String: Int]() 11 | 12 | /** 13 | * A credit contains data pertaining to how to display attributions/credits for certain content on the screen. 14 | * 15 | * @param {String} [text] The text to be displayed on the screen if no imageUrl is specified. 16 | * @param {String} [imageUrl] The source location for an image 17 | * @param {String} [link] A URL location for which the credit will be hyperlinked 18 | * 19 | * @alias Credit 20 | * @constructor 21 | * 22 | * @example 23 | * //Create a credit with a tooltip, image and link 24 | * var credit = new Cesium.Credit('Cesium', '/images/cesium_logo.png', 'http://cesiumjs.org/'); 25 | */ 26 | public struct Credit: Equatable { 27 | 28 | public let text: String? 29 | 30 | public let imageUrl: String? 31 | 32 | public let link: String? 33 | 34 | var hasText: Bool { 35 | return text != nil 36 | } 37 | 38 | var hasImage: Bool { 39 | return imageUrl != nil 40 | } 41 | 42 | var hasLink: Bool { 43 | return link != nil 44 | } 45 | 46 | /** 47 | * @memberof Credit.prototype 48 | * @type {Number} 49 | * 50 | * @private 51 | */ 52 | let id: Int 53 | 54 | init (text: String? = nil, imageUrl: String? = nil, link: String? = nil) { 55 | assert(text != nil || imageUrl != nil || link != nil, "text, imageUrl or link is required") 56 | 57 | if (text == nil && imageUrl == nil) { 58 | self.text = link 59 | } else { 60 | self.text = text 61 | } 62 | self.imageUrl = imageUrl 63 | self.link = link 64 | 65 | // Credits are immutable so generate an id to use to optimize equal() 66 | let key = "[\(text ?? ""):\(imageUrl ?? ""):\(link ?? "")]" 67 | if let creditToId = _creditToId[key] { 68 | id = creditToId 69 | } else { 70 | id = _nextCreditId 71 | _creditToId[key] = id 72 | _nextCreditId += 1 73 | } 74 | } 75 | } 76 | /** 77 | * Returns true if the credits are equal 78 | * 79 | * @param {Credit} left The first credit 80 | * @param {Credit} left The second credit 81 | * @returns {Boolean} true if left and right are equal, false otherwise. 82 | */ 83 | 84 | public func == (left: Credit, right: Credit) -> Bool { 85 | return left.id == right.id 86 | } 87 | -------------------------------------------------------------------------------- /CesiumKit/Scene/MaterialType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MaterialType.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 31/01/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import simd 11 | 12 | public protocol MaterialType { 13 | var name: String { get } 14 | var fabric: FabricDescription { get } 15 | var source: String? { get } 16 | var components: [String: String] { get } 17 | var translucent: (Material) -> Bool { get } 18 | } 19 | 20 | public struct ColorMaterialType: MaterialType { 21 | 22 | public let name = "Color" 23 | 24 | public var fabric: FabricDescription 25 | 26 | public var source: String? = nil 27 | 28 | public let components = [ 29 | "diffuse": "u_color.rgb", 30 | "alpha": "u_color.a" 31 | ] 32 | 33 | public let translucent = { (material: Material) in 34 | return (material.type.fabric as! ColorFabricDescription).color.alpha < 1.0 35 | } 36 | 37 | public init (fabric: ColorFabricDescription = ColorFabricDescription(), source: String? = nil) { 38 | self.fabric = fabric 39 | self.source = source 40 | } 41 | } 42 | 43 | open class FabricDescription { 44 | var uniformMap: LegacyUniformMap! { 45 | assertionFailure("invalid base class") 46 | return nil 47 | } 48 | } 49 | 50 | open class ColorFabricDescription: FabricDescription { 51 | 52 | open var color: Color { 53 | get { 54 | return _uniformMap.color 55 | } 56 | set { 57 | _uniformMap.color = newValue 58 | } 59 | } 60 | 61 | override var uniformMap: LegacyUniformMap { 62 | return _uniformMap 63 | } 64 | 65 | fileprivate let _uniformMap = ColorFabricUniformMap() 66 | 67 | public override init () { 68 | 69 | } 70 | } 71 | 72 | class ColorFabricUniformMap: LegacyUniformMap { 73 | 74 | var color = Color() 75 | 76 | var uniformBufferProvider: UniformBufferProvider! = nil 77 | 78 | let uniforms: [String: UniformFunc] = [ 79 | "u_color": { map, buffer, offset in 80 | let simd = (map as! ColorFabricUniformMap).color.floatRepresentation 81 | buffer.write(from: [simd], length: MemoryLayout.size(ofValue: simd)) 82 | } 83 | ] 84 | 85 | let uniformDescriptors = [ 86 | UniformDescriptor(name: "u_color", type: .floatVec4, count: 1) 87 | ] 88 | } 89 | 90 | 91 | 92 | 93 | 94 | open class ImageFabricDescription: FabricDescription { 95 | 96 | //var uniformMap: UniformMap = NullUniformMap() 97 | 98 | //public var uniforms: [String: UniformFunc] 99 | 100 | //public var uniformTypes: [String : UniformDataType] 101 | 102 | } 103 | -------------------------------------------------------------------------------- /CesiumKit/Core/Queue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Queue.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 27/09/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | 10 | /** 11 | * A queue that can enqueue items at the end, and dequeue items from the front. 12 | * 13 | * @alias Queue 14 | * @constructor 15 | */ 16 | class Queue { 17 | fileprivate var _array = [T]() 18 | 19 | /** 20 | * Enqueues the specified item. 21 | * 22 | * @param {Object} item The item to enqueue. 23 | */ 24 | func enqueue(_ item: T) { 25 | _array.append(item) 26 | } 27 | 28 | /** 29 | * Dequeues an item. Returns undefined if the queue is empty. 30 | */ 31 | func dequeue() -> T? { 32 | if _array.count == 0 { 33 | return nil 34 | } 35 | return _array.remove(at: 0) 36 | } 37 | 38 | var head: T? { 39 | get { 40 | if _array.count == 0 { 41 | return nil 42 | } 43 | return _array[0] 44 | } 45 | } 46 | 47 | var tail: T? { 48 | get { 49 | return _array.last 50 | } 51 | } 52 | 53 | var count: Int { 54 | get { 55 | return _array.count 56 | } 57 | } 58 | 59 | /** 60 | * Check whether this queue contains the specified item. 61 | * 62 | * @param {Object} item the item to search for. 63 | */ 64 | func contains(_ item: T) -> Bool { 65 | for object in _array { 66 | if object == item { 67 | return true 68 | } 69 | } 70 | return false 71 | } 72 | 73 | /** 74 | * Remove all items from the queue. 75 | */ 76 | func clear() { 77 | _array.removeAll() 78 | } 79 | 80 | /* 81 | /** 82 | * Sort the items in the queue in-place. 83 | * 84 | * @param {Queue~Comparator} compareFunction A function that defines the sort order. 85 | */ 86 | Queue.prototype.sort = function(compareFunction) { 87 | if (this._offset > 0) { 88 | //compact array 89 | this._array = this._array.slice(this._offset); 90 | this._offset = 0; 91 | } 92 | 93 | this._array.sort(compareFunction); 94 | }; 95 | */ 96 | /** 97 | * A function used to compare two items while sorting a queue. 98 | * @callback Queue~Comparator 99 | * 100 | * @param {Object} a An item in the array. 101 | * @param {Object} b An item in the array. 102 | * @returns {Number} Returns a negative value if a is less than b, 103 | * a positive value if a is greater than b, or 104 | * 0 if a is equal to b. 105 | * 106 | * @example 107 | * function compareNumbers(a, b) { 108 | * return a - b; 109 | * } 110 | */ 111 | 112 | } 113 | -------------------------------------------------------------------------------- /CesiumKit/Core/TimeConstants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimeConstants.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 10/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Constants for time conversions like those done by {@link JulianDate}. 13 | * 14 | * @namespace 15 | * @alias TimeConstants 16 | * 17 | * @see JulianDate 18 | * 19 | * @private 20 | */ 21 | struct TimeConstants { 22 | 23 | /** 24 | * The number of seconds in one millisecond: 0.001 25 | * @type {Number} 26 | * @constant 27 | */ 28 | static let SecondsPerMillisecond: Double = 0.001 29 | 30 | /** 31 | * The number of seconds in one millisecond: 0.001 32 | * @type {Number} 33 | * @constant 34 | */ 35 | static let SecondsPerNanosecond: Double = 0.000000001 36 | 37 | /** 38 | * The number of seconds in one minute: 60. 39 | * @type {Number} 40 | * @constant 41 | */ 42 | static let SecondsPerMinute: Double = 60.0 43 | 44 | /** 45 | * The number of minutes in one hour: 60. 46 | * @type {Number} 47 | * @constant 48 | */ 49 | static let MinutesPerHour: Double = 60.0 50 | 51 | /** 52 | * The number of hours in one day: 24. 53 | * @type {Number} 54 | * @constant 55 | */ 56 | static let HoursPerDay: Double = 24.0 57 | 58 | /** 59 | * The number of seconds in one hour: 3600. 60 | * @type {Number} 61 | * @constant 62 | */ 63 | static let SecondsPerHour: Double = 3600.0 64 | 65 | /** 66 | * The number of minutes in one day: 1440. 67 | * @type {Number} 68 | * @constant 69 | */ 70 | static let MinutesPerDay: Double = 1440.0 71 | 72 | /** 73 | * The number of seconds in one day, ignoring leap seconds: 86400. 74 | * @type {Number} 75 | * @constant 76 | */ 77 | static let SecondsPerDay: Double = 86400.0 78 | 79 | /** 80 | * The number of days in one Julian century: 36525. 81 | * @type {Number} 82 | * @constant 83 | */ 84 | static let DaysPerJulianCentury: Double = 36525.0 85 | 86 | /** 87 | * One trillionth of a second. 88 | * @type {Number} 89 | * @constant 90 | */ 91 | static let PicoSecond: Double = 0.000000001 92 | 93 | /** 94 | * The number of days to subtract from a Julian date to determine the 95 | * modified Julian date, which gives the number of days since midnight 96 | * on November 17, 1858. 97 | * @type {Number} 98 | * @constant 99 | */ 100 | static let ModifiedJulianDateDifference: Double = 2400000.5 101 | 102 | /** 103 | The number of days between the Julian epoch (4713-1-1 BCE) since the OS X reference date (2001-01-01T00:00Z) 104 | */ 105 | static let JulianEpochToMacEpochDifference: Double = 2451910.5 106 | 107 | } -------------------------------------------------------------------------------- /CesiumKit.xcodeproj/xcshareddata/xcschemes/CesiumKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 55 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 74 | 76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/RenderPipeline.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RenderPipeline.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 31/05/2015. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | class RenderPipeline { 12 | 13 | let state: MTLRenderPipelineState! 14 | 15 | let shaderProgram: ShaderProgram 16 | 17 | var keyword: String { 18 | return state.label ?? "" 19 | } 20 | 21 | var blendingState: BlendingState? = nil 22 | 23 | var count: Int = 0 24 | 25 | fileprivate var _descriptor: MTLRenderPipelineDescriptor 26 | 27 | init (device: MTLDevice, shaderProgram: ShaderProgram, descriptor: MTLRenderPipelineDescriptor) { 28 | 29 | self.shaderProgram = shaderProgram 30 | _descriptor = descriptor 31 | do { 32 | let state = try device.makeRenderPipelineState(descriptor: _descriptor) 33 | self.state = state 34 | } catch let error as NSError { 35 | state = nil 36 | assertionFailure("makeRenderPipelineState failed: \(error.localizedDescription)") 37 | } 38 | } 39 | 40 | static func fromCache (context: Context, vertexShaderSource vss: ShaderSource, fragmentShaderSource fss: ShaderSource, vertexDescriptor vd: VertexDescriptor?, colorMask: ColorMask? = nil, depthStencil: Bool, blendingState: BlendingState? = nil, manualUniformStruct: String? = nil, uniformStructSize: Int? = nil) -> RenderPipeline { 41 | //FIXME: remove nil for manualUniformStruct 42 | return context.pipelineCache.getRenderPipeline(vertexShaderSource: vss, fragmentShaderSource: fss, vertexDescriptor: vd, colorMask: colorMask, depthStencil: depthStencil, blendingState: blendingState, manualUniformStruct: manualUniformStruct, uniformStructSize: uniformStructSize) 43 | } 44 | 45 | static func replaceCache (context: Context, pipeline: RenderPipeline?, vertexShaderSource vss: ShaderSource, fragmentShaderSource fss: ShaderSource, vertexDescriptor vd: VertexDescriptor?, colorMask: ColorMask? = nil, depthStencil: Bool, blendingState: BlendingState? = nil) -> RenderPipeline? { 46 | 47 | return context.pipelineCache.replaceRenderPipeline(pipeline, vertexShaderSource: vss, fragmentShaderSource: fss, vertexDescriptor: vd, colorMask: colorMask, depthStencil: depthStencil, blendingState: blendingState) 48 | } 49 | 50 | static func withCompiledShader(_ context: Context, shaderSourceName: String, compiledMetalVertexName vertex: String, compiledMetalFragmentName fragment: String, uniformStructSize: Int, vertexDescriptor vd: VertexDescriptor?, colorMask: ColorMask? = nil, depthStencil: Bool, blendingState: BlendingState? = nil) -> RenderPipeline? { 51 | return context.pipelineCache.getRenderPipeline(shaderSourceName: shaderSourceName, compiledMetalVertexName: vertex, compiledMetalFragmentName: fragment, uniformStructSize: uniformStructSize, vertexDescriptor: vd, colorMask: colorMask, depthStencil: depthStencil, blendingState: blendingState) 52 | } 53 | 54 | func setUniforms(_ command: DrawCommand, device: MTLDevice, uniformState: UniformState) -> (fragmentOffset: Int, texturesValid: Bool, textures: [Texture]) { 55 | return shaderProgram.setUniforms(command, uniformState: uniformState) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /CesiumKit/Core/ScreenSpaceEventType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScreenSpaceEventType.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/03/2015. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | /** 10 | * This enumerated type is for classifying mouse events: down, up, click, double click, move and move while a button is held down. 11 | * 12 | * @namespace 13 | * @alias ScreenSpaceEventType 14 | */ 15 | enum ScreenSpaceEventType: Int { 16 | /** 17 | * Represents a mouse left button down event. 18 | * 19 | * @type {Number} 20 | * @constant 21 | */ 22 | case leftDown = 0, 23 | 24 | /** 25 | * Represents a mouse left button up event. 26 | * 27 | * @type {Number} 28 | * @constant 29 | */ 30 | leftUp, 31 | 32 | /** 33 | * Represents a mouse left click event. 34 | * 35 | * @type {Number} 36 | * @constant 37 | */ 38 | leftClick, 39 | 40 | /** 41 | * Represents a mouse left double click event. 42 | * 43 | * @type {Number} 44 | * @constant 45 | */ 46 | leftDoubleClick, 47 | 48 | /** 49 | * Represents a mouse left button down event. 50 | * 51 | * @type {Number} 52 | * @constant 53 | */ 54 | rightDown, 55 | 56 | /** 57 | * Represents a mouse right button up event. 58 | * 59 | * @type {Number} 60 | * @constant 61 | */ 62 | rightUp, 63 | 64 | /** 65 | * Represents a mouse right click event. 66 | * 67 | * @type {Number} 68 | * @constant 69 | */ 70 | rightClick, 71 | 72 | /** 73 | * Represents a mouse right double click event. 74 | * 75 | * @type {Number} 76 | * @constant 77 | */ 78 | rightDoubleClick, 79 | 80 | /** 81 | * Represents a mouse middle button down event. 82 | * 83 | * @type {Number} 84 | * @constant 85 | */ 86 | middleDown, 87 | 88 | /** 89 | * Represents a mouse middle button up event. 90 | * 91 | * @type {Number} 92 | * @constant 93 | */ 94 | middleUp, 95 | 96 | /** 97 | * Represents a mouse middle click event. 98 | * 99 | * @type {Number} 100 | * @constant 101 | */ 102 | middleClick, 103 | 104 | /** 105 | * Represents a mouse middle double click event. 106 | * 107 | * @type {Number} 108 | * @constant 109 | */ 110 | middleDoubleClick, 111 | 112 | /** 113 | * Represents a mouse move event. 114 | * 115 | * @type {Number} 116 | * @constant 117 | */ 118 | mouseMove, 119 | 120 | /** 121 | * Represents a mouse wheel event. 122 | * 123 | * @type {Number} 124 | * @constant 125 | */ 126 | wheel, 127 | 128 | /** 129 | * Represents the start of a two-finger event on a touch surface. 130 | * 131 | * @type {Number} 132 | * @constant 133 | */ 134 | pinchStart, 135 | 136 | /** 137 | * Represents the end of a two-finger event on a touch surface. 138 | * 139 | * @type {Number} 140 | * @constant 141 | */ 142 | pinchEnd, 143 | 144 | /** 145 | * Represents a change of a two-finger event on a touch surface. 146 | * 147 | * @type {Number} 148 | * @constant 149 | */ 150 | pinchMove 151 | } 152 | -------------------------------------------------------------------------------- /CesiumKit/Platform/Array.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array.swift 3 | // Cent 4 | // 5 | // Created by Ankur Patel on 6/28/14. 6 | // Copyright (c) 2014 Encore Dev Labs LLC. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public func deleteDuplicates(_ seq:S)-> S where S.Iterator.Element: Equatable { 12 | let s = seq.reduce(S()){ 13 | ac, x in ac.contains(x) ? ac : ac + [x] 14 | } 15 | return s 16 | } 17 | 18 | extension Array { 19 | var sizeInBytes: Int { 20 | return count == 0 ? 0 : count * MemoryLayout.stride(ofValue: self[0]) 21 | } 22 | 23 | /** 24 | * Finds an item in a sorted array. 25 | * 26 | * @exports binarySearch 27 | * 28 | * @param {Array} array The sorted array to search. 29 | * @param {Object} itemToFind The item to find in the array. 30 | * @param {binarySearch~Comparator} comparator The function to use to compare the item to 31 | * elements in the array. 32 | * @returns {Number} The index of itemToFind in the array, if it exists. If itemToFind 33 | * does not exist, the return value is a negative number which is the bitwise complement (~) 34 | * of the index before which the itemToFind should be inserted in order to maintain the 35 | * sorted order of the array. 36 | * 37 | * @example 38 | * // Create a comparator function to search through an array of numbers. 39 | * var comparator = function(a, b) { 40 | * return a - b; 41 | * }; 42 | * var numbers = [0, 2, 4, 6, 8]; 43 | * var index = Cesium.binarySearch(numbers, 6, comparator); // 3 44 | */ 45 | func binarySearch (_ itemToFind: Element, comparator: BinarySearchComparator) -> Int { 46 | var low = 0 47 | var high = self.count - 1 48 | var i: Int 49 | var comparison: Int 50 | 51 | while low <= high { 52 | i = Int(trunc(Double(low + high) / 2.0)) 53 | comparison = comparator(self[i], itemToFind) 54 | if comparison < 0 { 55 | low = i + 1 56 | continue 57 | } 58 | if comparison > 0 { 59 | high = i - 1 60 | continue 61 | } 62 | return i; 63 | } 64 | return ~(high + 1) 65 | } 66 | 67 | /** 68 | * A function used to compare two items while performing a binary search. 69 | * @callback binarySearch~Comparator 70 | * 71 | * @param {Object} a An item in the array. 72 | * @param {Object} b The item being searched for. 73 | * @returns {Number} Returns a negative value if a is less than b, 74 | * a positive value if a is greater than b, or 75 | * 0 if a is equal to b. 76 | * 77 | * @example 78 | * function compareNumbers(a, b) { 79 | * return a - b; 80 | * } 81 | */ 82 | typealias BinarySearchComparator = (_ a: Element, _ b: Element) -> Int 83 | 84 | } 85 | 86 | extension Array where Element: Equatable { 87 | 88 | // Remove first collection element that is equal to the given `object`: 89 | mutating func removeObject(object: Element) { 90 | if let index = index(of: object) { 91 | remove(at: index) 92 | } 93 | } 94 | } 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /CesiumKit/Scene/Imagery.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Imagery.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 16/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Stores details about a tile of imagery. 13 | * 14 | * @alias Imagery 15 | * @private 16 | */ 17 | class Imagery { 18 | 19 | unowned var imageryLayer: ImageryLayer 20 | 21 | var level: Int 22 | 23 | var x: Int 24 | 25 | var y: Int 26 | 27 | var parent: Imagery? = nil 28 | 29 | var rectangle: Rectangle? = nil 30 | 31 | var image: CGImage? = nil 32 | 33 | var imageUrl: String? = nil 34 | 35 | var state: ImageryState = .unloaded 36 | 37 | var texture: Texture? = nil 38 | 39 | var reprojectCommand: DrawCommand? = nil 40 | 41 | var credits = [Credit]() 42 | 43 | fileprivate var _referenceCount: Int = 0 44 | 45 | init(imageryLayer: ImageryLayer, level: Int, x: Int, y: Int, rectangle: Rectangle? = nil) { 46 | 47 | self.imageryLayer = imageryLayer 48 | self.level = level 49 | self.x = x 50 | self.y = y 51 | 52 | if (level != 0) { 53 | let parentX = x / 2 | 0 54 | let parentY = y / 2 | 0 55 | let parentLevel = level - 1 56 | parent = imageryLayer.getImageryFromCache(level: parentLevel, x: parentX, y: parentY) 57 | } 58 | 59 | if rectangle == nil && imageryLayer.imageryProvider.ready { 60 | let tilingScheme = imageryLayer.imageryProvider.tilingScheme 61 | self.rectangle = tilingScheme.tileXYToRectangle(x: x, y: y, level: level) 62 | } else { 63 | self.rectangle = rectangle 64 | } 65 | } 66 | 67 | class func createPlaceholder(_ imageryLayer: ImageryLayer) -> Imagery { 68 | let result = Imagery(imageryLayer: imageryLayer, level: 0, x: 0, y: 0) 69 | result.addReference() 70 | result.state = .placeHolder 71 | return result 72 | } 73 | 74 | func addReference() { 75 | _referenceCount += 1 76 | } 77 | 78 | func releaseReference() -> Int { 79 | _referenceCount -= 1 80 | 81 | if _referenceCount == 0 { 82 | imageryLayer.removeImageryFromCache(self) 83 | 84 | if parent != nil { 85 | parent!.releaseReference() 86 | } 87 | return 0 88 | } 89 | return _referenceCount 90 | } 91 | 92 | func processStateMachine (frameState: inout FrameState) { 93 | if (state == .unloaded) { 94 | state = .transitioning 95 | imageryLayer.requestImagery(self) 96 | } 97 | if (state == .received) { 98 | state = .transitioning 99 | imageryLayer.createTexture(frameState: frameState, imagery: self) 100 | } 101 | if (state == .textureLoaded) { 102 | state = .transitioning 103 | imageryLayer.reprojectTexture(frameState: &frameState, imagery: self) 104 | } 105 | if (state == .reprojected) { 106 | state = .transitioning 107 | imageryLayer.generateMipmaps(frameState: &frameState, imagery: self) 108 | } 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/Buffer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Buffer.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 26/05/2015. 6 | // Copyright (c) 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | class Buffer { 12 | 13 | let metalBuffer: MTLBuffer 14 | 15 | var componentDatatype: ComponentDatatype 16 | 17 | // bytes 18 | let length: Int 19 | 20 | fileprivate let _entireRange: Range 21 | 22 | var count: Int { 23 | return length / componentDatatype.elementSize 24 | } 25 | 26 | /** 27 | Creates a Metal GPU buffer. If an allocated memory region is passed in, it will be 28 | copied to the buffer and can be released (or automatically released via ARC). 29 | */ 30 | init? (device: MTLDevice, array: UnsafeRawPointer? = nil, componentDatatype: ComponentDatatype, sizeInBytes: Int, label: String? = nil) { 31 | assert(sizeInBytes > 0, "bufferSize must be greater than zero") 32 | 33 | length = sizeInBytes 34 | self.componentDatatype = componentDatatype 35 | _entireRange = 0..? = nil) { 82 | #if os(OSX) 83 | metalBuffer.didModifyRange(range ?? _entireRange) 84 | #endif 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/ClearCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 15/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | /** 12 | * Represents a command to the renderer for clearing a framebuffer. 13 | * 14 | * @private 15 | */ 16 | struct ClearCommand { 17 | 18 | let boundingVolume: BoundingVolume? = nil 19 | let cull: Bool = false 20 | 21 | /** 22 | * The value to clear the color buffer to. When undefined, the color buffer is not cleared. 23 | * 24 | * @type {Color} 25 | * 26 | * @default undefined 27 | */ 28 | var color: Color? 29 | 30 | /** 31 | * The value to clear the depth buffer to. When undefined, the depth buffer is not cleared. 32 | * 33 | * @type {Number} 34 | * 35 | * @default undefined 36 | */ 37 | var depth: Double? 38 | 39 | /** 40 | * The value to clear the stencil buffer to. When undefined, the stencil buffer is not cleared. 41 | * 42 | * @type {Number} 43 | * 44 | * @default undefined 45 | */ 46 | var stencil: UInt32? 47 | 48 | /** 49 | * The render state to apply when executing the clear command. The following states affect clearing: 50 | * scissor test, color mask, depth mask, and stencil mask. When the render state is 51 | * undefined, the default render state is used. 52 | * 53 | * @type {RenderState} 54 | * 55 | * @default undefined 56 | * 57 | * @see Context#createRenderState 58 | */ 59 | var renderState: RenderState? 60 | 61 | /** 62 | * The framebuffer to clear. 63 | * 64 | * @type {Framebuffer} 65 | * 66 | * @default undefined 67 | */ 68 | var framebuffer: Framebuffer? 69 | 70 | /** 71 | * The object who created this command. This is useful for debugging command 72 | * execution; it allows you to see who created a command when you only have a 73 | * reference to the command, and can be used to selectively execute commands 74 | * with {@link Scene#debugCommandFilter}. 75 | * 76 | * @type {Object} 77 | * 78 | * @default undefined 79 | * 80 | * @see Scene#debugCommandFilter 81 | */ 82 | // FIXME: Owner 83 | weak var owner: AnyObject? = nil 84 | 85 | var debugOverlappingFrustums: Int = 0 86 | var executeInClosestFrustum: Bool = false 87 | 88 | /** 89 | * Clears color to (0.0, 0.0, 0.0, 0.0); depth to 1.0; and stencil to 0. 90 | * 91 | * @type {ClearCommand} 92 | * 93 | * @constant 94 | */ 95 | init (color: Cartesian4? = nil, depth: Double? = nil, stencil: UInt32? = nil, renderState: RenderState? = nil, framebuffer: Framebuffer? = nil, owner: AnyObject? = nil) { 96 | 97 | self.color = color 98 | self.depth = depth 99 | self.stencil = stencil 100 | self.renderState = renderState 101 | self.framebuffer = framebuffer 102 | self.owner = owner 103 | } 104 | 105 | static func all() -> ClearCommand { 106 | return ClearCommand(color: Cartesian4(), depth: 1.0, stencil: 1, renderState: nil) 107 | } 108 | 109 | func execute(_ context: Context, passState: PassState?) { 110 | context.clear(self, passState: passState) 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /CesiumKit/Platform/ImageExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 4/10/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | #if os(OSX) 12 | import AppKit.NSImage 13 | 14 | extension NSImage { 15 | var cgImage: CGImage? { 16 | get { 17 | guard let imageData = tiffRepresentation else { 18 | return nil 19 | } 20 | guard let source = CGImageSourceCreateWithData(imageData as CFData, nil) else { 21 | return nil 22 | } 23 | let maskRef = CGImageSourceCreateImageAtIndex(source, 0, nil) 24 | return maskRef 25 | } 26 | } 27 | } 28 | #elseif os(iOS) 29 | import UIKit.UIImage 30 | #endif 31 | 32 | extension CGImage { 33 | class func loadFromURL (_ url: String, completionBlock: @escaping (CGImage?, NSError?) -> ()) { 34 | 35 | let imageOperation = NetworkOperation(url: url) 36 | imageOperation.completionBlock = { 37 | if let error = imageOperation.error { 38 | completionBlock(nil, error) 39 | } 40 | completionBlock(CGImage.from(imageOperation.data), nil) 41 | } 42 | imageOperation.enqueue() 43 | } 44 | 45 | class func from(_ data: Data) -> CGImage? { 46 | #if os(OSX) 47 | let nsImage = NSImage(data: data) 48 | return nsImage?.cgImage 49 | #elseif os(iOS) 50 | let uiImage = UIImage(data: data) 51 | return uiImage?.cgImage 52 | #endif 53 | } 54 | 55 | func renderToPixelArray (colorSpace cs: CGColorSpace, premultiplyAlpha: Bool, flipY: Bool) -> (array: [UInt8], bytesPerRow: Int)? { 56 | 57 | let width = self.width 58 | let height = self.height 59 | let bitsPerComponent = self.bitsPerComponent 60 | let numberOfComponents = 4 61 | 62 | let bytesPerPixel = (bitsPerComponent * numberOfComponents + 7)/8 63 | 64 | let bytesPerRow = bytesPerPixel * width 65 | 66 | let alphaInfo: CGImageAlphaInfo 67 | if bytesPerPixel == 1 { 68 | // no alpha info in single byte pixel array 69 | alphaInfo = .none 70 | } else if premultiplyAlpha { 71 | alphaInfo = .premultipliedLast 72 | } else { 73 | alphaInfo = .last 74 | } 75 | 76 | let bitmapInfo: CGBitmapInfo = [CGBitmapInfo(rawValue: alphaInfo.rawValue)] 77 | 78 | let pixelBuffer = [UInt8](repeating: 0, count: bytesPerRow * height) // if 4 components per pixel (RGBA) 79 | 80 | guard let bitmapContext = CGContext(data: UnsafeMutableRawPointer(mutating: pixelBuffer), width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: cs, bitmapInfo: bitmapInfo.rawValue) else { 81 | assertionFailure("bitmapContext == nil") 82 | return nil 83 | } 84 | 85 | let imageRect = CGRect(x: 0, y: 0, width: CGFloat(width), height: CGFloat(height)) 86 | 87 | if flipY { 88 | let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: CGFloat(height)) 89 | bitmapContext.concatenate(flipVertical) 90 | } 91 | bitmapContext.draw(self, in: imageRect) 92 | return (pixelBuffer, bytesPerRow) 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /CesiumKit/Core/GeographicProjection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GeographicProjection.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 11/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * A simple map projection where longitude and latitude are linearly mapped to X and Y by multiplying 13 | * them by the {@link Ellipsoid#maximumRadius}. This projection 14 | * is commonly known as geographic, equirectangular, equidistant cylindrical, or plate carrée. It 15 | * is also known as EPSG:4326. 16 | * 17 | * @alias GeographicProjection 18 | * @constructor 19 | * @immutable 20 | * 21 | * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid. 22 | * 23 | * @see WebMercatorProjection 24 | */ 25 | public struct GeographicProjection: MapProjection { 26 | 27 | public let ellipsoid: Ellipsoid 28 | public let semimajorAxis: Double 29 | public let oneOverSemimajorAxis: Double 30 | 31 | public init (ellipsoid: Ellipsoid = Ellipsoid.wgs84) { 32 | self.ellipsoid = ellipsoid 33 | semimajorAxis = ellipsoid.maximumRadius 34 | oneOverSemimajorAxis = 1.0 / semimajorAxis 35 | } 36 | 37 | /** 38 | * Projects a set of {@link Cartographic} coordinates, in radians, to map coordinates, in meters. 39 | * X and Y are the longitude and latitude, respectively, multiplied by the maximum radius of the 40 | * ellipsoid. Z is the unmodified height. 41 | * 42 | * @param {Cartographic} cartographic The coordinates to project. 43 | * @param {Cartesian3} [result] An instance into which to copy the result. If this parameter is 44 | * undefined, a new instance is created and returned. 45 | * @returns {Cartesian3} The projected coordinates. If the result parameter is not undefined, the 46 | * coordinates are copied there and that instance is returned. Otherwise, a new instance is 47 | * created and returned. 48 | */ 49 | public func project(_ cartographic: Cartographic) -> Cartesian3 { 50 | // Actually this is the special case of equidistant cylindrical called the plate carree 51 | return Cartesian3(x: cartographic.longitude * semimajorAxis, 52 | y: cartographic.latitude * semimajorAxis, 53 | z: cartographic.height) 54 | } 55 | 56 | /** 57 | * Unprojects a set of projected {@link Cartesian3} coordinates, in meters, to {@link Cartographic} 58 | * coordinates, in radians. Longitude and Latitude are the X and Y coordinates, respectively, 59 | * divided by the maximum radius of the ellipsoid. Height is the unmodified Z coordinate. 60 | * 61 | * @param {Cartesian3} cartesian The Cartesian position to unproject with height (z) in meters. 62 | * @param {Cartographic} [result] An instance into which to copy the result. If this parameter is 63 | * undefined, a new instance is created and returned. 64 | * @returns {Cartographic} The unprojected coordinates. If the result parameter is not undefined, the 65 | * coordinates are copied there and that instance is returned. Otherwise, a new instance is 66 | * created and returned. 67 | */ 68 | public func unproject(_ cartesian: Cartesian3) -> Cartographic { 69 | let longitude = cartesian.x * oneOverSemimajorAxis 70 | let latitude = cartesian.y * oneOverSemimajorAxis 71 | let height = cartesian.z 72 | return Cartographic(longitude: longitude, latitude: latitude, height: height) 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /CesiumKit/Core/MergeSort.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MergeSort.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 8/11/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class MergeSort { 12 | /* 13 | var leftScratchArray = []; 14 | var rightScratchArray = []; 15 | 16 | function merge(array, compare, userDefinedObject, start, middle, end) { 17 | var leftLength = middle - start + 1; 18 | var rightLength = end - middle; 19 | 20 | var left = leftScratchArray; 21 | var right = rightScratchArray; 22 | 23 | var i; 24 | var j; 25 | 26 | for (i = 0; i < leftLength; ++i) { 27 | left[i] = array[start + i]; 28 | } 29 | 30 | for (j = 0; j < rightLength; ++j) { 31 | right[j] = array[middle + j + 1]; 32 | } 33 | 34 | i = 0; 35 | j = 0; 36 | for (var k = start; k <= end; ++k) { 37 | var leftElement = left[i]; 38 | var rightElement = right[j]; 39 | if (i < leftLength && (j >= rightLength || compare(leftElement, rightElement, userDefinedObject) <= 0)) { 40 | array[k] = leftElement; 41 | ++i; 42 | } else if (j < rightLength) { 43 | array[k] = rightElement; 44 | ++j; 45 | } 46 | } 47 | } 48 | 49 | function sort(array, compare, userDefinedObject, start, end) { 50 | if (start >= end) { 51 | return; 52 | } 53 | 54 | var middle = Math.floor((start + end) * 0.5); 55 | sort(array, compare, userDefinedObject, start, middle); 56 | sort(array, compare, userDefinedObject, middle + 1, end); 57 | merge(array, compare, userDefinedObject, start, middle, end); 58 | } 59 | 60 | /** 61 | * A stable merge sort. 62 | * 63 | * @exports mergeSort 64 | * 65 | * @param {Array} array The array to sort. 66 | * @param {mergeSort~Comparator} comparator The function to use to compare elements in the array. 67 | * @param {Object} [userDefinedObject] An object to pass as the third parameter to comparator. 68 | * 69 | * @example 70 | * // Assume array contains BoundingSpheres in world coordinates. 71 | * // Sort them in ascending order of distance from the camera. 72 | * var position = camera.positionWC; 73 | * Cesium.mergeSort(array, function(a, b, position) { 74 | * return Cesium.BoundingSphere.distanceSquaredTo(b, position) - Cesium.BoundingSphere.distanceSquaredTo(a, position); 75 | * }, position); 76 | */ 77 | var mergeSort = function(array, comparator, userDefinedObject) { 78 | //>>includeStart('debug', pragmas.debug); 79 | if (!defined(array)) { 80 | throw new DeveloperError('array is required.'); 81 | } 82 | if (!defined(comparator)) { 83 | throw new DeveloperError('comparator is required.'); 84 | } 85 | //>>includeEnd('debug'); 86 | 87 | var length = array.length; 88 | var scratchLength = Math.ceil(length * 0.5); 89 | 90 | // preallocate space in scratch arrays 91 | leftScratchArray.length = scratchLength; 92 | rightScratchArray.length = scratchLength; 93 | 94 | sort(array, comparator, userDefinedObject, 0, length - 1); 95 | 96 | // trim scratch arrays 97 | leftScratchArray.length = 0; 98 | rightScratchArray.length = 0; 99 | }; 100 | 101 | /** 102 | * A function used to compare two items while performing a merge sort. 103 | * @callback mergeSort~Comparator 104 | * 105 | * @param {Object} a An item in the array. 106 | * @param {Object} b An item in the array. 107 | * @param {Object} [userDefinedObject] An object that was passed to {@link mergeSort}. 108 | * @returns {Number} Returns a negative value if a is less than b, 109 | * a positive value if a is greater than b, or 110 | * 0 if a is equal to b. 111 | * 112 | * @example 113 | * function compareNumbers(a, b, userDefinedObject) { 114 | * return a - b; 115 | * } 116 | */ 117 | 118 | return mergeSort; 119 | }); 120 | */ 121 | } -------------------------------------------------------------------------------- /CesiumKitRunner/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /CesiumKitRunner OSX/CesiumViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // CesiumKitRunner OSX 4 | // 5 | // Created by Ryan Walklin on 1/08/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import MetalKit 11 | import CesiumKit 12 | 13 | class CesiumViewController: NSViewController { 14 | 15 | fileprivate var _cesiumKitController: CesiumKitController! = nil 16 | 17 | @IBOutlet var _metalView: MTKView! 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | view.layer!.contentsScale = NSScreen.main()?.backingScaleFactor ?? 1.0 23 | _cesiumKitController = CesiumKitController(view: _metalView) 24 | _metalView.delegate = _cesiumKitController 25 | _cesiumKitController.startRendering() 26 | } 27 | 28 | override func viewWillAppear() { 29 | _metalView.window?.acceptsMouseMovedEvents = true 30 | } 31 | 32 | override func mouseDown(with event: NSEvent) { 33 | let locationInWindow = event.locationInWindow 34 | let localPoint = _metalView.convert(locationInWindow, from: nil) 35 | 36 | let viewHeight = Double(_metalView.bounds.height) 37 | let position = Cartesian2(x: Double(localPoint.x), y: viewHeight - Double(localPoint.y)) 38 | 39 | let modifier: KeyboardEventModifier? 40 | if event.modifierFlags.contains(.control) { 41 | modifier = .ctrl 42 | } else if event.modifierFlags.contains(.option) { 43 | modifier = .alt 44 | } else if event.modifierFlags.contains(.shift) { 45 | modifier = .shift 46 | } else { 47 | modifier = nil 48 | } 49 | _cesiumKitController.handleMouseDown(.left, position: position, modifier: modifier) 50 | } 51 | 52 | override func mouseDragged(with event: NSEvent) { 53 | let locationInWindow = event.locationInWindow 54 | let localPoint = _metalView.convert(locationInWindow, from: nil) 55 | let viewHeight = Double(_metalView.bounds.height) 56 | let position = Cartesian2(x: Double(localPoint.x), y: viewHeight - Double(localPoint.y)) 57 | 58 | let modifier: KeyboardEventModifier? 59 | if event.modifierFlags.contains(.control) { 60 | modifier = .ctrl 61 | } else if event.modifierFlags.contains(.option) { 62 | modifier = .alt 63 | } else if event.modifierFlags.contains(.shift) { 64 | modifier = .shift 65 | } else { 66 | modifier = nil 67 | } 68 | _cesiumKitController.handleMouseMove(.left, position: position, modifier: modifier) 69 | } 70 | 71 | override func mouseMoved(with event: NSEvent) { 72 | 73 | } 74 | 75 | override func mouseUp(with event: NSEvent) { 76 | let locationInWindow = event.locationInWindow 77 | let localPoint = _metalView.convert(locationInWindow, from: nil) 78 | let viewHeight = Double(_metalView.bounds.height) 79 | let position = Cartesian2(x: Double(localPoint.x), y: viewHeight - Double(localPoint.y)) 80 | 81 | let modifier: KeyboardEventModifier? 82 | if event.modifierFlags.contains(.control) { 83 | modifier = .ctrl 84 | } else if event.modifierFlags.contains(.option) { 85 | modifier = .alt 86 | } else if event.modifierFlags.contains(.shift) { 87 | modifier = .shift 88 | } else { 89 | modifier = nil 90 | } 91 | _cesiumKitController.handleMouseUp(.left, position: position, modifier: modifier) 92 | } 93 | 94 | override func scrollWheel(with event: NSEvent) { 95 | _cesiumKitController.handleWheel(Double(event.deltaX), deltaY: Double(event.deltaY)) 96 | } 97 | 98 | 99 | } 100 | 101 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/Framebuffer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Framebuffer.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 15/06/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | import MetalKit 10 | 11 | /** 12 | * @private 13 | */ 14 | class Framebuffer { 15 | 16 | let maximumColorAttachments: Int 17 | 18 | fileprivate (set) var colorTextures: [Texture]? 19 | 20 | fileprivate (set) var depthTexture: Texture? 21 | 22 | fileprivate (set) var stencilTexture: Texture? 23 | 24 | var depthStencilTexture: Texture? { 25 | return depthTexture === stencilTexture ? depthTexture : nil 26 | } 27 | 28 | var renderPassDescriptor: MTLRenderPassDescriptor { 29 | return _rpd 30 | } 31 | 32 | fileprivate var _rpd = MTLRenderPassDescriptor() 33 | 34 | var numberOfColorAttachments: Int { 35 | return colorTextures?.count ?? 0 36 | } 37 | 38 | /** 39 | * True if the framebuffer has a depth attachment. Depth attachments include 40 | * depth and depth-stencil textures, and depth and depth-stencil renderbuffers. When 41 | * rendering to a framebuffer, a depth attachment is required for the depth test to have effect. 42 | * @memberof Framebuffer.prototype 43 | * @type {Boolean} 44 | */ 45 | var hasDepthAttachment: Bool { 46 | return depthTexture != nil 47 | } 48 | 49 | init ( 50 | maximumColorAttachments: Int, 51 | colorTextures: [Texture]? = nil, 52 | depthTexture: Texture? = nil, 53 | stencilTexture: Texture? = nil) { 54 | self.maximumColorAttachments = maximumColorAttachments 55 | self.colorTextures = colorTextures 56 | self.depthTexture = depthTexture 57 | self.stencilTexture = stencilTexture 58 | 59 | assert(colorTextures == nil || colorTextures!.count <= Int(maximumColorAttachments), "The number of color attachments exceeds the number supported.") 60 | updateRenderPassDescriptor() 61 | } 62 | 63 | func updateFromDrawable (context: Context, drawable: CAMetalDrawable, depthStencil: MTLTexture?) { 64 | 65 | colorTextures = [Texture(context: context, metalTexture: drawable.texture)] 66 | depthTexture = depthStencil == nil ? nil : Texture(context: context, metalTexture: depthStencil!) 67 | stencilTexture = depthTexture 68 | 69 | updateRenderPassDescriptor() 70 | } 71 | 72 | func update (colorTextures: [Texture]?, depthTexture: Texture?, stencilTexture: Texture?) { 73 | self.colorTextures = colorTextures 74 | self.depthTexture = depthTexture 75 | self.stencilTexture = stencilTexture 76 | updateRenderPassDescriptor() 77 | } 78 | 79 | fileprivate func updateRenderPassDescriptor () { 80 | if let colorTextures = self.colorTextures { 81 | for (i, colorTexture) in colorTextures.enumerated() { 82 | _rpd.colorAttachments[i].texture = colorTexture.metalTexture 83 | _rpd.colorAttachments[i].storeAction = .store 84 | } 85 | } else { 86 | for i in 0.. Self 14 | func -(lhs: Self, rhs: Self) -> Self 15 | func *(lhs: Self, rhs: Self) -> Self 16 | func /(lhs: Self, rhs: Self) -> Self 17 | func *(lhs: Self, rhs: Double) -> Self 18 | prefix func -(cartesian: Self) -> Self 19 | 20 | func dot(other: Self) -> Double 21 | func multiplyComponents(other: Self) -> Self 22 | 23 | func multiplyByScalar(scalar: Double) -> Self 24 | func divideByScalar(scalar: Double) -> Self 25 | 26 | func add(other: Self) -> Self 27 | func subtract(other: Self) -> Self 28 | 29 | func negate() -> Self 30 | } 31 | 32 | extension CartesianType { 33 | 34 | /** 35 | * Computes the componentwise product of two Cartesians. 36 | * 37 | * @param {Cartesian3} left The first Cartesian. 38 | * @param {Cartesian3} right The second Cartesian. 39 | * @param {Cartesian3} [result] The object onto which to store the result. 40 | * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. 41 | */ 42 | func multiplyComponents(other: Self) -> Self { 43 | return self * other 44 | } 45 | 46 | /** 47 | * Multiplies the provided Cartesian componentwise by the provided scalar. 48 | * 49 | * @param {Cartesian3} cartesian The Cartesian to be scaled. 50 | * @param {Number} scalar The scalar to multiply with. 51 | * @param {Cartesian3} [result] The object onto which to store the result. 52 | * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. 53 | */ 54 | func multiplyByScalar(scalar: Double) -> Self { 55 | return self * scalar 56 | } 57 | 58 | /** 59 | * Divides the provided Cartesian componentwise by the provided scalar. 60 | * 61 | * @param {Cartesian3} cartesian The Cartesian to be divided. 62 | * @param {Number} scalar The scalar to divide by. 63 | * @param {Cartesian3} [result] The object onto which to store the result. 64 | * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. 65 | */ 66 | func divideByScalar(scalar: Double) -> Self { 67 | return multiplyByScalar(1.0/scalar) 68 | } 69 | 70 | /** 71 | * Computes the componentwise sum of two Cartesians. 72 | * 73 | * @param {Cartesian3} left The first Cartesian. 74 | * @param {Cartesian3} right The second Cartesian. 75 | * @param {Cartesian3} [result] The object onto which to store the result. 76 | * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. 77 | */ 78 | func add(other: Self) -> Self { 79 | return self + other 80 | } 81 | 82 | /** 83 | * Computes the componentwise difference of two Cartesians. 84 | * 85 | * @param {Cartesian3} left The first Cartesian. 86 | * @param {Cartesian3} right The second Cartesian. 87 | * @param {Cartesian3} [result] The object onto which to store the result. 88 | * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. 89 | */ 90 | func subtract(other: Self) -> Self { 91 | return self - other 92 | } 93 | 94 | /** 95 | * Negates the provided Cartesian. 96 | * 97 | * @param {Cartesian3} cartesian The Cartesian to be negated. 98 | * @param {Cartesian3} [result] The object onto which to store the result. 99 | * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. 100 | */ 101 | func negate() -> Self { 102 | return -self 103 | } 104 | 105 | 106 | } -------------------------------------------------------------------------------- /CesiumKit/Scene/ImageryLayerFeatureInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageryLayerFeatureInfo.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 31/10/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Describes a rasterized feature, such as a point, polygon, polyline, etc., in an imagery layer. 13 | * 14 | * @alias ImageryLayerFeatureInfo 15 | * @constructor 16 | */ 17 | public struct ImageryLayerFeatureInfo { 18 | 19 | /** 20 | * Gets or sets the name of the feature. 21 | * @type {String} 22 | */ 23 | var name: String 24 | 25 | /** 26 | * Gets or sets an HTML description of the feature. The HTML is not trusted and should 27 | * be sanitized before display to the user. 28 | * @type {String} 29 | */ 30 | var description: String 31 | 32 | /** 33 | * Gets or sets the position of the feature, or undefined if the position is not known. 34 | * 35 | * @type {Cartographic} 36 | */ 37 | var position: Cartographic 38 | 39 | /** 40 | * Gets or sets the raw data describing the feature. The raw data may be in any 41 | * number of formats, such as GeoJSON, KML, etc. 42 | * @type {Object} 43 | */ 44 | var data: Data 45 | 46 | /** 47 | * Configures the name of this feature by selecting an appropriate property. The name will be obtained from 48 | * one of the following sources, in this order: 1) the property with the name 'name', 2) the property with the name 'title', 49 | * 3) the first property containing the word 'name', 4) the first property containing the word 'title'. If 50 | * the name cannot be obtained from any of these sources, the existing name will be left unchanged. 51 | * 52 | * @param {Object} properties An object literal containing the properties of the feature. 53 | */ 54 | func configureNameFromProperties (_ properties: [String]) { 55 | /* 56 | var namePropertyPrecedence = 10; 57 | var nameProperty; 58 | 59 | for (var key in properties) { 60 | if (properties.hasOwnProperty(key) && properties[key]) { 61 | var lowerKey = key.toLowerCase(); 62 | 63 | if (namePropertyPrecedence > 1 && lowerKey === 'name') { 64 | namePropertyPrecedence = 1; 65 | nameProperty = key; 66 | } else if (namePropertyPrecedence > 2 && lowerKey === 'title') { 67 | namePropertyPrecedence = 2; 68 | nameProperty = key; 69 | } else if (namePropertyPrecedence > 3 && /name/i.test(key)) { 70 | namePropertyPrecedence = 3; 71 | nameProperty = key; 72 | } else if (namePropertyPrecedence > 4 && /title/i.test(key)) { 73 | namePropertyPrecedence = 4; 74 | nameProperty = key; 75 | } 76 | } 77 | } 78 | 79 | if (defined(nameProperty)) { 80 | this.name = properties[nameProperty]; 81 | }*/ 82 | } 83 | 84 | /** 85 | * Configures the description of this feature by creating an HTML table of properties and their values. 86 | * 87 | * @param {Object} properties An object literal containing the properties of the feature. 88 | */ 89 | func configureDescriptionFromProperties (_ properties: [String]) { 90 | /*function describe(properties) { 91 | var html = ''; 92 | for (var key in properties) { 93 | if (properties.hasOwnProperty(key)) { 94 | var value = properties[key]; 95 | if (defined(value)) { 96 | if (typeof value === 'object') { 97 | html += ''; 98 | } else { 99 | html += ''; 100 | } 101 | } 102 | } 103 | } 104 | html += '
' + key + '' + describe(value) + '
' + key + '' + value + '
'; 105 | 106 | return html; 107 | } 108 | 109 | this.description = describe(properties);*/ 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /CesiumKit/Platform/Data+ArrayView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+ArrayView.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 26/12/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Data { 12 | 13 | public func getFloat32(_ pos: Int, littleEndian: Bool = true) -> Float { 14 | assert(self.count >= pos + MemoryLayout.size, "pos out of bounds") 15 | var result: Float = 0.0 16 | _ = withUnsafeBytes { pointer in 17 | memcpy(&result, pointer+pos, MemoryLayout.size(ofValue: result)) 18 | } 19 | return result 20 | } 21 | 22 | public func getFloat64(_ pos: Int, littleEndian: Bool = true) -> Double { 23 | assert(self.count >= pos + MemoryLayout.size, "pos out of bounds") 24 | var result: Double = 0.0 25 | Float() 26 | _ = withUnsafeBytes { pointer in 27 | memcpy(&result, pointer+pos, MemoryLayout.size(ofValue: result)) 28 | } 29 | return result 30 | } 31 | 32 | public func getUInt8(_ pos: Int) -> UInt8 { 33 | assert(self.count >= pos + MemoryLayout.size, "pos out of bounds") 34 | var result: UInt8 = 0 35 | _ = withUnsafeBytes { pointer in 36 | memcpy(&result, pointer+pos, MemoryLayout.size(ofValue: result)) 37 | } 38 | return result 39 | } 40 | 41 | public func getUInt16(_ pos: Int, littleEndian: Bool = true) -> UInt16 { 42 | assert(self.count >= pos + MemoryLayout.size, "pos out of bounds") 43 | var result: UInt16 = 0 44 | _ = withUnsafeBytes { pointer in 45 | memcpy(&result, pointer+pos, MemoryLayout.size(ofValue: result)) 46 | } 47 | return littleEndian ? result : result.bigEndian 48 | } 49 | 50 | public func getUInt32(_ pos: Int, littleEndian: Bool = true) -> UInt32 { 51 | assert(self.count >= pos + MemoryLayout.size, "pos out of bounds") 52 | var result: UInt32 = 0 53 | _ = withUnsafeBytes { pointer in 54 | memcpy(&result, pointer+pos, MemoryLayout.size(ofValue: result)) 55 | } 56 | return littleEndian ? result : result.bigEndian 57 | } 58 | 59 | public func getUInt8Array(_ pos: Int = 0, elementCount: Int? = nil) -> [UInt8] { 60 | let elementCount = elementCount ?? self.count 61 | assert(self.count >= pos + elementCount, "requested array out of bounds") 62 | var result = [UInt8](repeating: 0, count: elementCount) 63 | copyBytes(to: &result, from: Range(uncheckedBounds: (lower: pos, upper: pos+elementCount))) 64 | return result 65 | } 66 | 67 | public func getUInt16Array(_ pos: Int = 0, elementCount: Int? = nil, littleEndian: Bool = true) -> [UInt16] { 68 | let elementCount = elementCount ?? self.count / MemoryLayout.stride 69 | let arrayByteLength = elementCount * MemoryLayout.stride 70 | assert(self.count >= pos + arrayByteLength, "requested array out of bounds") 71 | var result = [UInt16](repeating: 0, count: elementCount) 72 | _ = result.withUnsafeMutableBufferPointer { (pointer: inout UnsafeMutableBufferPointer) in 73 | memcpy(pointer.baseAddress, (self as NSData).bytes + pos, arrayByteLength) 74 | } 75 | return littleEndian ? result : result.map { $0.bigEndian } 76 | } 77 | 78 | public func getUInt32Array(_ pos: Int = 0, elementCount: Int? = nil, littleEndian: Bool = true) -> [UInt32] { 79 | let elementCount = elementCount ?? self.count / MemoryLayout.stride 80 | let arrayByteLength = elementCount * MemoryLayout.stride 81 | assert(self.count >= pos + arrayByteLength, "requested array out of bounds") 82 | var result = [UInt32](repeating: 0, count: elementCount) 83 | _ = result.withUnsafeMutableBufferPointer { (pointer: inout UnsafeMutableBufferPointer) in 84 | memcpy(pointer.baseAddress, (self as NSData).bytes + pos, arrayByteLength) 85 | } 86 | return littleEndian ? result : result.map { $0.bigEndian } 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/ComputeCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ComputeCommand.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 10/10/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Represents a command to the renderer for GPU Compute (using old-school GPGPU). 13 | * 14 | * @private 15 | */ 16 | class ComputeCommand: Command { 17 | 18 | /** 19 | * The vertex array. If none is provided, a viewport quad will be used. 20 | * 21 | * @type {VertexArray} 22 | * @default undefined 23 | */ 24 | var vertexArray: VertexArray? 25 | 26 | /** 27 | * The fragment shader source. The default vertex shader is ViewportQuadVS. 28 | * 29 | * @type {ShaderSource} 30 | * @default undefined 31 | */ 32 | var fragmentShaderSource: ShaderSource? 33 | 34 | /** 35 | * The shader program to apply. 36 | * 37 | * @type {ShaderProgram} 38 | * @default undefined 39 | */ 40 | var pipeline: RenderPipeline? 41 | 42 | /** 43 | * An object with functions whose names match the uniforms in the shader program 44 | * and return values to set those uniforms. 45 | * 46 | * @type {Object} 47 | * @default undefined 48 | */ 49 | var uniformMap: UniformMap? 50 | 51 | /** 52 | * Texture to use for offscreen rendering. 53 | * 54 | * @type {Texture} 55 | * @default undefined 56 | */ 57 | var outputTexture: Texture? 58 | 59 | /** 60 | * Function that is called immediately before the ComputeCommand is executed. Used to 61 | * update any renderer resources. Takes the ComputeCommand as its single argument. 62 | * 63 | * @type {Function} 64 | * @default undefined 65 | */ 66 | var preExecute: ((ComputeCommand) -> ())? 67 | 68 | /** 69 | * Function that is called after the ComputeCommand is executed. Takes the output 70 | * texture as its single argument. 71 | * 72 | * @type {Function} 73 | * @default undefined 74 | */ 75 | var postExecute: ((Texture) -> ())? 76 | 77 | /** 78 | * Whether the renderer resources will persist beyond this call. If not, they 79 | * will be destroyed after completion. 80 | * 81 | * @type {Boolean} 82 | * @default false 83 | */ 84 | var persists: Bool 85 | 86 | /** 87 | * The pass when to render. Always compute pass. 88 | * 89 | * @type {Pass} 90 | * @default Pass.COMPUTE; 91 | */ 92 | let pass: Pass = .compute 93 | 94 | /** 95 | * The object who created this command. This is useful for debugging command 96 | * execution; it allows us to see who created a command when we only have a 97 | * reference to the command, and can be used to selectively execute commands 98 | * with {@link Scene#debugCommandFilter}. 99 | * 100 | * @type {Object} 101 | * @default undefined 102 | * 103 | * @see Scene#debugCommandFilter 104 | */ 105 | var owner: AnyObject? = nil 106 | 107 | init( 108 | vertexArray: VertexArray? = nil, 109 | fragmentShaderSource: ShaderSource? = nil, 110 | renderPipeline: RenderPipeline? = nil, 111 | uniformMap: UniformMap? = nil, 112 | outputTexture: Texture? = nil, 113 | preExecute: ((ComputeCommand) -> ())? = nil, 114 | postExecute: ((Texture) -> ())? = nil, 115 | persists: Bool = false, 116 | owner: AnyObject? = nil) { 117 | self.vertexArray = vertexArray 118 | self.fragmentShaderSource = fragmentShaderSource 119 | self.pipeline = renderPipeline 120 | self.uniformMap = uniformMap 121 | self.outputTexture = outputTexture 122 | self.preExecute = preExecute 123 | self.postExecute = postExecute 124 | self.persists = persists 125 | self.owner = owner 126 | } 127 | 128 | /** 129 | * Executes the compute command. 130 | * 131 | * @param {Context} context The context that processes the compute command. 132 | */ 133 | func execute (_ computeEngine: ComputeEngine) { 134 | computeEngine.execute(self) 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /CesiumKit/Scene/TileReplacementQueue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TileReplacementQueue.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 28/09/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | 10 | /** 11 | * A priority queue of tiles to be replaced, if necessary, to make room for new tiles. The queue 12 | * is implemented as a linked list. 13 | * 14 | * @alias TileReplacementQueue 15 | * @private 16 | */ 17 | class TileReplacementQueue { 18 | 19 | var head: QuadtreeTile? = nil 20 | 21 | var tail: QuadtreeTile? = nil 22 | 23 | var count = 0 24 | 25 | fileprivate var _lastBeforeStartOfFrame: QuadtreeTile? = nil 26 | 27 | fileprivate var _tileProvider: GlobeSurfaceTileProvider 28 | 29 | init (tileProvider: GlobeSurfaceTileProvider) { 30 | _tileProvider = tileProvider 31 | } 32 | 33 | /** 34 | * Marks the start of the render frame. Tiles before (closer to the head) this tile in the 35 | * list were used last frame and must not be unloaded. 36 | */ 37 | func markStartOfRenderFrame() { 38 | _lastBeforeStartOfFrame = head 39 | } 40 | 41 | /** 42 | * Reduces the size of the queue to a specified size by unloading the least-recently used 43 | * tiles. Tiles that were used last frame will not be unloaded, even if that puts the number 44 | * of tiles above the specified maximum. 45 | * 46 | * @param {Number} maximumTiles The maximum number of tiles in the queue. 47 | */ 48 | func trimTiles(_ maximumTiles: Int) { 49 | var tileToTrim = tail 50 | var keepTrimming = true 51 | while keepTrimming && _lastBeforeStartOfFrame != nil && count > maximumTiles && tileToTrim != nil { 52 | // Stop trimming after we process the last tile not used in the 53 | // current frame. 54 | keepTrimming = tileToTrim! != _lastBeforeStartOfFrame 55 | 56 | let previous = tileToTrim!.replacementPrevious 57 | 58 | if tileToTrim!.eligibleForUnloading { 59 | tileToTrim!.freeResources(_tileProvider) 60 | remove(tileToTrim!) 61 | } 62 | tileToTrim = previous 63 | } 64 | } 65 | 66 | func remove(_ item: QuadtreeTile) { 67 | let previous = item.replacementPrevious 68 | let next = item.replacementNext 69 | 70 | if item == _lastBeforeStartOfFrame { 71 | _lastBeforeStartOfFrame = next 72 | } 73 | 74 | if (item == head) { 75 | head = next 76 | } else { 77 | previous!.replacementNext = next 78 | } 79 | 80 | if (item == tail) { 81 | tail = previous 82 | } else { 83 | next!.replacementPrevious = previous 84 | } 85 | 86 | item.replacementPrevious = nil 87 | item.replacementNext = nil 88 | 89 | count -= 1 90 | } 91 | 92 | /** 93 | * Marks a tile as rendered this frame and moves it before the first tile that was not rendered 94 | * this frame. 95 | * 96 | * @param {TileReplacementQueue} item The tile that was rendered. 97 | */ 98 | func markTileRendered (_ item: QuadtreeTile) { 99 | if head == item { 100 | if (item == _lastBeforeStartOfFrame) { 101 | _lastBeforeStartOfFrame = item.replacementNext 102 | } 103 | return; 104 | } 105 | 106 | count += 1 107 | 108 | if head == nil { 109 | // no other tiles in the list 110 | item.replacementPrevious = nil 111 | item.replacementNext = nil 112 | head = item 113 | tail = item 114 | return 115 | } 116 | 117 | if item.replacementPrevious != nil || item.replacementNext != nil { 118 | // tile already in the list, remove from its current location 119 | remove(item) 120 | } 121 | 122 | item.replacementPrevious = nil 123 | item.replacementNext = head 124 | head!.replacementPrevious = item 125 | 126 | head = item 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /CesiumKit/Renderer/ComputeEngine.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ComputeEngine.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 10/10/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Metal 11 | 12 | class ComputeEngine { 13 | 14 | 15 | /** 16 | * @private 17 | */ 18 | let context: Context 19 | 20 | init (context: Context) { 21 | self.context = context 22 | } 23 | 24 | fileprivate func createViewportQuadPipeline(_ fragmentShaderSource: ShaderSource) -> RenderPipeline? { 25 | 26 | let attributes = [ 27 | // attribute vec4 position; 28 | VertexAttributes( 29 | buffer: nil, 30 | bufferIndex: VertexDescriptorFirstBufferOffset, 31 | index: 0, 32 | format: .float2, 33 | offset: 0, 34 | size: 8, 35 | normalize: false), 36 | // attribute vec2 textureCoordinates; 37 | VertexAttributes( 38 | buffer: nil, 39 | bufferIndex: VertexDescriptorFirstBufferOffset, 40 | index: 1, 41 | format: .float2, 42 | offset: 8, 43 | size: 8, 44 | normalize: false) 45 | ] 46 | 47 | return RenderPipeline.fromCache( 48 | context: context, 49 | vertexShaderSource: ShaderSource(sources: [Shaders["ViewportQuadVS"]!]), 50 | fragmentShaderSource: fragmentShaderSource, 51 | vertexDescriptor: VertexDescriptor(attributes: attributes), 52 | colorMask: nil, 53 | depthStencil: false) 54 | } 55 | 56 | func execute (_ computeCommand: ComputeCommand) { 57 | 58 | // This may modify the command's resources, so do error checking afterwards 59 | if let preExecute = computeCommand.preExecute { 60 | preExecute(computeCommand) 61 | } 62 | 63 | assert(computeCommand.fragmentShaderSource != nil || computeCommand.pipeline != nil, "computeCommand.fragmentShaderSource or pipeline is required") 64 | guard let outputTexture = computeCommand.outputTexture else { 65 | assertionFailure("computeCommand.outputTexture is required") 66 | return 67 | } 68 | 69 | let framebuffer = Framebuffer(maximumColorAttachments: 1, colorTextures: [computeCommand.outputTexture!], depthTexture: nil, stencilTexture: nil) 70 | let passState = PassState() 71 | passState.context = context 72 | passState.framebuffer = framebuffer 73 | 74 | let vertexArray = computeCommand.vertexArray ?? context.getViewportQuadVertexArray() 75 | let pipeline = computeCommand.pipeline ?? createViewportQuadPipeline(computeCommand.fragmentShaderSource!) 76 | let renderState = RenderState( 77 | device: context.device, 78 | viewport: Cartesian4(x: 0, y: 0, width: Double(outputTexture.width), height: Double(outputTexture.height))) 79 | 80 | 81 | var clearCommand = ClearCommand(color: Cartesian4(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)) 82 | clearCommand.renderState = renderState 83 | clearCommand.execute(context, passState: passState) 84 | 85 | let drawCommand = DrawCommand() 86 | drawCommand.vertexArray = vertexArray 87 | drawCommand.renderState = renderState 88 | drawCommand.pipeline = pipeline 89 | drawCommand.uniformMap = computeCommand.uniformMap 90 | if let map = drawCommand.uniformMap { 91 | map.uniformBufferProvider = drawCommand.pipeline!.shaderProgram.createUniformBufferProvider(context.device, deallocationBlock: nil) 92 | } 93 | 94 | guard let renderPass = context.createRenderPass(passState) else { 95 | logPrint(.critical, "Cannot create renderPass") 96 | return 97 | } 98 | drawCommand.execute(context, renderPass: renderPass) 99 | renderPass.complete() 100 | //FIXME: postExecute 101 | if let postExecute = computeCommand.postExecute { 102 | postExecute(computeCommand.outputTexture!) 103 | } 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /CesiumKit/Scene/OffscreenQuadPrimitive.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OffscreenQuadPrimitive 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 12/03/2016. 6 | // Copyright © 2016 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** A render-to-texture primitive allowing multiple draw commands. 12 | Most useful for creating HUDs and other UI. 13 | */ 14 | open class OffscreenQuadPrimitive: Primitive { 15 | 16 | let height, width: Int 17 | 18 | fileprivate weak var _context: Context! 19 | 20 | fileprivate var _text = [TextRenderer]() 21 | 22 | fileprivate var _textCommands = [DrawCommand]() 23 | 24 | fileprivate var _rectangles = [DrawCommand]() 25 | 26 | fileprivate let _passState: PassState 27 | 28 | fileprivate let _clearCommand = ClearCommand( 29 | color: Color(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0) 30 | ) 31 | 32 | init (context: Context, width: Int, height: Int) { 33 | _context = context 34 | self.width = width 35 | self.height = height 36 | 37 | let options = TextureOptions( 38 | width: width, 39 | height: height, 40 | premultiplyAlpha: false, 41 | usage: [.ShaderRead, .RenderTarget]) 42 | 43 | let texture = Texture(context: context, options: options) 44 | 45 | let framebuffer = Framebuffer( 46 | maximumColorAttachments: context.limits.maximumColorAttachments, 47 | colorTextures: [texture] 48 | ) 49 | _passState = PassState() 50 | _passState.context = context 51 | _passState.framebuffer = framebuffer 52 | } 53 | 54 | open func addString (_ string: String, fontName: String, color: Color, pointSize: Int, rectangle: Cartesian4) -> Int { 55 | let text = TextRenderer(string: string, fontName: fontName, color: color, pointSize: pointSize, viewportRect: rectangle, offscreenTarget: true) 56 | _text.append(text) 57 | return _text.count-1 58 | } 59 | 60 | open func updateString (_ index: Int, newText: String) { 61 | 62 | } 63 | 64 | open func addRectangle (_ bounds: Cartesian4, material: Material) -> Int { 65 | 66 | let rs = RenderState( 67 | device: _context.device, 68 | viewport : bounds 69 | ) 70 | 71 | let overrides = ViewportQuadOverrides( 72 | renderState: rs, 73 | uniformMap: material.uniformMap, 74 | owner: self 75 | ) 76 | let fs = ShaderSource( 77 | sources: [material.shaderSource, Shaders["ViewportQuadFS"]].flatMap { $0 } 78 | ) 79 | let command = _context.createViewportQuadCommand( 80 | fragmentShaderSource: fs, 81 | overrides: overrides, 82 | depthStencil: false, 83 | blendingState: nil) 84 | 85 | _rectangles.append(command) 86 | 87 | return _rectangles.count-1 88 | } 89 | 90 | 91 | override func update (_ frameState: inout FrameState) { 92 | 93 | _textCommands.removeAll() 94 | 95 | for text in _text { 96 | text.update(&frameState) 97 | } 98 | } 99 | 100 | /** 101 | * Executes the draw command. 102 | * 103 | * @param {Context} context The renderer context in which to draw. 104 | * @param {RenderPass} [renderPass] The render pass this command is part of. 105 | * @param {RenderState} [renderState] The render state that will override the render state of the command. 106 | * @param {RenderPipeline} [renderPipeline] The render pipeline that will override the shader program of the command. 107 | */ 108 | func execute(_ context: Context) { 109 | 110 | guard let renderPass = context.createRenderPass(_passState) else { 111 | return 112 | } 113 | _clearCommand.execute(context, passState: _passState) 114 | for command in _rectangles { 115 | command.execute(context, renderPass: renderPass) 116 | } 117 | 118 | for command in _textCommands { 119 | command.execute(context, renderPass: renderPass) 120 | } 121 | renderPass.complete() 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /CesiumKit/Scene/BlendingState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlendingState.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 25/10/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | /** 10 | * The blending state combines {@link BlendEquation} and {@link BlendFunction} and the 11 | * enabled flag to define the full blending state for combining source and 12 | * destination fragments when rendering. 13 | *

14 | * This is a helper when using custom render states with {@link Appearance#renderState}. 15 | *

16 | * 17 | * @namespace 18 | * @alias BlendingState 19 | */ 20 | struct BlendingState: Equatable, CustomStringConvertible { 21 | let enabled: Bool 22 | let equationRgb: BlendEquation 23 | let equationAlpha: BlendEquation 24 | let functionSourceRgb: BlendFunction 25 | let functionSourceAlpha: BlendFunction 26 | let functionDestinationRgb: BlendFunction 27 | let functionDestinationAlpha: BlendFunction 28 | let color: Cartesian4? 29 | 30 | /** 31 | * Blending is disabled. 32 | * 33 | * @type {Object} 34 | * @constant 35 | */ 36 | static func Disabled() -> BlendingState { 37 | return BlendingState(enabled: false, 38 | equationRgb: .add, 39 | equationAlpha: .add, 40 | functionSourceRgb: .zero, 41 | functionSourceAlpha: .zero, 42 | functionDestinationRgb: .zero, 43 | functionDestinationAlpha: .zero, 44 | color: nil) 45 | } 46 | 47 | /** 48 | * Blending is enabled using alpha blending, source(source.alpha) + destination(1 - source.alpha). 49 | * 50 | * @type {Object} 51 | * @constant 52 | */ 53 | static func AlphaBlend() -> BlendingState { 54 | return BlendingState(enabled: true, 55 | equationRgb : .add, 56 | equationAlpha : .add, 57 | functionSourceRgb : .sourceAlpha, 58 | functionSourceAlpha : .sourceAlpha, 59 | functionDestinationRgb : .oneMinusSourceAlpha, 60 | functionDestinationAlpha : .oneMinusSourceAlpha, 61 | color: nil) 62 | } 63 | 64 | static func AlphaBlend(_ color: Cartesian4) -> BlendingState { 65 | return BlendingState(enabled: true, 66 | equationRgb : .add, 67 | equationAlpha : .add, 68 | functionSourceRgb : .sourceAlpha, 69 | functionSourceAlpha : .sourceAlpha, 70 | functionDestinationRgb : .oneMinusSourceAlpha, 71 | functionDestinationAlpha : .oneMinusSourceAlpha, 72 | color: color) 73 | } 74 | 75 | /** 76 | * Blending is enabled using alpha blending with premultiplied alpha, source + destination(1 - source.alpha). 77 | * 78 | * @type {Object} 79 | * @constant 80 | */ 81 | static func PremultipliedAlphaBlend(_ color: Cartesian4) -> BlendingState { 82 | return BlendingState(enabled : true, 83 | equationRgb : .add, 84 | equationAlpha : .add, 85 | functionSourceRgb : .one, 86 | functionSourceAlpha : .one, 87 | functionDestinationRgb : .oneMinusSourceAlpha, 88 | functionDestinationAlpha : .oneMinusSourceAlpha, 89 | color: color) 90 | } 91 | 92 | /** 93 | * Blending is enabled using additive blending, source(source.alpha) + destination. 94 | * 95 | * @type {Object} 96 | * @constant 97 | */ 98 | static func AdditiveBlend(_ color: Cartesian4) -> BlendingState { 99 | return BlendingState(enabled : true, 100 | equationRgb : .add, 101 | equationAlpha : .add, 102 | functionSourceRgb : .sourceAlpha, 103 | functionSourceAlpha : .sourceAlpha, 104 | functionDestinationRgb : .one, 105 | functionDestinationAlpha : .one, 106 | color: color) 107 | } 108 | 109 | var description: String { 110 | return "r\(equationRgb.rawValue):a\(equationAlpha.rawValue):sr\(functionSourceRgb.rawValue):sa\(functionSourceAlpha.rawValue):dr\(functionDestinationRgb.rawValue):da\(functionDestinationAlpha.rawValue):c\(color?.simdType.debugDescription ?? "nil")" 111 | 112 | } 113 | } 114 | 115 | func == (lhs: BlendingState, rhs: BlendingState) -> Bool { 116 | return lhs.description == rhs.description 117 | } 118 | -------------------------------------------------------------------------------- /CesiumKit/Scene/TileImagery.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TileImagery.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 16/08/14. 6 | // Copyright (c) 2014 Test Toast. All rights reserved. 7 | // 8 | 9 | /** 10 | * The assocation between a terrain tile and an imagery tile. 11 | * 12 | * @alias TileImagery 13 | * @private 14 | * 15 | * @param {Imagery} imagery The imagery tile. 16 | * @param {Cartesian4} textureCoordinateRectangle The texture rectangle of the tile that is covered 17 | * by the imagery, where X=west, Y=south, Z=east, W=north. 18 | */ 19 | class TileImagery { 20 | 21 | var readyImagery: Imagery? = nil 22 | 23 | var loadingImagery: Imagery? = nil 24 | 25 | var textureCoordinateRectangle: Cartesian4? = nil 26 | 27 | var textureTranslationAndScale: Cartesian4? = nil 28 | 29 | init(imagery: Imagery, textureCoordinateRectangle: Cartesian4? = nil) { 30 | loadingImagery = imagery 31 | self.textureCoordinateRectangle = textureCoordinateRectangle 32 | textureTranslationAndScale = nil 33 | } 34 | 35 | /** 36 | * Frees the resources held by this instance. 37 | */ 38 | deinit { 39 | if readyImagery != nil { 40 | readyImagery!.releaseReference() 41 | } 42 | 43 | if loadingImagery != nil { 44 | loadingImagery!.releaseReference() 45 | } 46 | } 47 | 48 | /** 49 | * Processes the load state machine for this instance. 50 | * 51 | * @param {Tile} tile The tile to which this instance belongs. 52 | * @param {FrameState} frameState The frameState. 53 | * @returns {Boolean} True if this instance is done loading; otherwise, false. 54 | */ 55 | func processStateMachine (_ tile: QuadtreeTile, frameState: inout FrameState) -> Bool { 56 | 57 | let imageryLayer = loadingImagery!.imageryLayer 58 | 59 | loadingImagery!.processStateMachine(frameState: &frameState) 60 | 61 | if loadingImagery!.state == .ready { 62 | if readyImagery != nil { 63 | readyImagery!.releaseReference() 64 | } 65 | readyImagery = loadingImagery 66 | loadingImagery = nil 67 | textureTranslationAndScale = imageryLayer.calculateTextureTranslationAndScale(tile, tileImagery: self) 68 | return true // done loading 69 | } 70 | 71 | // Find some ancestor imagery we can use while this imagery is still loading. 72 | var ancestor = loadingImagery!.parent 73 | var closestAncestorThatNeedsLoading: Imagery? 74 | while ancestor != nil && ancestor!.state != ImageryState.ready { 75 | if ancestor!.state != ImageryState.failed && ancestor!.state != ImageryState.invalid { 76 | // ancestor is still loading 77 | closestAncestorThatNeedsLoading = closestAncestorThatNeedsLoading ?? ancestor! 78 | } 79 | ancestor = ancestor!.parent 80 | } 81 | 82 | if readyImagery !== ancestor { 83 | if let readyImagery = readyImagery { 84 | readyImagery.releaseReference() 85 | } 86 | 87 | readyImagery = ancestor 88 | 89 | if let ancestor = ancestor { 90 | ancestor.addReference() 91 | textureTranslationAndScale = imageryLayer.calculateTextureTranslationAndScale(tile, tileImagery: self) 92 | } 93 | } 94 | 95 | if loadingImagery!.state == .failed || loadingImagery!.state == .invalid { 96 | if let closestAncestorThatNeedsLoading = closestAncestorThatNeedsLoading { 97 | // Push the ancestor's load process along a bit. This is necessary because some ancestor imagery 98 | // tiles may not be attached directly to a terrain tile. Such tiles will never load if 99 | // we don't do it here. 100 | closestAncestorThatNeedsLoading.processStateMachine(frameState: &frameState) 101 | return false 102 | } else { 103 | // This imagery tile is failed or invalid, and we have the "best available" substitute. So we're done loading. 104 | return true // done loading 105 | } 106 | } 107 | return false // not done loading 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /CesiumKit/Scene/FXAA.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FXAA.swift 3 | // CesiumKit 4 | // 5 | // Created by Ryan Walklin on 20/11/2015. 6 | // Copyright © 2015 Test Toast. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import MetalKit 11 | 12 | class FXAA { 13 | /** 14 | * @private 15 | */ 16 | fileprivate var _texture: Texture? = nil 17 | fileprivate var _depthTexture: Texture? = nil 18 | 19 | fileprivate var _fbo: Framebuffer? = nil 20 | fileprivate var _command: DrawCommand? = nil 21 | 22 | fileprivate var _clearCommand: ClearCommand 23 | 24 | init () { 25 | _clearCommand = ClearCommand( 26 | color : Cartesian4(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0), 27 | depth : 1.0 28 | ) 29 | _clearCommand.owner = self 30 | } 31 | 32 | func update (_ context: Context) { 33 | let width = context.width 34 | let height = context.height 35 | 36 | let textureChanged = _texture == nil || _texture!.width != width || _texture!.height != height 37 | if textureChanged { 38 | _depthTexture = nil 39 | 40 | _texture = Texture( 41 | context: context, 42 | options: TextureOptions( 43 | width: width, 44 | height: height, 45 | usage: [.ShaderRead, .RenderTarget]) 46 | ) 47 | 48 | if context.depthTexture { 49 | _depthTexture = Texture( 50 | context: context, 51 | options: TextureOptions( 52 | width: width, 53 | height: height, 54 | pixelFormat: .depth32FloatStencil8, 55 | usage: .RenderTarget) 56 | ) 57 | } 58 | } 59 | 60 | if _fbo == nil || textureChanged { 61 | 62 | _fbo = Framebuffer( 63 | maximumColorAttachments: 1, 64 | colorTextures : [_texture!], 65 | depthTexture : _depthTexture 66 | ) 67 | } 68 | 69 | if _command == nil { 70 | var overrides = ViewportQuadOverrides() 71 | overrides.renderState = RenderState(device: context.device) 72 | overrides.owner = self 73 | _command = context.createViewportQuadCommand( 74 | fragmentShaderSource: ShaderSource(sources: [Shaders["FXAAFS"]!]), 75 | overrides: overrides 76 | ) 77 | } 78 | 79 | if textureChanged { 80 | let uniformMap = FXAAUniformMap() 81 | uniformMap.texture = _texture 82 | uniformMap.step = Cartesian2(x: 1.0 / Double(_texture!.width), y: 1.0 / Double(_texture!.height)) 83 | uniformMap.uniformBufferProvider = _command!.pipeline!.shaderProgram.createUniformBufferProvider(context.device, deallocationBlock: nil) 84 | _command!.uniformMap = uniformMap 85 | } 86 | } 87 | 88 | func execute (_ context: Context, renderPass: RenderPass) { 89 | _command!.execute(context, renderPass: renderPass) 90 | } 91 | 92 | func clear (_ context: Context, passState: PassState, clearColor: Cartesian4) { 93 | let framebuffer = passState.framebuffer 94 | 95 | passState.framebuffer = _fbo 96 | _clearCommand.color = clearColor 97 | _clearCommand.execute(context, passState: passState) 98 | 99 | passState.framebuffer = framebuffer 100 | } 101 | 102 | 103 | func getColorFramebuffer() -> Framebuffer? { 104 | return _fbo 105 | } 106 | 107 | } 108 | 109 | private struct FXAAUniformStruct: UniformStruct { 110 | var step = float2() 111 | } 112 | 113 | class FXAAUniformMap: NativeUniformMap { 114 | 115 | var step: Cartesian2 { 116 | get { 117 | return Cartesian2(simd: simd_double(_uniformStruct.step)) 118 | } 119 | set { 120 | _uniformStruct.step = newValue.floatRepresentation 121 | } 122 | } 123 | 124 | var texture : Texture? 125 | 126 | var uniformBufferProvider: UniformBufferProvider! = nil 127 | 128 | fileprivate var _uniformStruct = FXAAUniformStruct() 129 | 130 | var uniformDescriptors: [UniformDescriptor] = [ 131 | UniformDescriptor(name: "u_step", type: .floatVec2, count: 1) 132 | ] 133 | 134 | lazy var uniformUpdateBlock: UniformUpdateBlock = { buffer in 135 | buffer.write(from: &self._uniformStruct, length: MemoryLayout.size) 136 | return [self.texture!] 137 | } 138 | 139 | } 140 | 141 | --------------------------------------------------------------------------------