├── Screenshot.png ├── RealityKitLaunchScreen.mp4 ├── RealityKitLaunchScreen.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── aheze.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── README.md ├── RealityKitLaunchScreen ├── RealityKitLaunchScreenApp.swift ├── LaunchModels.swift ├── LaunchViewController.swift ├── ContentView.swift ├── Utilities.swift ├── LaunchConstants.swift ├── LaunchViewModel.swift └── LaunchVC+Scene.swift └── LICENSE /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aheze/RealityKitLaunchScreen/HEAD/Screenshot.png -------------------------------------------------------------------------------- /RealityKitLaunchScreen.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aheze/RealityKitLaunchScreen/HEAD/RealityKitLaunchScreen.mp4 -------------------------------------------------------------------------------- /RealityKitLaunchScreen.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RealityKitLaunchScreen 2 | 3 | A launch screen made with SwiftUI and RealityKit. Used in the [Find](http://getfind.app/) app. 4 | 5 | https://user-images.githubusercontent.com/49819455/167744031-f1f2503d-c056-4bc0-a2b7-925e4e3a3749.mp4 6 | 7 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen/RealityKitLaunchScreenApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealityKitLaunchScreenApp.swift 3 | // RealityKitLaunchScreen 4 | // 5 | // Created by A. Zheng (github.com/aheze) on 5/10/22. 6 | // Copyright © 2022 A. Zheng. All rights reserved. 7 | // 8 | 9 | 10 | import SwiftUI 11 | 12 | @main 13 | struct RealityKitLaunchScreenApp: App { 14 | var body: some Scene { 15 | WindowGroup { 16 | ContentView() 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen.xcodeproj/xcuserdata/aheze.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RealityKitLaunchScreen.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 A. Zheng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen/LaunchModels.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchModels.swift 3 | // Find 4 | // 5 | // Created by A. Zheng (github.com/aheze) on 4/16/22. 6 | // Copyright © 2022 A. Zheng. All rights reserved. 7 | // 8 | 9 | import RealityKit 10 | import UIKit 11 | 12 | /// Row of launch text 13 | /// X X X X X X 14 | struct LaunchTextRow { 15 | var text = [LaunchText]() 16 | } 17 | 18 | struct LaunchText { 19 | var character: String 20 | var isPartOfFind = false /// if true, make blue 21 | 22 | /// height, change this later 23 | var yOffset = Float(0) 24 | 25 | var additionalXOffset = Float(0) 26 | var additionalZOffset = Float(0) 27 | 28 | var color: UIColor { 29 | if isPartOfFind { 30 | return LaunchConstants.backgroundColor 31 | } else { 32 | return UIColor.clear 33 | } 34 | } 35 | } 36 | 37 | struct LaunchTile { 38 | var text: LaunchText 39 | var entity: ModelEntity 40 | var location: Location /// populate from index inside `LaunchTextRow` 41 | var initialTransform: Transform 42 | var midTransform: Transform 43 | var finalTransform: Transform? /// only for Find tiles 44 | 45 | struct Location: Equatable { 46 | var x: Int 47 | var z: Int 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen/LaunchViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchViewController.swift 3 | // Find 4 | // 5 | // Created by A. Zheng (github.com/aheze) on 4/16/22. 6 | // Copyright © 2022 A. Zheng. All rights reserved. 7 | // 8 | 9 | import RealityKit 10 | import SwiftUI 11 | 12 | class LaunchViewController: UIViewController { 13 | var model: LaunchViewModel 14 | 15 | lazy var sceneView: ARView? = ARView() 16 | var baseEntity: ModelEntity? 17 | var camera: PerspectiveCamera? 18 | 19 | init(model: LaunchViewModel) { 20 | self.model = model 21 | super.init(nibName: nil, bundle: nil) 22 | } 23 | 24 | @available(*, unavailable) 25 | required init?(coder: NSCoder) { 26 | fatalError("init(coder:) has not been implemented") 27 | } 28 | 29 | override func loadView() { 30 | /** 31 | Instantiate the base `view`. 32 | */ 33 | view = UIView() 34 | view.backgroundColor = .clear 35 | setupScene() 36 | } 37 | } 38 | 39 | struct LaunchViewControllerRepresentable: UIViewControllerRepresentable { 40 | @ObservedObject var model: LaunchViewModel 41 | 42 | func makeUIViewController(context: Context) -> LaunchViewController { 43 | LaunchViewController(model: model) 44 | } 45 | 46 | func updateUIViewController(_ uiViewController: LaunchViewController, context: Context) {} 47 | } 48 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // RealityKitLaunchScreen 4 | // 5 | // Created by A. Zheng (github.com/aheze) on 5/10/22. 6 | // Copyright © 2022 A. Zheng. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ContentView: View { 12 | @StateObject var model = LaunchViewModel() 13 | var body: some View { 14 | VStack { 15 | VStack(alignment: .leading) { 16 | Text("Find") 17 | .font(.system(size: 42, weight: .bold, design: .rounded)) 18 | 19 | Text("An app to find text in real life.") 20 | .font(.system(size: 28, weight: .bold, design: .rounded)) 21 | } 22 | .frame(maxWidth: .infinity, alignment: .leading) 23 | .padding(24) 24 | 25 | Spacer() 26 | 27 | Group { 28 | Text("Use this launch screen however you'd like, but it would be nice if you linked to the GitHub repo.") 29 | + 30 | Text(" https://github.com/aheze") 31 | } 32 | .font(.system(size: 24, weight: .semibold)) 33 | .accentColor(.white.opacity(0.75)) 34 | .frame(maxWidth: .infinity, alignment: .leading) 35 | .padding(24) 36 | } 37 | .foregroundColor(.white) 38 | .background( 39 | ZStack { 40 | Color(LaunchConstants.backgroundColor) 41 | 42 | LaunchViewControllerRepresentable(model: model) 43 | } 44 | .edgesIgnoringSafeArea(.all) 45 | ) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen/Utilities.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utilities.swift 3 | // RealityKitLaunchScreen 4 | // 5 | // Created by A. Zheng (github.com/aheze) on 5/10/22. 6 | // Copyright © 2022 A. Zheng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIView { 12 | func pinEdgesToSuperview(padding: UIEdgeInsets = .zero) { 13 | guard let superview = superview else { return } 14 | self.translatesAutoresizingMaskIntoConstraints = false 15 | NSLayoutConstraint.activate([ 16 | self.topAnchor.constraint(equalTo: superview.topAnchor, constant: padding.top), 17 | self.rightAnchor.constraint(equalTo: superview.rightAnchor, constant: -padding.right), 18 | self.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: -padding.bottom), 19 | self.leftAnchor.constraint(equalTo: superview.leftAnchor, constant: padding.left) 20 | ]) 21 | } 22 | } 23 | 24 | extension BinaryInteger { 25 | var degreesToRadians: CGFloat { CGFloat(self) * .pi / 180 } 26 | var asRadians: Float { Float(self) * .pi / 180 } /// degrees to radians, for RealityKit 27 | } 28 | 29 | extension FloatingPoint { 30 | var degreesToRadians: Self { self * .pi / 180 } 31 | var radiansToDegrees: Self { self * 180 / .pi } 32 | } 33 | 34 | extension UIColor { 35 | convenience init(hex: UInt, alpha: CGFloat = 1) { 36 | self.init( 37 | red: CGFloat((hex & 0xFF0000) >> 16) / 255.0, 38 | green: CGFloat((hex & 0x00FF00) >> 8) / 255.0, 39 | blue: CGFloat(hex & 0x0000FF) / 255.0, 40 | alpha: alpha 41 | ) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen/LaunchConstants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchConstants.swift 3 | // Find 4 | // 5 | // Created by A. Zheng (github.com/aheze) on 4/16/22. 6 | // Copyright © 2022 A. Zheng. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum LaunchConstants { 12 | /// use for the background and also the tile color 13 | static let backgroundColor = UIColor(hex: 0x62008D) 14 | 15 | static let textDepth = Float(0.008) 16 | static let textHeight = CGFloat(0.08) 17 | 18 | static let tileGap = Float(0.01) 19 | static let tileLength = Float(0.1) 20 | static let tileDepth = Float(0.02) 21 | static let tileCornerRadius = Float(0.05) 22 | 23 | static let tileFont = CTFontCreateWithName("SFUI-Semibold" as CFString, LaunchConstants.textHeight, nil) 24 | 25 | static let cameraPositionInitial = SIMD3( 26 | x: 0.000001, /// can't be 0 27 | y: 0.054, /// height of camera 28 | z: 0.04 /// larger = steeper/more sloped tiles 29 | ) 30 | 31 | static let cameraPositionFinal = SIMD3( 32 | x: 0.024, 33 | y: 0.96, /// height of camera 34 | z: 0.3 /// larger = steeper/more sloped tiles 35 | ) 36 | 37 | static let cameraPositionBeforeEnter = SIMD3( 38 | x: 0.000001, 39 | y: 0.8, 40 | z: 0 41 | ) 42 | 43 | static let cameraPositionAfterEnter = SIMD3( 44 | x: 0, 45 | y: 0.03, 46 | z: 0 47 | ) 48 | 49 | static let tileYOffsetLimit = Float(0.1) 50 | static let tileDiagonalOffsetLimit = Float(0.2) 51 | 52 | static let findTileFinalYOffset = Float(0.08) 53 | 54 | static let tilesInitialAnimationDuration = CGFloat(9) 55 | static let tilesFinalAnimationDuration = CGFloat(4) 56 | 57 | static let tilesRepeatingAnimationDelay = CGFloat(1.2) 58 | 59 | /// time to flip half way. 60 | /// tiles are flipped 360 degrees, so this is multiplied by 2. 61 | static let tilesRepeatingAnimationDuration = CGFloat(0.9) 62 | 63 | static let findTileAnimationDelay = CGFloat(5.5) 64 | static let findTileAnimationIndividualDuration = CGFloat(0.5) 65 | static let findTileAnimationTotalDuration = CGFloat(1) /// time to start all 4 tiles 66 | 67 | static let enterBeforeDuration = CGFloat(1.2) 68 | static let enterAfterDuration = CGFloat(1.4) 69 | } 70 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen/LaunchViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchViewModel.swift 3 | // Find 4 | // 5 | // Created by A. Zheng (github.com/aheze) on 4/16/22. 6 | // Copyright © 2022 A. Zheng. All rights reserved. 7 | // 8 | 9 | import Combine 10 | import SwiftUI 11 | 12 | class LaunchViewModel: ObservableObject { 13 | @Published var showingUI = false 14 | 15 | var tiles = [LaunchTile]() 16 | 17 | var textRows = [ 18 | LaunchTextRow( 19 | text: [ 20 | LaunchText(character: "∮"), 21 | LaunchText(character: "π"), 22 | LaunchText(character: "⧑"), 23 | LaunchText(character: "∞"), 24 | LaunchText(character: "∴"), 25 | LaunchText(character: "➤") 26 | ] 27 | ), 28 | LaunchTextRow( 29 | text: [ 30 | LaunchText(character: "♛"), 31 | LaunchText(character: "♣︎"), 32 | LaunchText(character: "♦︎"), 33 | LaunchText(character: "♥︎"), 34 | LaunchText(character: "♠︎"), 35 | LaunchText(character: "♜") 36 | ] 37 | ), 38 | LaunchTextRow( 39 | text: [ 40 | LaunchText(character: "✭"), 41 | LaunchText(character: "✣"), 42 | LaunchText(character: "✿"), 43 | LaunchText(character: "❂"), 44 | LaunchText(character: "❃"), 45 | LaunchText(character: "◼︎") 46 | ] 47 | ), 48 | LaunchTextRow( 49 | text: [ 50 | LaunchText(character: "𝛴"), 51 | LaunchText(character: "𝜽"), 52 | LaunchText(character: "𝛹"), 53 | LaunchText(character: "𝜔"), 54 | LaunchText(character: "𝛼"), 55 | LaunchText(character: "𝛺") 56 | ] 57 | ), 58 | LaunchTextRow( 59 | text: [ 60 | LaunchText(character: "❖"), 61 | LaunchText(character: "F", isPartOfFind: true), 62 | LaunchText(character: "I", isPartOfFind: true), 63 | LaunchText(character: "N", isPartOfFind: true), 64 | LaunchText(character: "D", isPartOfFind: true), 65 | LaunchText(character: "❖") 66 | ] 67 | ), 68 | LaunchTextRow( 69 | text: [ 70 | LaunchText(character: "∮"), 71 | LaunchText(character: "π"), 72 | LaunchText(character: "⧑"), 73 | LaunchText(character: "∞"), 74 | LaunchText(character: "∴"), 75 | LaunchText(character: "➤") 76 | ] 77 | ), 78 | LaunchTextRow( 79 | text: [ 80 | LaunchText(character: "♛"), 81 | LaunchText(character: "♣︎"), 82 | LaunchText(character: "♦︎"), 83 | LaunchText(character: "♥︎"), 84 | LaunchText(character: "♠︎"), 85 | LaunchText(character: "♜") 86 | ] 87 | ), 88 | LaunchTextRow( 89 | text: [ 90 | LaunchText(character: "✭"), 91 | LaunchText(character: "✣"), 92 | LaunchText(character: "✿"), 93 | LaunchText(character: "❂"), 94 | LaunchText(character: "❃"), 95 | LaunchText(character: "◼︎") 96 | ] 97 | ), 98 | LaunchTextRow( 99 | text: [ 100 | LaunchText(character: "𝛴"), 101 | LaunchText(character: "𝜽"), 102 | LaunchText(character: "𝛹"), 103 | LaunchText(character: "𝜔"), 104 | LaunchText(character: "𝛼"), 105 | LaunchText(character: "𝛺") 106 | ] 107 | ) 108 | ] 109 | 110 | var width: Int { 111 | textRows.first?.text.count ?? 0 112 | } 113 | 114 | var height: Int { 115 | textRows.count 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen/LaunchVC+Scene.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchVC+Scene.swift 3 | // Find 4 | // 5 | // Created by A. Zheng (github.com/aheze) on 4/16/22. 6 | // Copyright © 2022 A. Zheng. All rights reserved. 7 | // 8 | 9 | import RealityKit 10 | import SceneKit 11 | import UIKit 12 | 13 | extension LaunchViewController { 14 | func setupScene() { 15 | _ = sceneView 16 | 17 | guard let sceneView = sceneView else { return } 18 | sceneView.cameraMode = .nonAR 19 | sceneView.environment.background = .color(.clear) 20 | view.addSubview(sceneView) 21 | sceneView.pinEdgesToSuperview() 22 | 23 | let anchor = AnchorEntity() 24 | sceneView.scene.addAnchor(anchor) 25 | 26 | let baseEntity = ModelEntity() 27 | self.baseEntity = baseEntity 28 | anchor.addChild(baseEntity) 29 | 30 | self.adjustPositions() 31 | self.addTiles(to: baseEntity) 32 | 33 | let camera = PerspectiveCamera() 34 | self.camera = camera 35 | let cameraAnchor = AnchorEntity(world: .zero) 36 | cameraAnchor.addChild(camera) 37 | sceneView.scene.addAnchor(cameraAnchor) 38 | camera.look(at: .zero, from: LaunchConstants.cameraPositionInitial, relativeTo: baseEntity) 39 | 40 | print("animating") 41 | self.animateScene() 42 | } 43 | 44 | func animateScene() { 45 | guard let camera = self.camera else { return } 46 | guard let baseEntity = self.baseEntity else { return } 47 | 48 | for tile in self.model.tiles { 49 | tile.entity.move( 50 | to: tile.midTransform, 51 | relativeTo: nil, 52 | duration: LaunchConstants.tilesInitialAnimationDuration, 53 | timingFunction: .easeInOut 54 | ) 55 | } 56 | 57 | /// one tiles done animating, start flipping them 58 | DispatchQueue.main.asyncAfter(deadline: .now() + LaunchConstants.tilesInitialAnimationDuration) { 59 | let normalTiles = self.model.tiles.filter { !$0.text.isPartOfFind } 60 | self.flipRandomNormalTile(in: normalTiles) 61 | } 62 | 63 | DispatchQueue.main.asyncAfter(deadline: .now() + LaunchConstants.findTileAnimationDelay) { 64 | let findTiles = self.model.tiles.filter { $0.text.isPartOfFind } 65 | for index in findTiles.indices { 66 | let tile = findTiles[index] 67 | guard let finalTransform = tile.finalTransform else { continue } 68 | 69 | let percentage = Double(index) / 3 70 | let delay = percentage * LaunchConstants.findTileAnimationTotalDuration 71 | DispatchQueue.main.asyncAfter(deadline: .now() + delay) { 72 | tile.entity.move( 73 | to: finalTransform, 74 | relativeTo: nil, 75 | duration: LaunchConstants.findTileAnimationIndividualDuration, 76 | timingFunction: .easeInOut 77 | ) 78 | } 79 | } 80 | } 81 | 82 | camera.look(at: .zero, from: LaunchConstants.cameraPositionFinal, relativeTo: baseEntity) 83 | let transform = camera.transform /// get the final transform 84 | camera.look(at: .zero, from: LaunchConstants.cameraPositionInitial, relativeTo: baseEntity) 85 | 86 | camera.move( 87 | to: transform, 88 | relativeTo: nil, 89 | duration: 5, 90 | timingFunction: .easeInOut 91 | ) 92 | } 93 | 94 | func flipRandomNormalTile(in tiles: [LaunchTile]) { 95 | func flip(tile: LaunchTile, reversed: Bool) { 96 | let multiplier = Float(reversed ? -1 : 1) 97 | var transform = tile.midTransform 98 | transform.rotation = simd_quatf( 99 | angle: Float(180.degreesToRadians) * multiplier, 100 | axis: [0, 0, 1] 101 | ) 102 | tile.entity.move( 103 | to: transform, 104 | relativeTo: nil, 105 | duration: LaunchConstants.tilesRepeatingAnimationDuration, 106 | timingFunction: .easeInOut 107 | ) 108 | DispatchQueue.main.asyncAfter(deadline: .now() + LaunchConstants.tilesRepeatingAnimationDuration) { 109 | transform.rotation = simd_quatf( 110 | angle: Float(360.degreesToRadians) * multiplier, 111 | axis: [0, 0, 1] 112 | ) 113 | tile.entity.move( 114 | to: transform, 115 | relativeTo: nil, 116 | duration: LaunchConstants.tilesRepeatingAnimationDuration, 117 | timingFunction: .easeInOut 118 | ) 119 | } 120 | } 121 | 122 | guard let randomTile = tiles.randomElement() else { return } 123 | 124 | let location = randomTile.location 125 | let mirroringLocation = LaunchTile.Location( 126 | x: model.width - 1 - location.x, 127 | z: model.height - 1 - location.z 128 | ) 129 | 130 | let mirroringTile = tiles.first { $0.location == mirroringLocation } 131 | 132 | flip(tile: randomTile, reversed: false) 133 | if let mirroringTile = mirroringTile { 134 | flip(tile: mirroringTile, reversed: true) 135 | } 136 | 137 | DispatchQueue.main.asyncAfter(deadline: .now() + LaunchConstants.tilesRepeatingAnimationDelay * 2) { 138 | self.flipRandomNormalTile(in: tiles) 139 | } 140 | } 141 | 142 | func adjustPositions() { 143 | let modelXCenter = Float(model.width - 1) / 2 /// should be 2.5, which corresponds to a `rowIndex` / `textIndex` 144 | let modelZCenter = Float(model.height - 1) / 2 145 | let maxValue = modelXCenter * modelZCenter 146 | 147 | for rowIndex in model.textRows.indices { 148 | let row = model.textRows[rowIndex] 149 | for textIndex in row.text.indices { 150 | let x = Float(textIndex) - modelXCenter 151 | let z = Float(rowIndex) - modelZCenter 152 | let value = abs(x * z) 153 | 154 | let percentageOfMaximum = value / maxValue 155 | 156 | let limit = LaunchConstants.tileYOffsetLimit * percentageOfMaximum 157 | let additionalXOffset = LaunchConstants.tileDiagonalOffsetLimit * (x / modelXCenter) 158 | let additionalZOffset = LaunchConstants.tileDiagonalOffsetLimit * (z / modelZCenter) 159 | 160 | model.textRows[rowIndex].text[textIndex].yOffset = limit 161 | model.textRows[rowIndex].text[textIndex].additionalXOffset = additionalXOffset 162 | model.textRows[rowIndex].text[textIndex].additionalZOffset = additionalZOffset 163 | } 164 | } 165 | } 166 | 167 | func addTiles(to baseEntity: ModelEntity) { 168 | func getStartingOffset(length: Int) -> Float { 169 | let totalTileLength = Float(length) * LaunchConstants.tileLength 170 | let totalTileGap = Float(length - 1) * LaunchConstants.tileGap 171 | let totalLength = totalTileLength + totalTileGap 172 | let offset = -totalLength / 2 + LaunchConstants.tileLength / 2 173 | return offset 174 | } 175 | 176 | /// get offset along one access 177 | func getAdditionalOffset(for index: Float, startingOffset: Float) -> Float { 178 | let lengthOffset = LaunchConstants.tileLength * index 179 | let gapOffset = LaunchConstants.tileGap * index 180 | let offset = startingOffset + lengthOffset + gapOffset 181 | return offset 182 | } 183 | 184 | /// start to the left 185 | let startingXOffset = getStartingOffset(length: model.width) 186 | let startingZOffset = getStartingOffset(length: model.height) 187 | 188 | var tiles = [LaunchTile]() 189 | for rowIndex in model.textRows.indices { 190 | let row = model.textRows[rowIndex] 191 | for textIndex in row.text.indices { 192 | let text = row.text[textIndex] 193 | 194 | let xOffset = getAdditionalOffset(for: Float(textIndex), startingOffset: startingXOffset) /// left to right 195 | let zOffset = getAdditionalOffset(for: Float(rowIndex), startingOffset: startingZOffset) /// back to front 196 | 197 | let tileEntity = getTileEntity(character: text.character, color: text.color) 198 | 199 | let initialPosition = SIMD3( 200 | x: xOffset + text.additionalXOffset, 201 | y: text.yOffset, 202 | z: zOffset + text.additionalZOffset 203 | ) 204 | let midPosition = SIMD3( 205 | x: xOffset, 206 | y: 0, 207 | z: zOffset 208 | ) 209 | var finalPosition: SIMD3? 210 | 211 | if text.isPartOfFind { 212 | finalPosition = SIMD3( 213 | x: xOffset, 214 | y: LaunchConstants.findTileFinalYOffset, 215 | z: zOffset 216 | ) 217 | } 218 | 219 | let initialTransform = Transform( 220 | scale: .one, 221 | rotation: simd_quatf(), 222 | translation: initialPosition 223 | ) 224 | let midTransform = Transform( 225 | scale: .one, 226 | rotation: simd_quatf(), 227 | translation: midPosition 228 | ) 229 | 230 | var finalTransform: Transform? 231 | if let finalPosition = finalPosition { 232 | finalTransform = Transform( 233 | scale: .one, 234 | rotation: simd_quatf(), 235 | translation: finalPosition 236 | ) 237 | } 238 | 239 | tileEntity.transform = initialTransform 240 | baseEntity.addChild(tileEntity) 241 | 242 | let tile = LaunchTile( 243 | text: text, 244 | entity: tileEntity, 245 | location: .init(x: textIndex, z: rowIndex), 246 | initialTransform: initialTransform, 247 | midTransform: midTransform, 248 | finalTransform: finalTransform 249 | ) 250 | tiles.append(tile) 251 | } 252 | } 253 | 254 | model.tiles = tiles 255 | } 256 | 257 | /// Gets half of the width, height and length of the bounding box, 258 | /// because the origin-point of the text is originally in the bottom-left corner of the bounding box. 259 | func getCompensation(for mesh: MeshResource) -> SIMD3 { 260 | let bounds = mesh.bounds 261 | let boxCenter = bounds.center 262 | var compensation = -boxCenter 263 | compensation *= [1, 1, 0] 264 | return compensation 265 | } 266 | } 267 | 268 | extension LaunchViewController { 269 | func getTileEntity(character: String, color: UIColor) -> ModelEntity { 270 | let tile = MeshResource.generateBox( 271 | width: LaunchConstants.tileLength, 272 | height: LaunchConstants.tileDepth, 273 | depth: LaunchConstants.tileLength, 274 | cornerRadius: LaunchConstants.tileCornerRadius, 275 | splitFaces: false 276 | ) 277 | 278 | let tileMaterial = SimpleMaterial(color: color, roughness: 0, isMetallic: true) 279 | let textMaterial = SimpleMaterial(color: UIColor.white.withAlphaComponent(0.25), roughness: 0, isMetallic: true) 280 | 281 | let text = MeshResource.generateText( 282 | character, 283 | extrusionDepth: LaunchConstants.textDepth, 284 | font: LaunchConstants.tileFont, 285 | containerFrame: .zero, 286 | alignment: .center, 287 | lineBreakMode: .byWordWrapping 288 | ) 289 | 290 | let tileEntity = ModelEntity(mesh: tile, materials: [tileMaterial]) 291 | 292 | let textEntity = ModelEntity(mesh: text, materials: [textMaterial]) 293 | let rotation = simd_quatf( 294 | angle: -.pi / 2, /* 45 Degrees */ 295 | axis: [1, 0, 0] /* About X axis */ 296 | ) 297 | 298 | let compensation = self.getCompensation(for: text) 299 | 300 | textEntity.transform.rotation = rotation 301 | textEntity.position.x = compensation.x 302 | textEntity.position.y = LaunchConstants.textDepth / 2 + LaunchConstants.tileDepth / 2 303 | textEntity.position.z = -compensation.y /// need to switch because of rotation 304 | tileEntity.addChild(textEntity) 305 | 306 | return tileEntity 307 | } 308 | } 309 | -------------------------------------------------------------------------------- /RealityKitLaunchScreen.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3C13D15E282B2F3F00ABF44B /* RealityKitLaunchScreenApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C13D15D282B2F3F00ABF44B /* RealityKitLaunchScreenApp.swift */; }; 11 | 3C13D160282B2F3F00ABF44B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C13D15F282B2F3F00ABF44B /* ContentView.swift */; }; 12 | 3C13D176282B2F8100ABF44B /* LaunchConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C13D16C282B2F8100ABF44B /* LaunchConstants.swift */; }; 13 | 3C13D178282B2F8100ABF44B /* LaunchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C13D16E282B2F8100ABF44B /* LaunchViewModel.swift */; }; 14 | 3C13D17A282B2F8100ABF44B /* LaunchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C13D170282B2F8100ABF44B /* LaunchViewController.swift */; }; 15 | 3C13D17B282B2F8100ABF44B /* LaunchModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C13D171282B2F8100ABF44B /* LaunchModels.swift */; }; 16 | 3C13D17E282B2F8100ABF44B /* LaunchVC+Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C13D174282B2F8100ABF44B /* LaunchVC+Scene.swift */; }; 17 | 3C13D180282B304400ABF44B /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C13D17F282B304400ABF44B /* Utilities.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 3C13D15A282B2F3F00ABF44B /* RealityKitLaunchScreen.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RealityKitLaunchScreen.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 3C13D15D282B2F3F00ABF44B /* RealityKitLaunchScreenApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealityKitLaunchScreenApp.swift; sourceTree = ""; }; 23 | 3C13D15F282B2F3F00ABF44B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 24 | 3C13D16C282B2F8100ABF44B /* LaunchConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchConstants.swift; sourceTree = ""; }; 25 | 3C13D16E282B2F8100ABF44B /* LaunchViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchViewModel.swift; sourceTree = ""; }; 26 | 3C13D170282B2F8100ABF44B /* LaunchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchViewController.swift; sourceTree = ""; }; 27 | 3C13D171282B2F8100ABF44B /* LaunchModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchModels.swift; sourceTree = ""; }; 28 | 3C13D174282B2F8100ABF44B /* LaunchVC+Scene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LaunchVC+Scene.swift"; sourceTree = ""; }; 29 | 3C13D17F282B304400ABF44B /* Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utilities.swift; sourceTree = ""; }; 30 | /* End PBXFileReference section */ 31 | 32 | /* Begin PBXFrameworksBuildPhase section */ 33 | 3C13D157282B2F3F00ABF44B /* Frameworks */ = { 34 | isa = PBXFrameworksBuildPhase; 35 | buildActionMask = 2147483647; 36 | files = ( 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 3C13D151282B2F3F00ABF44B = { 44 | isa = PBXGroup; 45 | children = ( 46 | 3C13D15C282B2F3F00ABF44B /* RealityKitLaunchScreen */, 47 | 3C13D15B282B2F3F00ABF44B /* Products */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | 3C13D15B282B2F3F00ABF44B /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | 3C13D15A282B2F3F00ABF44B /* RealityKitLaunchScreen.app */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | 3C13D15C282B2F3F00ABF44B /* RealityKitLaunchScreen */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 3C13D15D282B2F3F00ABF44B /* RealityKitLaunchScreenApp.swift */, 63 | 3C13D16E282B2F8100ABF44B /* LaunchViewModel.swift */, 64 | 3C13D15F282B2F3F00ABF44B /* ContentView.swift */, 65 | 3C13D16C282B2F8100ABF44B /* LaunchConstants.swift */, 66 | 3C13D171282B2F8100ABF44B /* LaunchModels.swift */, 67 | 3C13D170282B2F8100ABF44B /* LaunchViewController.swift */, 68 | 3C13D174282B2F8100ABF44B /* LaunchVC+Scene.swift */, 69 | 3C13D17F282B304400ABF44B /* Utilities.swift */, 70 | ); 71 | path = RealityKitLaunchScreen; 72 | sourceTree = ""; 73 | }; 74 | /* End PBXGroup section */ 75 | 76 | /* Begin PBXNativeTarget section */ 77 | 3C13D159282B2F3F00ABF44B /* RealityKitLaunchScreen */ = { 78 | isa = PBXNativeTarget; 79 | buildConfigurationList = 3C13D168282B2F4100ABF44B /* Build configuration list for PBXNativeTarget "RealityKitLaunchScreen" */; 80 | buildPhases = ( 81 | 3C13D156282B2F3F00ABF44B /* Sources */, 82 | 3C13D157282B2F3F00ABF44B /* Frameworks */, 83 | 3C13D158282B2F3F00ABF44B /* Resources */, 84 | ); 85 | buildRules = ( 86 | ); 87 | dependencies = ( 88 | ); 89 | name = RealityKitLaunchScreen; 90 | productName = RealityKitLaunchScreen; 91 | productReference = 3C13D15A282B2F3F00ABF44B /* RealityKitLaunchScreen.app */; 92 | productType = "com.apple.product-type.application"; 93 | }; 94 | /* End PBXNativeTarget section */ 95 | 96 | /* Begin PBXProject section */ 97 | 3C13D152282B2F3F00ABF44B /* Project object */ = { 98 | isa = PBXProject; 99 | attributes = { 100 | BuildIndependentTargetsInParallel = 1; 101 | LastSwiftUpdateCheck = 1330; 102 | LastUpgradeCheck = 1330; 103 | TargetAttributes = { 104 | 3C13D159282B2F3F00ABF44B = { 105 | CreatedOnToolsVersion = 13.3; 106 | }; 107 | }; 108 | }; 109 | buildConfigurationList = 3C13D155282B2F3F00ABF44B /* Build configuration list for PBXProject "RealityKitLaunchScreen" */; 110 | compatibilityVersion = "Xcode 13.0"; 111 | developmentRegion = en; 112 | hasScannedForEncodings = 0; 113 | knownRegions = ( 114 | en, 115 | Base, 116 | ); 117 | mainGroup = 3C13D151282B2F3F00ABF44B; 118 | productRefGroup = 3C13D15B282B2F3F00ABF44B /* Products */; 119 | projectDirPath = ""; 120 | projectRoot = ""; 121 | targets = ( 122 | 3C13D159282B2F3F00ABF44B /* RealityKitLaunchScreen */, 123 | ); 124 | }; 125 | /* End PBXProject section */ 126 | 127 | /* Begin PBXResourcesBuildPhase section */ 128 | 3C13D158282B2F3F00ABF44B /* Resources */ = { 129 | isa = PBXResourcesBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | ); 133 | runOnlyForDeploymentPostprocessing = 0; 134 | }; 135 | /* End PBXResourcesBuildPhase section */ 136 | 137 | /* Begin PBXSourcesBuildPhase section */ 138 | 3C13D156282B2F3F00ABF44B /* Sources */ = { 139 | isa = PBXSourcesBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | 3C13D176282B2F8100ABF44B /* LaunchConstants.swift in Sources */, 143 | 3C13D160282B2F3F00ABF44B /* ContentView.swift in Sources */, 144 | 3C13D15E282B2F3F00ABF44B /* RealityKitLaunchScreenApp.swift in Sources */, 145 | 3C13D17E282B2F8100ABF44B /* LaunchVC+Scene.swift in Sources */, 146 | 3C13D178282B2F8100ABF44B /* LaunchViewModel.swift in Sources */, 147 | 3C13D180282B304400ABF44B /* Utilities.swift in Sources */, 148 | 3C13D17A282B2F8100ABF44B /* LaunchViewController.swift in Sources */, 149 | 3C13D17B282B2F8100ABF44B /* LaunchModels.swift in Sources */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXSourcesBuildPhase section */ 154 | 155 | /* Begin XCBuildConfiguration section */ 156 | 3C13D166282B2F4100ABF44B /* Debug */ = { 157 | isa = XCBuildConfiguration; 158 | buildSettings = { 159 | ALWAYS_SEARCH_USER_PATHS = NO; 160 | CLANG_ANALYZER_NONNULL = YES; 161 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 162 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 163 | CLANG_ENABLE_MODULES = YES; 164 | CLANG_ENABLE_OBJC_ARC = YES; 165 | CLANG_ENABLE_OBJC_WEAK = YES; 166 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 167 | CLANG_WARN_BOOL_CONVERSION = YES; 168 | CLANG_WARN_COMMA = YES; 169 | CLANG_WARN_CONSTANT_CONVERSION = YES; 170 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 171 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 172 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 173 | CLANG_WARN_EMPTY_BODY = YES; 174 | CLANG_WARN_ENUM_CONVERSION = YES; 175 | CLANG_WARN_INFINITE_RECURSION = YES; 176 | CLANG_WARN_INT_CONVERSION = YES; 177 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 178 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 179 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 180 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 181 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 182 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 183 | CLANG_WARN_STRICT_PROTOTYPES = YES; 184 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 185 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 186 | CLANG_WARN_UNREACHABLE_CODE = YES; 187 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 188 | COPY_PHASE_STRIP = NO; 189 | DEBUG_INFORMATION_FORMAT = dwarf; 190 | ENABLE_STRICT_OBJC_MSGSEND = YES; 191 | ENABLE_TESTABILITY = YES; 192 | GCC_C_LANGUAGE_STANDARD = gnu11; 193 | GCC_DYNAMIC_NO_PIC = NO; 194 | GCC_NO_COMMON_BLOCKS = YES; 195 | GCC_OPTIMIZATION_LEVEL = 0; 196 | GCC_PREPROCESSOR_DEFINITIONS = ( 197 | "DEBUG=1", 198 | "$(inherited)", 199 | ); 200 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 201 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 202 | GCC_WARN_UNDECLARED_SELECTOR = YES; 203 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 204 | GCC_WARN_UNUSED_FUNCTION = YES; 205 | GCC_WARN_UNUSED_VARIABLE = YES; 206 | IPHONEOS_DEPLOYMENT_TARGET = 15.4; 207 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 208 | MTL_FAST_MATH = YES; 209 | ONLY_ACTIVE_ARCH = YES; 210 | SDKROOT = iphoneos; 211 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 212 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 213 | }; 214 | name = Debug; 215 | }; 216 | 3C13D167282B2F4100ABF44B /* Release */ = { 217 | isa = XCBuildConfiguration; 218 | buildSettings = { 219 | ALWAYS_SEARCH_USER_PATHS = NO; 220 | CLANG_ANALYZER_NONNULL = YES; 221 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 223 | CLANG_ENABLE_MODULES = YES; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | CLANG_ENABLE_OBJC_WEAK = YES; 226 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 227 | CLANG_WARN_BOOL_CONVERSION = YES; 228 | CLANG_WARN_COMMA = YES; 229 | CLANG_WARN_CONSTANT_CONVERSION = YES; 230 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 231 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 232 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 233 | CLANG_WARN_EMPTY_BODY = YES; 234 | CLANG_WARN_ENUM_CONVERSION = YES; 235 | CLANG_WARN_INFINITE_RECURSION = YES; 236 | CLANG_WARN_INT_CONVERSION = YES; 237 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 238 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 239 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 240 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 241 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 242 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 243 | CLANG_WARN_STRICT_PROTOTYPES = YES; 244 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 245 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 246 | CLANG_WARN_UNREACHABLE_CODE = YES; 247 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 248 | COPY_PHASE_STRIP = NO; 249 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 250 | ENABLE_NS_ASSERTIONS = NO; 251 | ENABLE_STRICT_OBJC_MSGSEND = YES; 252 | GCC_C_LANGUAGE_STANDARD = gnu11; 253 | GCC_NO_COMMON_BLOCKS = YES; 254 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 255 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 256 | GCC_WARN_UNDECLARED_SELECTOR = YES; 257 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 258 | GCC_WARN_UNUSED_FUNCTION = YES; 259 | GCC_WARN_UNUSED_VARIABLE = YES; 260 | IPHONEOS_DEPLOYMENT_TARGET = 15.4; 261 | MTL_ENABLE_DEBUG_INFO = NO; 262 | MTL_FAST_MATH = YES; 263 | SDKROOT = iphoneos; 264 | SWIFT_COMPILATION_MODE = wholemodule; 265 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 266 | VALIDATE_PRODUCT = YES; 267 | }; 268 | name = Release; 269 | }; 270 | 3C13D169282B2F4100ABF44B /* Debug */ = { 271 | isa = XCBuildConfiguration; 272 | buildSettings = { 273 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 274 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 275 | CODE_SIGN_STYLE = Automatic; 276 | CURRENT_PROJECT_VERSION = 1; 277 | DEVELOPMENT_ASSET_PATHS = ""; 278 | DEVELOPMENT_TEAM = YA533DMD5J; 279 | ENABLE_PREVIEWS = YES; 280 | GENERATE_INFOPLIST_FILE = YES; 281 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 282 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 283 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 284 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 285 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 286 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 287 | LD_RUNPATH_SEARCH_PATHS = ( 288 | "$(inherited)", 289 | "@executable_path/Frameworks", 290 | ); 291 | MARKETING_VERSION = 1.0; 292 | PRODUCT_BUNDLE_IDENTIFIER = com.aheze.RealityKitLaunchScreen; 293 | PRODUCT_NAME = "$(TARGET_NAME)"; 294 | SWIFT_EMIT_LOC_STRINGS = YES; 295 | SWIFT_VERSION = 5.0; 296 | TARGETED_DEVICE_FAMILY = "1,2"; 297 | }; 298 | name = Debug; 299 | }; 300 | 3C13D16A282B2F4100ABF44B /* Release */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 304 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 305 | CODE_SIGN_STYLE = Automatic; 306 | CURRENT_PROJECT_VERSION = 1; 307 | DEVELOPMENT_ASSET_PATHS = ""; 308 | DEVELOPMENT_TEAM = YA533DMD5J; 309 | ENABLE_PREVIEWS = YES; 310 | GENERATE_INFOPLIST_FILE = YES; 311 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 312 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 313 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 314 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 315 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 316 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 317 | LD_RUNPATH_SEARCH_PATHS = ( 318 | "$(inherited)", 319 | "@executable_path/Frameworks", 320 | ); 321 | MARKETING_VERSION = 1.0; 322 | PRODUCT_BUNDLE_IDENTIFIER = com.aheze.RealityKitLaunchScreen; 323 | PRODUCT_NAME = "$(TARGET_NAME)"; 324 | SWIFT_EMIT_LOC_STRINGS = YES; 325 | SWIFT_VERSION = 5.0; 326 | TARGETED_DEVICE_FAMILY = "1,2"; 327 | }; 328 | name = Release; 329 | }; 330 | /* End XCBuildConfiguration section */ 331 | 332 | /* Begin XCConfigurationList section */ 333 | 3C13D155282B2F3F00ABF44B /* Build configuration list for PBXProject "RealityKitLaunchScreen" */ = { 334 | isa = XCConfigurationList; 335 | buildConfigurations = ( 336 | 3C13D166282B2F4100ABF44B /* Debug */, 337 | 3C13D167282B2F4100ABF44B /* Release */, 338 | ); 339 | defaultConfigurationIsVisible = 0; 340 | defaultConfigurationName = Release; 341 | }; 342 | 3C13D168282B2F4100ABF44B /* Build configuration list for PBXNativeTarget "RealityKitLaunchScreen" */ = { 343 | isa = XCConfigurationList; 344 | buildConfigurations = ( 345 | 3C13D169282B2F4100ABF44B /* Debug */, 346 | 3C13D16A282B2F4100ABF44B /* Release */, 347 | ); 348 | defaultConfigurationIsVisible = 0; 349 | defaultConfigurationName = Release; 350 | }; 351 | /* End XCConfigurationList section */ 352 | }; 353 | rootObject = 3C13D152282B2F3F00ABF44B /* Project object */; 354 | } 355 | --------------------------------------------------------------------------------