diff --git a/Compatibility.md b/Compatibility.md
index c3b8eec..dea0894 100644
--- a/Compatibility.md
+++ b/Compatibility.md
@@ -1,6 +1,6 @@
# Compatible Applications/Games
-**ATTENTION** This list is a work in progress. Feel free to open a Pull Request updating it.
+**ATTENTION** This list is incomplete and it is a work in progress. The app might work with some other Quest titles, feel free to open a Pull Request adding more titles to the list.
You can find a list of the officially supported games/applications [here](https://creator.oculus.com/mrc/).
@@ -23,5 +23,5 @@ You can find a list of the officially supported games/applications [here](https:
| [Richie's Plank Experience](https://www.oculus.com/experiences/quest/1642239225880682) | ? | ? | [Tweet](https://twitter.com/FreekTeunen/status/1327673218891649024) | ? |
| [SUPERHOT](https://www.oculus.com/experiences/quest/1921533091289407/) | 5 | 5 | [YouTube video](https://www.youtube.com/watch?v=ZnOY8juMw4k) | Works perfectly. |
| [Space Pirate Trainer](https://www.oculus.com/experiences/quest/1663790613725314) | 5 | 5 | [YouTube video](https://www.youtube.com/watch?v=44Nmv7Es5yI) | Works perfectly. |
-| [Tilt Brush](https://www.oculus.com/experiences/quest/2322529091093901) | 0 | 0 | ? | The video output is glitching and the camera doesn't appear to be respecting the calibration. |
+| [Tilt Brush](https://www.oculus.com/experiences/quest/2322529091093901) | 0 | 0 | [Tweet](https://twitter.com/fabio914/status/1332724521497931777) | The video output is glitching and the camera doesn't appear to be respecting the calibration. |
| [The Thrill of the Fight](https://www.oculus.com/experiences/quest/3008315795852749) | 4 | 5 | [YouTube video](https://www.youtube.com/watch?v=aPSBmej4ppc) | You'll have to use the "Use magenta for transparency" option. |
diff --git a/Instructions.md b/Instructions.md
index 9a4ce81..3ebc84b 100644
--- a/Instructions.md
+++ b/Instructions.md
@@ -4,7 +4,7 @@
- Oculus Quest 1 or 2 with the [Oculus MRC Calibration app](https://www.oculus.com/experiences/quest/2532132800176262/) version 1.7 installed.
- iPhone or iPad with an A12 chip or newer, running iOS 14. The LiDAR sensor is optional but recommended for better results.
- - 5 Ghz WiFi network.
+ - 5 Ghz WiFi network (802.11ac).
- A [compatible Quest VR application/game](Compatibility.md).
## Calibration, what is this?
diff --git a/README.md b/README.md
index 85332c5..f0702dc 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ Follow us on [Twitter](https://twitter.com/reality_mixer) for more updates!
- Oculus Quest 1 or 2 with the [Oculus MRC Calibration app](https://www.oculus.com/experiences/quest/2532132800176262/) version 1.7 installed.
- iPhone or iPad with an A12 chip or newer, running iOS 14. The LiDAR sensor is optional but recommended for better results.
- - 5 Ghz WiFi network.
+ - 5 Ghz WiFi network (802.11ac).
- A [compatible Quest VR application/game](Compatibility.md).
Note that this app is still just a prototype and it's still being developed, use at your own risk.
diff --git a/RealityMixer.xcodeproj/project.pbxproj b/RealityMixer.xcodeproj/project.pbxproj
index efc99c3..4c512da 100644
--- a/RealityMixer.xcodeproj/project.pbxproj
+++ b/RealityMixer.xcodeproj/project.pbxproj
@@ -932,7 +932,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 6;
+ CURRENT_PROJECT_VERSION = 7;
DEVELOPMENT_TEAM = ZTJ55TM37B;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -948,7 +948,7 @@
"$(inherited)",
"$(PROJECT_DIR)/RealityMixer/FFmpeg-iOS/lib",
);
- MARKETING_VERSION = 0.1.4;
+ MARKETING_VERSION = 0.1.5;
PRODUCT_BUNDLE_IDENTIFIER = com.bluenose.reality.mixer;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "RealityMixer/RealityMixer-Bridging-Header.h";
@@ -965,7 +965,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 6;
+ CURRENT_PROJECT_VERSION = 7;
DEVELOPMENT_TEAM = ZTJ55TM37B;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -981,7 +981,7 @@
"$(inherited)",
"$(PROJECT_DIR)/RealityMixer/FFmpeg-iOS/lib",
);
- MARKETING_VERSION = 0.1.4;
+ MARKETING_VERSION = 0.1.5;
PRODUCT_BUNDLE_IDENTIFIER = com.bluenose.reality.mixer;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "RealityMixer/RealityMixer-Bridging-Header.h";
diff --git a/RealityMixer/Calibration/Builders/CalibrationSceneNodeBuilder.swift b/RealityMixer/Calibration/Builders/CalibrationSceneNodeBuilder.swift
index 859f3bf..d6c3bb6 100644
--- a/RealityMixer/Calibration/Builders/CalibrationSceneNodeBuilder.swift
+++ b/RealityMixer/Calibration/Builders/CalibrationSceneNodeBuilder.swift
@@ -36,19 +36,27 @@ struct CalibrationSceneNodeBuilder {
let leftController: SCNNode! = model(named: "left")
leftController.geometry?.firstMaterial?.lightingModel = .constant
leftController.geometry?.firstMaterial?.diffuse.contents = UIColor.red
- leftController.rotation = SCNVector4(1, 0, 0, 45.0 * .pi/180.0)
+ leftController.position = SCNVector3(-0.004, 0.027, 0.04)
+
+ let rotatedLeftController = SCNNode()
+ rotatedLeftController.addChildNode(leftController)
+ rotatedLeftController.rotation = SCNVector4(1, 0, 0, 45.0 * .pi/180.0)
let leftControllerNode = SCNNode()
- leftControllerNode.addChildNode(leftController)
+ leftControllerNode.addChildNode(rotatedLeftController)
mainNode.addChildNode(leftControllerNode)
let rightController: SCNNode! = model(named: "right")
rightController.geometry?.firstMaterial?.lightingModel = .constant
rightController.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
- rightController.rotation = SCNVector4(1, 0, 0, 45.0 * .pi/180.0)
+ rightController.position = SCNVector3(0.004, 0.027, 0.04)
+
+ let rotatedRightController = SCNNode()
+ rotatedRightController.addChildNode(rightController)
+ rotatedRightController.rotation = SCNVector4(1, 0, 0, 45.0 * .pi/180.0)
let rightControllerNode = SCNNode()
- rightControllerNode.addChildNode(rightController)
+ rightControllerNode.addChildNode(rotatedRightController)
mainNode.addChildNode(rightControllerNode)
// Using Quest 2 dimensions
@@ -56,8 +64,12 @@ struct CalibrationSceneNodeBuilder {
headset.firstMaterial?.lightingModel = .constant
headset.firstMaterial?.diffuse.contents = UIColor.gray
+ let headsetIntermediateNode = SCNNode()
+ headsetIntermediateNode.geometry = headset
+ headsetIntermediateNode.position = SCNVector3(0, 0.025, 0)
+
let headsetNode = SCNNode()
- headsetNode.geometry = headset
+ headsetNode.addChildNode(headsetIntermediateNode)
mainNode.addChildNode(headsetNode)
return .init(
diff --git a/RealityMixer/Calibration/ViewControllers/CalibrationConnectionViewController.xib b/RealityMixer/Calibration/ViewControllers/CalibrationConnectionViewController.xib
index 3c68bb2..7c6a81e 100644
--- a/RealityMixer/Calibration/ViewControllers/CalibrationConnectionViewController.xib
+++ b/RealityMixer/Calibration/ViewControllers/CalibrationConnectionViewController.xib
@@ -29,184 +29,182 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
@@ -214,11 +212,12 @@
+
-
+
+
-
diff --git a/RealityMixer/Calibration/ViewControllers/CalibrationViewController.swift b/RealityMixer/Calibration/ViewControllers/CalibrationViewController.swift
index 48d883d..2281466 100644
--- a/RealityMixer/Calibration/ViewControllers/CalibrationViewController.swift
+++ b/RealityMixer/Calibration/ViewControllers/CalibrationViewController.swift
@@ -158,12 +158,11 @@ final class CalibrationViewController: UIViewController {
delegate: self
)
- let navigationController = UINavigationController(rootViewController: viewController)
+ viewController.isModalInPresentation = true
+ viewController.modalPresentationStyle = .overFullScreen
+ viewController.modalTransitionStyle = .crossDissolve
- navigationController.isModalInPresentation = true
- navigationController.modalPresentationStyle = .fullScreen
-
- present(navigationController, animated: true, completion: nil)
+ present(viewController, animated: true, completion: nil)
case .calibrationSet(let transform, _):
saveButtonContainer.isHidden = false
updateInfo("Step 4 of 4: Review your calibration and tap on \"Save to Headset\" to save it. ")
@@ -221,7 +220,7 @@ final class CalibrationViewController: UIViewController {
alert.addAction(.init(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
case .success:
- let alert = UIAlertController(title: "Calibration Saved!", message: nil, preferredStyle: .alert)
+ let alert = UIAlertController(title: "Calibration Saved!", message: "You can now close the Oculus Mixed Reality Capture Calibration app and launch your VR application/game.", preferredStyle: .alert)
alert.addAction(.init(title: "OK", style: .default, handler: { [weak self] _ in
guard let self = self else { return }
self.displayLink?.invalidate()
diff --git a/RealityMixer/Calibration/ViewControllers/ProjectionViewController.swift b/RealityMixer/Calibration/ViewControllers/ProjectionViewController.swift
index 493fe6b..8d58e4b 100644
--- a/RealityMixer/Calibration/ViewControllers/ProjectionViewController.swift
+++ b/RealityMixer/Calibration/ViewControllers/ProjectionViewController.swift
@@ -35,8 +35,13 @@ final class ProjectionViewController: UIViewController {
@IBOutlet private weak var imageView: UIImageView!
@IBOutlet private weak var sceneOverlay: SCNView!
@IBOutlet private weak var blueView: UIView!
+
+ @IBOutlet private weak var adjustDistanceButtonContainer: UIView!
+ @IBOutlet private weak var adjustDistanceContainer: UIView!
@IBOutlet private weak var distanceLabel: UILabel!
+ @IBOutlet private weak var instructionsOverlayView: UIView!
+
private weak var mainNode: SCNNode?
private let radius = CGFloat(20)
@@ -57,6 +62,8 @@ final class ProjectionViewController: UIViewController {
}
}
+ private var first = true
+
init(
scaleFactor: Double,
cameraOrigin: Vector3,
@@ -80,11 +87,15 @@ final class ProjectionViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- title = "Step 3 of 4"
imageView.image = image
- navigationItem.rightBarButtonItem = .init(title: "Done", style: .done, target: self, action: #selector(done))
- navigationItem.leftBarButtonItem = .init(title: "Cancel", style: .plain, target: self, action: #selector(cancel))
- buildScene()
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ if first {
+ buildScene()
+ first = false
+ }
}
private func buildScene() {
@@ -107,11 +118,19 @@ final class ProjectionViewController: UIViewController {
let imageRatio = frame.camera.imageResolution.width/frame.camera.imageResolution.height
if imageViewRatio > imageRatio {
+ let imageHeightInImageViewCoordinates = frame.camera.imageResolution.height * (imageView.frame.size.width/frame.camera.imageResolution.width)
+ let distanceInImageViewCoordinates = (imageHeightInImageViewCoordinates * 0.5)/CGFloat(tan(yFov/2.0))
+ let adjustedYFov = CGFloat(2.0 * atan2((imageView.frame.size.height * 0.5), distanceInImageViewCoordinates))
+
camera.projectionDirection = .vertical
- camera.fieldOfView = CGFloat(yFov * (180.0/Float.pi))
+ camera.fieldOfView = (adjustedYFov * (180.0/CGFloat.pi))
} else {
+ let imageWidthInImageViewCoordinates = frame.camera.imageResolution.width * (imageView.frame.size.height/frame.camera.imageResolution.height)
+ let distanceInImageViewCoordinates = (imageWidthInImageViewCoordinates * 0.5)/CGFloat(tan(xFov/2.0))
+ let adjustedXFov = CGFloat(2.0 * atan2((imageView.frame.size.width * 0.5), distanceInImageViewCoordinates))
+
camera.projectionDirection = .horizontal
- camera.fieldOfView = CGFloat(xFov * (180.0/Float.pi))
+ camera.fieldOfView = (adjustedXFov * (180.0/CGFloat.pi))
}
let cameraNode = SCNNode()
@@ -169,12 +188,32 @@ final class ProjectionViewController: UIViewController {
distanceAdjustment = Double(sender.value)
}
- @objc private func done() {
+ @IBAction private func hideInstructionsAction(_ sender: UIButton) {
+ sender.isUserInteractionEnabled = false
+
+ UIView.animateKeyframes(
+ withDuration: 0.2,
+ delay: 0,
+ animations: { [weak self] in
+ self?.instructionsOverlayView.alpha = 0
+ },
+ completion: { [weak self] _ in
+ self?.instructionsOverlayView.isHidden = true
+ }
+ )
+ }
+
+ @IBAction private func showDistanceAdjustmentAction(_ sender: UIButton) {
+ adjustDistanceButtonContainer.isHidden = true
+ adjustDistanceContainer.isHidden = false
+ }
+
+ @IBAction private func done() {
guard let currentResult = currentResult else { return }
delegate?.projection(self, didFinishWithCalibration: currentResult.1, transform: currentResult.0)
}
- @objc private func cancel() {
+ @IBAction private func cancel() {
delegate?.projectionDidCancel(self)
}
@@ -199,27 +238,32 @@ final class ProjectionViewController: UIViewController {
blueView?.center = blueViewCenter
}
- // Using Aspect Fit
+ // Using Aspect Fill
private func pixelCoordinate(from viewCoordinate: CGPoint) -> CGPoint {
let imageViewRatio = imageView.frame.size.width/imageView.frame.size.height
let imageRatio = image.size.width/image.size.height
if imageViewRatio > imageRatio {
+ let imageHeightInImageViewCoordinates = image.size.height * (imageView.frame.size.width/image.size.width)
+ let offsetY = (imageHeightInImageViewCoordinates - imageView.frame.size.height)/2.0
+
return CGPoint(
- x: floor((viewCoordinate.x-((imageView.frame.size.width/2.0)-(((imageView.frame.size.height/image.size.height)*image.size.width)/2.0)))/(imageView.frame.size.height/image.size.height)),
- y: floor(viewCoordinate.y/(imageView.frame.size.height/image.size.height))
+ x: floor(viewCoordinate.x * (image.size.width/imageView.frame.size.width)),
+ y: floor((viewCoordinate.y + offsetY) * (image.size.height/imageHeightInImageViewCoordinates))
)
} else if imageViewRatio < imageRatio {
- let halfAspectFit: CGFloat = ((imageView.frame.size.width/image.size.width)*image.size.height)/2.0
+ let imageWidthInImageViewCoordinates = image.size.width * (imageView.frame.size.height/image.size.height)
+ let offsetX = (imageWidthInImageViewCoordinates - imageView.frame.size.width)/2.0
+
return CGPoint(
- x: floor(viewCoordinate.x/(imageView.frame.size.width/image.size.width)),
- y: floor((viewCoordinate.y-((imageView.frame.size.width/2.0)-halfAspectFit))/(imageView.frame.size.height/image.size.height))
+ x: floor((viewCoordinate.x + offsetX) * (image.size.width/imageWidthInImageViewCoordinates)),
+ y: floor(viewCoordinate.y * (image.size.height/imageView.frame.size.height))
)
} else {
return CGPoint(
- x: floor(viewCoordinate.x/(imageView.frame.size.width/image.size.width)),
- y: floor(viewCoordinate.y/(imageView.frame.size.width/image.size.height))
+ x: floor(viewCoordinate.x * (image.size.width/imageView.frame.size.width)),
+ y: floor(viewCoordinate.y * (image.size.height/imageView.frame.size.height))
)
}
}
diff --git a/RealityMixer/Calibration/ViewControllers/ProjectionViewController.xib b/RealityMixer/Calibration/ViewControllers/ProjectionViewController.xib
index 76a8c74..61ef5fd 100644
--- a/RealityMixer/Calibration/ViewControllers/ProjectionViewController.xib
+++ b/RealityMixer/Calibration/ViewControllers/ProjectionViewController.xib
@@ -1,8 +1,8 @@
-
-
+
+
-
+
@@ -10,38 +10,34 @@
+
+
+
-
+
-
-
- Move the blue circle to where the right controller is. Try to align the controllers and the headset with the overlay image. Tap on "Cancel" to return to the first step if you can't get a good alignment. Tap on "Done" to continue.
-
-
-
-
-
+
-
-
+
+
-
+
-
+
@@ -63,54 +59,224 @@
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Step 3 of 4: Move the blue circle to where the right controller is. Try to align the controllers and the headset with the overlay image. Tap on "Cancel" to return to the first step if you can't get a good alignment. Tap on "Next" to continue.
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/RealityMixer/Capture/Shaders/Shaders.swift b/RealityMixer/Capture/Shaders/Shaders.swift
index cd8f632..23f9c01 100644
--- a/RealityMixer/Capture/Shaders/Shaders.swift
+++ b/RealityMixer/Capture/Shaders/Shaders.swift
@@ -104,6 +104,7 @@ struct Shaders {
vec3 magenta = vec3(1.0, 0.0, 1.0);
float threshold = 0.10;
+ // FIXME: Consider using HSV to compare these colors
bool checkRed = (alphaColor.r >= (magenta.r - threshold));
bool checkGreen = (alphaColor.g >= (magenta.g - threshold) && alphaColor.g <= (magenta.g + threshold));
bool checkBlue = (alphaColor.b >= (magenta.b - threshold));
diff --git a/RealityMixer/Capture/ViewControllers/MixedRealityConnectionViewController.xib b/RealityMixer/Capture/ViewControllers/MixedRealityConnectionViewController.xib
index 3110416..16f2083 100644
--- a/RealityMixer/Capture/ViewControllers/MixedRealityConnectionViewController.xib
+++ b/RealityMixer/Capture/ViewControllers/MixedRealityConnectionViewController.xib
@@ -30,212 +30,210 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
@@ -243,11 +241,12 @@
+
-
+
-
+
diff --git a/RealityMixer/Main/ViewControllers/AboutViewController.xib b/RealityMixer/Main/ViewControllers/AboutViewController.xib
index c130290..b8ec412 100644
--- a/RealityMixer/Main/ViewControllers/AboutViewController.xib
+++ b/RealityMixer/Main/ViewControllers/AboutViewController.xib
@@ -23,122 +23,120 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
@@ -146,13 +144,14 @@
-
-
+
+
+
diff --git a/RealityMixer/Main/ViewControllers/InitialViewController.swift b/RealityMixer/Main/ViewControllers/InitialViewController.swift
index 8dc1305..926480a 100644
--- a/RealityMixer/Main/ViewControllers/InitialViewController.swift
+++ b/RealityMixer/Main/ViewControllers/InitialViewController.swift
@@ -10,6 +10,8 @@ import SafariServices
final class InitialViewController: UIViewController {
+ @IBOutlet private weak var scrollView: UIScrollView!
+
init() {
super.init(nibName: String(describing: type(of: self)), bundle: Bundle(for: type(of: self)))
}
@@ -23,6 +25,11 @@ final class InitialViewController: UIViewController {
title = "Reality Mixer"
}
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ scrollView.flashScrollIndicators()
+ }
+
@IBAction private func calibrateAction(_ sender: Any) {
let otherNavigationController = UINavigationController(rootViewController: CalibrationConnectionViewController())
otherNavigationController.modalPresentationStyle = .overFullScreen
diff --git a/RealityMixer/Main/ViewControllers/InitialViewController.xib b/RealityMixer/Main/ViewControllers/InitialViewController.xib
index 5d09de9..25524a4 100644
--- a/RealityMixer/Main/ViewControllers/InitialViewController.xib
+++ b/RealityMixer/Main/ViewControllers/InitialViewController.xib
@@ -1,14 +1,15 @@
-
+
-
+
+
@@ -20,96 +21,123 @@
-
-
+
+
-
-
-
-
+
-
+
+
+
+
+
-
+
+
+
-
-
+
+
+
+