Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 350a67d63e | |||
| 0832eeb927 | |||
| 3eb3c4db2b |
@@ -65,4 +65,3 @@ fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
fastlane/test_output
|
||||
.DS_Store
|
||||
|
||||
+5
-4
@@ -1,11 +1,11 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "ARVideoKit"
|
||||
s.version = "1.6.0"
|
||||
s.version = "1.51"
|
||||
s.summary = "Capture & record ARKit videos 📹, photos 🌄, Live Photos 🎇, and GIFs 🎆."
|
||||
s.description = "Enabling developers to capture videos 📹, photos 🌄, Live Photos 🎇, and GIFs 🎆 with augmented reality components."
|
||||
s.homepage = "https://github.com/AFathi/ARVideoKit"
|
||||
s.screenshots = "http://www.ahmedbekhit.com/SK_PREV.gif", "http://www.ahmedbekhit.com/SCN_PREVIEW.gif"
|
||||
s.swift_version = '5.0'
|
||||
s.swift_version = '4.2'
|
||||
|
||||
|
||||
s.license = { :type => "Apache 2.0", :file => "LICENSE" }
|
||||
@@ -16,7 +16,8 @@ Pod::Spec.new do |s|
|
||||
|
||||
s.platform = :ios, "11.0"
|
||||
|
||||
# ARVideoKit for Swift 5.0
|
||||
s.source = { :git => "https://github.com/AFathi/ARVideoKit.git", :tag => "1.6.0" }
|
||||
# ARVideoKit for Swift 4.2
|
||||
s.source = { :git => "https://github.com/AFathi/ARVideoKit.git", :tag => "1.51" }
|
||||
s.source_files = "ARVideoKit", "ARVideoKit/**/*.{h,m,swift}"
|
||||
s.resources = "ARVideoKit/Assets/*.scnassets"
|
||||
end
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
FB2E36891FAE29C00035B8D6 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = FB2E36881FAE29BF0035B8D6 /* LICENSE */; };
|
||||
FB404FFE20D72A190056EA1D /* JPEG.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB404FFD20D72A190056EA1D /* JPEG.swift */; };
|
||||
FBD604DF1FA969DD00EC9804 /* ARVideoKit.h in Headers */ = {isa = PBXBuildFile; fileRef = FBD604DD1FA969DD00EC9804 /* ARVideoKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
FBD604EB1FA96B1C00EC9804 /* video.scnassets in Resources */ = {isa = PBXBuildFile; fileRef = FBD604EA1FA96B1C00EC9804 /* video.scnassets */; };
|
||||
FBD604EE1FA96B2700EC9804 /* ARVideoOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD604EC1FA96B2700EC9804 /* ARVideoOptions.swift */; };
|
||||
FBD604EF1FA96B2700EC9804 /* ARInputViewOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD604ED1FA96B2700EC9804 /* ARInputViewOptions.swift */; };
|
||||
FBD604F51FA96B3300EC9804 /* UIImage+VideoBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD604F01FA96B3300EC9804 /* UIImage+VideoBuffer.swift */; };
|
||||
@@ -39,6 +40,7 @@
|
||||
FBD604DA1FA969DD00EC9804 /* ARVideoKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ARVideoKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FBD604DD1FA969DD00EC9804 /* ARVideoKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARVideoKit.h; sourceTree = "<group>"; };
|
||||
FBD604DE1FA969DD00EC9804 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
FBD604EA1FA96B1C00EC9804 /* video.scnassets */ = {isa = PBXFileReference; lastKnownFileType = wrapper.scnassets; path = video.scnassets; sourceTree = "<group>"; };
|
||||
FBD604EC1FA96B2700EC9804 /* ARVideoOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ARVideoOptions.swift; sourceTree = "<group>"; };
|
||||
FBD604ED1FA96B2700EC9804 /* ARInputViewOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ARInputViewOptions.swift; sourceTree = "<group>"; };
|
||||
FBD604F01FA96B3300EC9804 /* UIImage+VideoBuffer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+VideoBuffer.swift"; sourceTree = "<group>"; };
|
||||
@@ -108,6 +110,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B466A8B62279E33800BD7070 /* Utils */,
|
||||
FBD604E51FA96ACD00EC9804 /* Assets */,
|
||||
FBD604E61FA96AD400EC9804 /* Enumerations */,
|
||||
FBD604E71FA96AE500EC9804 /* Extensions */,
|
||||
FBD604E81FA96AEC00EC9804 /* Protocols */,
|
||||
@@ -119,6 +122,14 @@
|
||||
path = ARVideoKit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD604E51FA96ACD00EC9804 /* Assets */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD604EA1FA96B1C00EC9804 /* video.scnassets */,
|
||||
);
|
||||
path = Assets;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD604E61FA96AD400EC9804 /* Enumerations */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -241,7 +252,7 @@
|
||||
TargetAttributes = {
|
||||
FBD604D91FA969DD00EC9804 = {
|
||||
CreatedOnToolsVersion = 9.1;
|
||||
LastSwiftMigration = 1020;
|
||||
LastSwiftMigration = 0910;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
@@ -252,7 +263,6 @@
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = FBD604D01FA969DD00EC9804;
|
||||
productRefGroup = FBD604DB1FA969DD00EC9804 /* Products */;
|
||||
@@ -270,6 +280,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FB2E36891FAE29C00035B8D6 /* LICENSE in Resources */,
|
||||
FBD604EB1FA96B1C00EC9804 /* video.scnassets in Resources */,
|
||||
FBD605071FA96B6B00EC9804 /* LoveLiver_LICENSE in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -451,7 +462,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -476,7 +487,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ahmedbekhit.ARVideoKit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -5,7 +5,6 @@
|
||||
// Created by Ahmed Bekhit on 10/18/17.
|
||||
// Copyright © 2017 Ahmed Fathi Bekhit. All rights reserved.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
/// Allows specifying the final video orientation.
|
||||
@objc public enum ARFrameMode: Int {
|
||||
@@ -13,7 +12,6 @@ import Foundation
|
||||
case aspectFit
|
||||
/// Recommended for iPhone X
|
||||
case aspectFill
|
||||
case viewAspectRatio
|
||||
}
|
||||
|
||||
/// Allows specifying the video rendering frame per second `FPS` rate.
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
import AVFoundation
|
||||
import Photos
|
||||
import UIKit
|
||||
|
||||
@available(iOS 11.0, *)
|
||||
extension RecordAR {
|
||||
|
||||
@@ -14,8 +14,8 @@ extension UIScreen {
|
||||
/**
|
||||
`isiPhone10` is a boolean that returns if the device is iPhone X or not.
|
||||
*/
|
||||
var isNotch: Bool {
|
||||
return UIApplication.shared.keyWindow?.safeAreaInsets != UIEdgeInsets.zero
|
||||
var isiPhone10: Bool {
|
||||
return self.nativeBounds.size == CGSize(width: 1125, height: 2436) || self.nativeBounds.size == CGSize(width: 2436, height: 1125)
|
||||
}
|
||||
}
|
||||
@available(iOS 11.0, *)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
import AVFoundation
|
||||
import Photos
|
||||
import UIKit
|
||||
|
||||
@available(iOS 11.0, *)
|
||||
class LivePhotoGenerator {
|
||||
|
||||
@@ -44,7 +44,7 @@ struct RenderAR {
|
||||
if let contentMode = ARcontentMode {
|
||||
switch contentMode {
|
||||
case .auto:
|
||||
if UIScreen.main.isNotch {
|
||||
if UIScreen.main.isiPhone10 {
|
||||
width = Int(UIScreen.main.nativeBounds.width)
|
||||
height = Int(UIScreen.main.nativeBounds.height)
|
||||
}
|
||||
@@ -54,15 +54,8 @@ struct RenderAR {
|
||||
case .aspectFill:
|
||||
width = Int(UIScreen.main.nativeBounds.width)
|
||||
height = Int(UIScreen.main.nativeBounds.height)
|
||||
case .viewAspectRatio where view is UIView:
|
||||
let bufferWidth = CVPixelBufferGetWidth(raw)
|
||||
let bufferHeight = CVPixelBufferGetHeight(raw)
|
||||
let viewSize = (view as! UIView).bounds.size
|
||||
let targetSize = AVMakeRect(aspectRatio: viewSize, insideRect: CGRect(x: 0, y: 0, width: bufferWidth, height: bufferHeight)).size
|
||||
width = Int(targetSize.width)
|
||||
height = Int(targetSize.height)
|
||||
default:
|
||||
if UIScreen.main.isNotch {
|
||||
if UIScreen.main.isiPhone10 {
|
||||
width = Int(UIScreen.main.nativeBounds.width)
|
||||
height = Int(UIScreen.main.nativeBounds.height)
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ class WritAR: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate {
|
||||
audioInput.expectsMediaDataInRealTime = true
|
||||
|
||||
audioBufferQueue.async {
|
||||
self.session?.startRunning()
|
||||
self.session.startRunning()
|
||||
}
|
||||
|
||||
if assetWriter.canAdd(audioInput) {
|
||||
@@ -208,10 +208,7 @@ class WritAR: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate {
|
||||
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
|
||||
if let input = audioInput {
|
||||
audioBufferQueue.async { [weak self] in
|
||||
if let isRecording = self?.isRecording,
|
||||
let session = self?.session,
|
||||
input.isReadyForMoreMediaData && isRecording
|
||||
&& session.isRunning {
|
||||
if input.isReadyForMoreMediaData && (self?.isRecording)! {
|
||||
input.append(sampleBuffer)
|
||||
}
|
||||
}
|
||||
@@ -230,7 +227,6 @@ class WritAR: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate {
|
||||
}
|
||||
|
||||
if assetWriter.status == .writing {
|
||||
isRecording = false
|
||||
assetWriter.finishWriting(completionHandler: finished)
|
||||
}
|
||||
}
|
||||
@@ -241,7 +237,6 @@ class WritAR: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate {
|
||||
session.stopRunning()
|
||||
}
|
||||
}
|
||||
isRecording = false
|
||||
assetWriter.cancelWriting()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ import PhotosUI
|
||||
/**
|
||||
An object that passes the AR recorder errors and status in the protocol methods.
|
||||
*/
|
||||
@objc weak public var delegate: RecordARDelegate?
|
||||
@objc public var delegate: RecordARDelegate?
|
||||
/**
|
||||
An object that passes the AR rendered content in the protocol method.
|
||||
*/
|
||||
@objc weak public var renderAR: RenderARDelegate?
|
||||
@objc public var renderAR: RenderARDelegate?
|
||||
/**
|
||||
An object that returns the AR recorder current status.
|
||||
*/
|
||||
@@ -109,21 +109,6 @@ import PhotosUI
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
A boolean that indicates whether render engine should retain SCNTechnique used in the view. Default is `false`.
|
||||
*/
|
||||
@objc public var retainTechnique: Bool = false {
|
||||
didSet {
|
||||
if retainTechnique {
|
||||
guard let techniqueSupportingView = view as? SCNTechniqueSupport else {
|
||||
return
|
||||
}
|
||||
renderEngine?.technique = techniqueSupportingView.technique
|
||||
} else {
|
||||
renderEngine?.technique = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - Public initialization methods
|
||||
/**
|
||||
@@ -143,9 +128,16 @@ import PhotosUI
|
||||
view = ARSpriteKit
|
||||
scnView = SCNView(frame: UIScreen.main.bounds)
|
||||
|
||||
let scene = SCNScene()
|
||||
scnView.scene = scene
|
||||
setup()
|
||||
let bundle = Bundle(for: RecordAR.self)
|
||||
let url = bundle.url(forResource: "video.scnassets/vid", withExtension: "scn")
|
||||
|
||||
do {
|
||||
let scene = try SCNScene(url: url!, options: nil)
|
||||
scnView.scene = scene
|
||||
setup()
|
||||
}catch let error {
|
||||
logAR.message("Error occurred while loading SK Video Assets : \(error). Please download \"video.scnassets\" from\nwww.ahmedbekhit.com/ARVideoKitAssets")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,6 +164,7 @@ import PhotosUI
|
||||
private var renderEngine: SCNRenderer!
|
||||
private var gpuLoop: CADisplayLink!
|
||||
private var isResting = false
|
||||
private var ARcontentMode: ARFrameMode!
|
||||
private var renderer: RenderAR!
|
||||
|
||||
private var scnView: SCNView!
|
||||
@@ -723,8 +716,8 @@ import PhotosUI
|
||||
Recommended to use in the `UIViewController`'s method `func viewWillAppear(_ animated: Bool)`
|
||||
- parameter configuration: An object that defines motion and scene tracking behaviors for the session.
|
||||
*/
|
||||
@objc func prepare(_ configuration: ARConfiguration? = nil) {
|
||||
renderer.ARcontentMode = contentMode
|
||||
@objc public func prepare(_ configuration: ARConfiguration? = nil) {
|
||||
ARcontentMode = contentMode
|
||||
onlyRenderWhileRec = onlyRenderWhileRecording
|
||||
if let view = view as? ARSCNView {
|
||||
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
|
||||
@@ -748,7 +741,7 @@ import PhotosUI
|
||||
|
||||
Recommended to use in the `UIViewController`'s method `func viewWillDisappear(_ animated: Bool)`.
|
||||
*/
|
||||
@objc func rest() {
|
||||
@objc public func rest() {
|
||||
ViewAR.orientation = UIInterfaceOrientationMask(ViewAR.orientations)
|
||||
}
|
||||
}
|
||||
@@ -760,8 +753,6 @@ extension RecordAR {
|
||||
//frame rendering
|
||||
if self.onlyRenderWhileRec && !isRecording && !isRecordingGIF { return }
|
||||
|
||||
renderer.ARcontentMode = contentMode
|
||||
|
||||
guard let buffer = renderer.buffer else { return }
|
||||
guard let rawBuffer = renderer.rawBuffer else {
|
||||
logAR.message("ERROR:- An error occurred while rendering the camera's main buffers.")
|
||||
@@ -771,6 +762,7 @@ extension RecordAR {
|
||||
logAR.message("ERROR:- An error occurred while rendering the camera buffer.")
|
||||
return
|
||||
}
|
||||
renderer.ARcontentMode = contentMode
|
||||
|
||||
self.writerQueue.sync {
|
||||
|
||||
|
||||
@@ -429,7 +429,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.ahmedbekhit.ARVideoKit-Example";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -451,7 +451,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.ahmedbekhit.ARVideoKit-Example";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
|
||||
+2
-17
@@ -1,23 +1,8 @@
|
||||
// swift-tools-version:5.1
|
||||
// swift-tools-version:4.0
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "ARVideoKit",
|
||||
platforms: [
|
||||
.iOS(.v11)
|
||||
],
|
||||
products: [
|
||||
.library(
|
||||
name: "ARVideoKit",
|
||||
targets: ["ARVideoKit"]),
|
||||
],
|
||||
dependencies: [ ],
|
||||
targets: [
|
||||
.target(
|
||||
name: "ARVideoKit",
|
||||
dependencies: [],
|
||||
path: "ARVideoKit")
|
||||
]
|
||||
name: "ARVideoKit"
|
||||
)
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
> Use [swift_4_2](https://github.com/AFathi/ARVideoKit/tree/swift_4_2) branch for projects written in Swift 4.2
|
||||
> Use [swift_5](https://github.com/AFathi/ARVideoKit/tree/swift_5) branch for projects written in Swift 5
|
||||
|
||||
> Use [master](https://github.com/AFathi/ARVideoKit/tree/master) branch for projects written in Swift 4.0
|
||||
|
||||
## Sponsors
|
||||
[**Chemical Wedding**](https://www.chemicalwedding.tv)
|
||||
|
||||

|
||||
|
||||
## ARVideoKit
|
||||
|
||||

|
||||
|
||||
An iOS Framework that enables developers to capture videos 📹, photos 🌄, Live Photos 🎇, and GIFs 🎆 with ARKit content.
|
||||
@@ -27,7 +20,6 @@ In other words, you **NO LONGER** have to ~screen record~/~screenshot~ to captur
|
||||
| [Implementation](#implementation) | Lists the [steps needed](#implementation) for Objective-C & Swift, [notes](#note), and [reference](#youre-all-set-) for more options |
|
||||
| [Publishing to the App Store](#publishing-to-the-app-store) | Describes the steps **required** before submitting an application using `ARVideoKit` to the App Store. |
|
||||
|[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ahmedfbekhit@gmail.com&item_name=Support+ARVideoKit+Developer&item_number=ARVideoKit+Framework+Donations&amount=0%2e00¤cy_code=USD) | [Donations](#donate) will support me to keep maintaining `ARVideoKit` ❤️|
|
||||
|[Sponsors](#sponsors) | Featuring the sponsors of this project |
|
||||
| [Contributions](#contributions) | Describes how you can contribute to this project |
|
||||
| [Apps using ARVideoKit](#apps-using-arvideokit) | A list of published applications using ARVideoKit |
|
||||
| [License](#license) | Describes `ARVideoKit` license |
|
||||
@@ -62,10 +54,9 @@ To try the example project, simply clone this repository and open the `Examples`
|
||||
|
||||
## Installation
|
||||
### Cocoapods
|
||||
1. Add this line to your project's `Podfile` (for Swift 5.0)
|
||||
1. Add this line to your project's `Podfile` (for Swift 4.2 projects)
|
||||
```
|
||||
pod 'ARVideoKit', '~> 1.5.51'
|
||||
|
||||
pod 'ARVideoKit','~> 1.51'
|
||||
```
|
||||
2. Install the pod
|
||||
```
|
||||
@@ -82,11 +73,6 @@ github "AFathi/ARVideoKit" ~> 1.31
|
||||
$ carthage update
|
||||
```
|
||||
|
||||
### Swift Package Manager (available Xcode 11.2 and forward)
|
||||
|
||||
1. In Xcode, select File > Swift Packages > Add Package Dependency.
|
||||
2. Follow the prompts using the URL for this repository.
|
||||
|
||||
### Manual
|
||||
Drag `ARVideoKit.xcodeproj` into your project and click the **+** button in the embedded binaries section of your project's target.
|
||||

|
||||
@@ -154,7 +140,7 @@ To do so, follow those steps:
|
||||
Donations will support me to keep maintining **ARVideoKit Framework** ❤️
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ahmedfbekhit@gmail.com&item_name=Support+ARVideoKit+Developer&item_number=ARVideoKit+Framework+Donations&amount=0%2e00¤cy_code=USD)
|
||||
|
||||
|
||||
## Contributions
|
||||
If you have an idea for a new **ARVideoKit** feature/functionality and want to add it to this repository, feel free to fork the project and create a pull request!
|
||||
|
||||
@@ -163,10 +149,7 @@ Also, feel free to create an issue if you have any suggestions or need any help
|
||||
## Apps using ARVideoKit
|
||||
| App | Description |
|
||||
| ------------------ |:------------------:|
|
||||
| [Pathica](https://apps.apple.com/us/app/pathica/id1564780182) | The first proof of the theory of "six degrees of separation" which is the idea that any two people on the planet can be connected through five or fewer individuals. |
|
||||
| [Our SolAR](https://itunes.apple.com/app/id1267675913) | An app that allows you to see our Solar System anywhere at all! |
|
||||
| [In The Walls](https://apps.apple.com/us/app/id1522257130) | Uses real time face tracking and AR to put your face in any real world wall! |
|
||||
| [ScribScrab](https://apps.apple.com/in/app/scribscrab/id1339432955) | ScribScrab is a tool for creativity. You’re only limited to your imagination and your battery life. |
|
||||
|
||||
_Feel free to add your application to this list!_
|
||||
## License
|
||||
|
||||
Reference in New Issue
Block a user