A => .gitignore +1 -0
A => AR-SDF-Renderer/AR-SDF-Renderer.xcodeproj/project.pbxproj +703 -0
@@ 1,703 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 55;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ B9D8709327C0185500775F31 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8709227C0185500775F31 /* AppDelegate.swift */; };
+ B9D8709527C0185500775F31 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8709427C0185500775F31 /* SceneDelegate.swift */; };
+ B9D8709727C0185500775F31 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8709627C0185500775F31 /* ViewController.swift */; };
+ B9D8709A27C0185500775F31 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9D8709827C0185500775F31 /* Main.storyboard */; };
+ B9D8709C27C0185800775F31 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B9D8709B27C0185800775F31 /* Assets.xcassets */; };
+ B9D8709F27C0185800775F31 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9D8709D27C0185800775F31 /* LaunchScreen.storyboard */; };
+ B9D870AA27C0185800775F31 /* AR_SDF_RendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D870A927C0185800775F31 /* AR_SDF_RendererTests.swift */; };
+ B9D870B427C0185800775F31 /* AR_SDF_RendererUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D870B327C0185800775F31 /* AR_SDF_RendererUITests.swift */; };
+ B9D870B627C0185800775F31 /* AR_SDF_RendererUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D870B527C0185800775F31 /* AR_SDF_RendererUITestsLaunchTests.swift */; };
+ B9D8715527C13AEF00775F31 /* AR_SDF.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9D8714D27C058CA00775F31 /* AR_SDF.framework */; platformFilter = ios; };
+ B9D8715627C13AEF00775F31 /* AR_SDF.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B9D8714D27C058CA00775F31 /* AR_SDF.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ B9D870A627C0185800775F31 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = B9D8708727C0185500775F31 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B9D8708E27C0185500775F31;
+ remoteInfo = "AR-SDF-Renderer";
+ };
+ B9D870B027C0185800775F31 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = B9D8708727C0185500775F31 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B9D8708E27C0185500775F31;
+ remoteInfo = "AR-SDF-Renderer";
+ };
+ B9D8714C27C058CA00775F31 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = B9D8714727C058CA00775F31 /* AR-SDF.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = B9D8703327BFF97900775F31;
+ remoteInfo = "AR-SDF";
+ };
+ B9D8714E27C058CA00775F31 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = B9D8714727C058CA00775F31 /* AR-SDF.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = B9D8703D27BFF97A00775F31;
+ remoteInfo = "AR-SDFTests";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ B9D8715727C13AF000775F31 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ B9D8715627C13AEF00775F31 /* AR_SDF.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ B9D8708F27C0185500775F31 /* AR-SDF-Renderer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "AR-SDF-Renderer.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ B9D8709227C0185500775F31 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+ B9D8709427C0185500775F31 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
+ B9D8709627C0185500775F31 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
+ B9D8709927C0185500775F31 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ B9D8709B27C0185800775F31 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ B9D8709E27C0185800775F31 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+ B9D870A027C0185800775F31 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ B9D870A527C0185800775F31 /* AR-SDF-RendererTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "AR-SDF-RendererTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ B9D870A927C0185800775F31 /* AR_SDF_RendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AR_SDF_RendererTests.swift; sourceTree = "<group>"; };
+ B9D870AF27C0185800775F31 /* AR-SDF-RendererUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "AR-SDF-RendererUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ B9D870B327C0185800775F31 /* AR_SDF_RendererUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AR_SDF_RendererUITests.swift; sourceTree = "<group>"; };
+ B9D870B527C0185800775F31 /* AR_SDF_RendererUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AR_SDF_RendererUITestsLaunchTests.swift; sourceTree = "<group>"; };
+ B9D8714727C058CA00775F31 /* AR-SDF.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "AR-SDF.xcodeproj"; path = "../AR-SDF/AR-SDF.xcodeproj"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ B9D8708C27C0185500775F31 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D8715527C13AEF00775F31 /* AR_SDF.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D870A227C0185800775F31 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D870AC27C0185800775F31 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ B9D8708627C0185500775F31 = {
+ isa = PBXGroup;
+ children = (
+ B9D8714727C058CA00775F31 /* AR-SDF.xcodeproj */,
+ B9D8709127C0185500775F31 /* AR-SDF-Renderer */,
+ B9D870A827C0185800775F31 /* AR-SDF-RendererTests */,
+ B9D870B227C0185800775F31 /* AR-SDF-RendererUITests */,
+ B9D8709027C0185500775F31 /* Products */,
+ B9D8715427C13AEF00775F31 /* Frameworks */,
+ );
+ sourceTree = "<group>";
+ };
+ B9D8709027C0185500775F31 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8708F27C0185500775F31 /* AR-SDF-Renderer.app */,
+ B9D870A527C0185800775F31 /* AR-SDF-RendererTests.xctest */,
+ B9D870AF27C0185800775F31 /* AR-SDF-RendererUITests.xctest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ B9D8709127C0185500775F31 /* AR-SDF-Renderer */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8709227C0185500775F31 /* AppDelegate.swift */,
+ B9D8709427C0185500775F31 /* SceneDelegate.swift */,
+ B9D8709627C0185500775F31 /* ViewController.swift */,
+ B9D8709827C0185500775F31 /* Main.storyboard */,
+ B9D8709B27C0185800775F31 /* Assets.xcassets */,
+ B9D8709D27C0185800775F31 /* LaunchScreen.storyboard */,
+ B9D870A027C0185800775F31 /* Info.plist */,
+ );
+ path = "AR-SDF-Renderer";
+ sourceTree = "<group>";
+ };
+ B9D870A827C0185800775F31 /* AR-SDF-RendererTests */ = {
+ isa = PBXGroup;
+ children = (
+ B9D870A927C0185800775F31 /* AR_SDF_RendererTests.swift */,
+ );
+ path = "AR-SDF-RendererTests";
+ sourceTree = "<group>";
+ };
+ B9D870B227C0185800775F31 /* AR-SDF-RendererUITests */ = {
+ isa = PBXGroup;
+ children = (
+ B9D870B327C0185800775F31 /* AR_SDF_RendererUITests.swift */,
+ B9D870B527C0185800775F31 /* AR_SDF_RendererUITestsLaunchTests.swift */,
+ );
+ path = "AR-SDF-RendererUITests";
+ sourceTree = "<group>";
+ };
+ B9D8714827C058CA00775F31 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8714D27C058CA00775F31 /* AR_SDF.framework */,
+ B9D8714F27C058CA00775F31 /* AR-SDFTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ B9D8715427C13AEF00775F31 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ B9D8708E27C0185500775F31 /* AR-SDF-Renderer */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B9D870B927C0185800775F31 /* Build configuration list for PBXNativeTarget "AR-SDF-Renderer" */;
+ buildPhases = (
+ B9D8708B27C0185500775F31 /* Sources */,
+ B9D8708C27C0185500775F31 /* Frameworks */,
+ B9D8708D27C0185500775F31 /* Resources */,
+ B9D8715727C13AF000775F31 /* Embed Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "AR-SDF-Renderer";
+ productName = "AR-SDF-Renderer";
+ productReference = B9D8708F27C0185500775F31 /* AR-SDF-Renderer.app */;
+ productType = "com.apple.product-type.application";
+ };
+ B9D870A427C0185800775F31 /* AR-SDF-RendererTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B9D870BC27C0185800775F31 /* Build configuration list for PBXNativeTarget "AR-SDF-RendererTests" */;
+ buildPhases = (
+ B9D870A127C0185800775F31 /* Sources */,
+ B9D870A227C0185800775F31 /* Frameworks */,
+ B9D870A327C0185800775F31 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B9D870A727C0185800775F31 /* PBXTargetDependency */,
+ );
+ name = "AR-SDF-RendererTests";
+ productName = "AR-SDF-RendererTests";
+ productReference = B9D870A527C0185800775F31 /* AR-SDF-RendererTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ B9D870AE27C0185800775F31 /* AR-SDF-RendererUITests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B9D870BF27C0185800775F31 /* Build configuration list for PBXNativeTarget "AR-SDF-RendererUITests" */;
+ buildPhases = (
+ B9D870AB27C0185800775F31 /* Sources */,
+ B9D870AC27C0185800775F31 /* Frameworks */,
+ B9D870AD27C0185800775F31 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B9D870B127C0185800775F31 /* PBXTargetDependency */,
+ );
+ name = "AR-SDF-RendererUITests";
+ productName = "AR-SDF-RendererUITests";
+ productReference = B9D870AF27C0185800775F31 /* AR-SDF-RendererUITests.xctest */;
+ productType = "com.apple.product-type.bundle.ui-testing";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ B9D8708727C0185500775F31 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1310;
+ LastUpgradeCheck = 1310;
+ TargetAttributes = {
+ B9D8708E27C0185500775F31 = {
+ CreatedOnToolsVersion = 13.1;
+ };
+ B9D870A427C0185800775F31 = {
+ CreatedOnToolsVersion = 13.1;
+ TestTargetID = B9D8708E27C0185500775F31;
+ };
+ B9D870AE27C0185800775F31 = {
+ CreatedOnToolsVersion = 13.1;
+ TestTargetID = B9D8708E27C0185500775F31;
+ };
+ };
+ };
+ buildConfigurationList = B9D8708A27C0185500775F31 /* Build configuration list for PBXProject "AR-SDF-Renderer" */;
+ compatibilityVersion = "Xcode 13.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = B9D8708627C0185500775F31;
+ productRefGroup = B9D8709027C0185500775F31 /* Products */;
+ projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = B9D8714827C058CA00775F31 /* Products */;
+ ProjectRef = B9D8714727C058CA00775F31 /* AR-SDF.xcodeproj */;
+ },
+ );
+ projectRoot = "";
+ targets = (
+ B9D8708E27C0185500775F31 /* AR-SDF-Renderer */,
+ B9D870A427C0185800775F31 /* AR-SDF-RendererTests */,
+ B9D870AE27C0185800775F31 /* AR-SDF-RendererUITests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+ B9D8714D27C058CA00775F31 /* AR_SDF.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = AR_SDF.framework;
+ remoteRef = B9D8714C27C058CA00775F31 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ B9D8714F27C058CA00775F31 /* AR-SDFTests.xctest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = "AR-SDFTests.xctest";
+ remoteRef = B9D8714E27C058CA00775F31 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+ B9D8708D27C0185500775F31 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D8709F27C0185800775F31 /* LaunchScreen.storyboard in Resources */,
+ B9D8709C27C0185800775F31 /* Assets.xcassets in Resources */,
+ B9D8709A27C0185500775F31 /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D870A327C0185800775F31 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D870AD27C0185800775F31 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ B9D8708B27C0185500775F31 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D8709727C0185500775F31 /* ViewController.swift in Sources */,
+ B9D8709327C0185500775F31 /* AppDelegate.swift in Sources */,
+ B9D8709527C0185500775F31 /* SceneDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D870A127C0185800775F31 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D870AA27C0185800775F31 /* AR_SDF_RendererTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D870AB27C0185800775F31 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D870B627C0185800775F31 /* AR_SDF_RendererUITestsLaunchTests.swift in Sources */,
+ B9D870B427C0185800775F31 /* AR_SDF_RendererUITests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ B9D870A727C0185800775F31 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B9D8708E27C0185500775F31 /* AR-SDF-Renderer */;
+ targetProxy = B9D870A627C0185800775F31 /* PBXContainerItemProxy */;
+ };
+ B9D870B127C0185800775F31 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B9D8708E27C0185500775F31 /* AR-SDF-Renderer */;
+ targetProxy = B9D870B027C0185800775F31 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ B9D8709827C0185500775F31 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ B9D8709927C0185500775F31 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+ B9D8709D27C0185800775F31 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ B9D8709E27C0185800775F31 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ B9D870B727C0185800775F31 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ B9D870B827C0185800775F31 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ B9D870BA27C0185800775F31 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "AR-SDF-Renderer/Info.plist";
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
+ INFOPLIST_KEY_UIMainStoryboardFile = Main;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDF-Renderer";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ B9D870BB27C0185800775F31 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "AR-SDF-Renderer/Info.plist";
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
+ INFOPLIST_KEY_UIMainStoryboardFile = Main;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDF-Renderer";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ B9D870BD27C0185800775F31 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ GENERATE_INFOPLIST_FILE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDF-RendererTests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AR-SDF-Renderer.app/AR-SDF-Renderer";
+ };
+ name = Debug;
+ };
+ B9D870BE27C0185800775F31 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ GENERATE_INFOPLIST_FILE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDF-RendererTests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AR-SDF-Renderer.app/AR-SDF-Renderer";
+ };
+ name = Release;
+ };
+ B9D870C027C0185800775F31 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ GENERATE_INFOPLIST_FILE = YES;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDF-RendererUITests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = "AR-SDF-Renderer";
+ };
+ name = Debug;
+ };
+ B9D870C127C0185800775F31 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ GENERATE_INFOPLIST_FILE = YES;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDF-RendererUITests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = "AR-SDF-Renderer";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ B9D8708A27C0185500775F31 /* Build configuration list for PBXProject "AR-SDF-Renderer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B9D870B727C0185800775F31 /* Debug */,
+ B9D870B827C0185800775F31 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B9D870B927C0185800775F31 /* Build configuration list for PBXNativeTarget "AR-SDF-Renderer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B9D870BA27C0185800775F31 /* Debug */,
+ B9D870BB27C0185800775F31 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B9D870BC27C0185800775F31 /* Build configuration list for PBXNativeTarget "AR-SDF-RendererTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B9D870BD27C0185800775F31 /* Debug */,
+ B9D870BE27C0185800775F31 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B9D870BF27C0185800775F31 /* Build configuration list for PBXNativeTarget "AR-SDF-RendererUITests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B9D870C027C0185800775F31 /* Debug */,
+ B9D870C127C0185800775F31 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = B9D8708727C0185500775F31 /* Project object */;
+}
A => AR-SDF-Renderer/AR-SDF-Renderer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
@@ 1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:">
+ </FileRef>
+</Workspace>
A => AR-SDF-Renderer/AR-SDF-Renderer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
@@ 1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IDEDidComputeMac32BitWarning</key>
+ <true/>
+</dict>
+</plist>
A => AR-SDF-Renderer/AR-SDF-Renderer.xcodeproj/project.xcworkspace/xcuserdata/connorbell.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
A => AR-SDF-Renderer/AR-SDF-Renderer.xcodeproj/xcuserdata/connorbell.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +6 -0
@@ 1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Bucket
+ uuid = "D030DA74-D6E5-487E-A2E4-F2C751FF240A"
+ type = "1"
+ version = "2.0">
+</Bucket>
A => AR-SDF-Renderer/AR-SDF-Renderer.xcodeproj/xcuserdata/connorbell.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
@@ 1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>SchemeUserState</key>
+ <dict>
+ <key>AR-SDF-Renderer.xcscheme_^#shared#^_</key>
+ <dict>
+ <key>orderHint</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+</dict>
+</plist>
A => AR-SDF-Renderer/AR-SDF-Renderer/AppDelegate.swift +36 -0
@@ 1,36 @@
+//
+// AppDelegate.swift
+// AR-SDF-Renderer
+//
+// Created by Connor Bell on 2022-02-18.
+//
+
+import UIKit
+
+@main
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ // Override point for customization after application launch.
+ return true
+ }
+
+ // MARK: UISceneSession Lifecycle
+
+ func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
+ // Called when a new scene session is being created.
+ // Use this method to select a configuration to create the new scene with.
+ return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
+ }
+
+ func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
+ // Called when the user discards a scene session.
+ // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
+ // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
+ }
+
+
+}
+
A => AR-SDF-Renderer/AR-SDF-Renderer/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
@@ 1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
A => AR-SDF-Renderer/AR-SDF-Renderer/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
@@ 1,98 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "60x60"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "60x60"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "1x",
+ "size" : "76x76"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "76x76"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "83.5x83.5"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
A => AR-SDF-Renderer/AR-SDF-Renderer/Assets.xcassets/Contents.json +6 -0
@@ 1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
A => AR-SDF-Renderer/AR-SDF-Renderer/Base.lproj/LaunchScreen.storyboard +25 -0
@@ 1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
A => AR-SDF-Renderer/AR-SDF-Renderer/Base.lproj/Main.storyboard +24 -0
@@ 1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="tne-QT-ifu">
+ <objects>
+ <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+ </objects>
+ </scene>
+ </scenes>
+</document>
A => AR-SDF-Renderer/AR-SDF-Renderer/Info.plist +27 -0
@@ 1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>UIApplicationSceneManifest</key>
+ <dict>
+ <key>UIApplicationSupportsMultipleScenes</key>
+ <false/>
+ <key>UISceneConfigurations</key>
+ <dict>
+ <key>UIWindowSceneSessionRoleApplication</key>
+ <array>
+ <dict>
+ <key>UISceneConfigurationName</key>
+ <string>Default Configuration</string>
+ <key>UISceneDelegateClassName</key>
+ <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
+ <key>UISceneStoryboardFile</key>
+ <string>Main</string>
+ </dict>
+ </array>
+ </dict>
+ </dict>
+ <key>NSCameraUsageDescription</key>
+ <string>This app requires camera for AR.</string>
+</dict>
+</plist>
A => AR-SDF-Renderer/AR-SDF-Renderer/SceneDelegate.swift +52 -0
@@ 1,52 @@
+//
+// SceneDelegate.swift
+// AR-SDF-Renderer
+//
+// Created by Connor Bell on 2022-02-18.
+//
+
+import UIKit
+
+class SceneDelegate: UIResponder, UIWindowSceneDelegate {
+
+ var window: UIWindow?
+
+
+ func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
+ // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
+ // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
+ // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
+ guard let _ = (scene as? UIWindowScene) else { return }
+ }
+
+ func sceneDidDisconnect(_ scene: UIScene) {
+ // Called as the scene is being released by the system.
+ // This occurs shortly after the scene enters the background, or when its session is discarded.
+ // Release any resources associated with this scene that can be re-created the next time the scene connects.
+ // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
+ }
+
+ func sceneDidBecomeActive(_ scene: UIScene) {
+ // Called when the scene has moved from an inactive state to an active state.
+ // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
+ }
+
+ func sceneWillResignActive(_ scene: UIScene) {
+ // Called when the scene will move from an active state to an inactive state.
+ // This may occur due to temporary interruptions (ex. an incoming phone call).
+ }
+
+ func sceneWillEnterForeground(_ scene: UIScene) {
+ // Called as the scene transitions from the background to the foreground.
+ // Use this method to undo the changes made on entering the background.
+ }
+
+ func sceneDidEnterBackground(_ scene: UIScene) {
+ // Called as the scene transitions from the foreground to the background.
+ // Use this method to save data, release shared resources, and store enough scene-specific state information
+ // to restore the scene back to its current state.
+ }
+
+
+}
+
A => AR-SDF-Renderer/AR-SDF-Renderer/ViewController.swift +37 -0
@@ 1,37 @@
+//
+// ViewController.swift
+// AR-SDF-Renderer
+//
+// Created by Connor Bell on 2022-02-18.
+//
+
+import UIKit
+import AR_SDF
+import simd
+
+class ViewController: UIViewController {
+
+ var arSDFView: ARSDFView?
+
+ override func viewDidLoad() {
+ let cubeSizeUniform = Float3Uniform(name: "Cube Size",
+ range: CGSize(width: 0.1, height: 5.0),
+ value: simd_float3(0.5, 0.5, 0.5))
+
+ let distanceField = DistanceField(kernelName: "tunnel",
+ uniforms: [cubeSizeUniform])
+
+ arSDFView = ARSDFView(frame: self.view.frame)
+
+ self.view.addSubview(arSDFView!)
+ arSDFView?.start(distanceFields: [distanceField])
+
+ super.viewDidLoad()
+ }
+
+ override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+ super.viewWillTransition(to: size, with: coordinator)
+ arSDFView?.updateResolution(resolution: size)
+ }
+}
+
A => AR-SDF-Renderer/AR-SDF-RendererTests/AR_SDF_RendererTests.swift +33 -0
@@ 1,33 @@
+//
+// AR_SDF_RendererTests.swift
+// AR-SDF-RendererTests
+//
+// Created by Connor Bell on 2022-02-18.
+//
+
+import XCTest
+@testable import AR_SDF_Renderer
+
+class AR_SDF_RendererTests: XCTestCase {
+
+ override func setUpWithError() throws {
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+ }
+
+ override func tearDownWithError() throws {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ }
+
+ func testExample() throws {
+ // This is an example of a functional test case.
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
+ }
+
+ func testPerformanceExample() throws {
+ // This is an example of a performance test case.
+ self.measure {
+ // Put the code you want to measure the time of here.
+ }
+ }
+
+}
A => AR-SDF-Renderer/AR-SDF-RendererUITests/AR_SDF_RendererUITests.swift +42 -0
@@ 1,42 @@
+//
+// AR_SDF_RendererUITests.swift
+// AR-SDF-RendererUITests
+//
+// Created by Connor Bell on 2022-02-18.
+//
+
+import XCTest
+
+class AR_SDF_RendererUITests: XCTestCase {
+
+ override func setUpWithError() throws {
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+
+ // In UI tests it is usually best to stop immediately when a failure occurs.
+ continueAfterFailure = false
+
+ // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
+ }
+
+ override func tearDownWithError() throws {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ }
+
+ func testExample() throws {
+ // UI tests must launch the application that they test.
+ let app = XCUIApplication()
+ app.launch()
+
+ // Use recording to get started writing UI tests.
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
+ }
+
+ func testLaunchPerformance() throws {
+ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
+ // This measures how long it takes to launch your application.
+ measure(metrics: [XCTApplicationLaunchMetric()]) {
+ XCUIApplication().launch()
+ }
+ }
+ }
+}
A => AR-SDF-Renderer/AR-SDF-RendererUITests/AR_SDF_RendererUITestsLaunchTests.swift +32 -0
@@ 1,32 @@
+//
+// AR_SDF_RendererUITestsLaunchTests.swift
+// AR-SDF-RendererUITests
+//
+// Created by Connor Bell on 2022-02-18.
+//
+
+import XCTest
+
+class AR_SDF_RendererUITestsLaunchTests: XCTestCase {
+
+ override class var runsForEachTargetApplicationUIConfiguration: Bool {
+ true
+ }
+
+ override func setUpWithError() throws {
+ continueAfterFailure = false
+ }
+
+ func testLaunch() throws {
+ let app = XCUIApplication()
+ app.launch()
+
+ // Insert steps here to perform after app launch but before taking a screenshot,
+ // such as logging into a test account or navigating somewhere in the app
+
+ let attachment = XCTAttachment(screenshot: app.screenshot())
+ attachment.name = "Launch Screen"
+ attachment.lifetime = .keepAlways
+ add(attachment)
+ }
+}
A => AR-SDF/AR-SDF.xcodeproj/project.pbxproj +597 -0
@@ 1,597 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 55;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ B9D8703827BFF97900775F31 /* AR_SDF.docc in Sources */ = {isa = PBXBuildFile; fileRef = B9D8703727BFF97900775F31 /* AR_SDF.docc */; };
+ B9D8703E27BFF97A00775F31 /* AR_SDF.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9D8703327BFF97900775F31 /* AR_SDF.framework */; };
+ B9D8704327BFF97A00775F31 /* AR_SDFTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8704227BFF97A00775F31 /* AR_SDFTests.swift */; };
+ B9D8704427BFF97A00775F31 /* AR_SDF.h in Headers */ = {isa = PBXBuildFile; fileRef = B9D8703627BFF97900775F31 /* AR_SDF.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ B9D8705427BFF9A300775F31 /* Conemarcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8704D27BFF9A300775F31 /* Conemarcher.swift */; };
+ B9D8705527BFF9A300775F31 /* ComputePass.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8704E27BFF9A300775F31 /* ComputePass.swift */; };
+ B9D8705627BFF9A300775F31 /* RendererDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8704F27BFF9A300775F31 /* RendererDelegate.swift */; };
+ B9D8705727BFF9A300775F31 /* ARSDFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8705027BFF9A300775F31 /* ARSDFView.swift */; };
+ B9D8705827BFF9A300775F31 /* MetalManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8705127BFF9A300775F31 /* MetalManager.swift */; };
+ B9D8705927BFF9A300775F31 /* ARManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8705227BFF9A300775F31 /* ARManager.swift */; };
+ B9D8705A27BFF9A300775F31 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8705327BFF9A300775F31 /* MetalView.swift */; };
+ B9D8706227BFFA4E00775F31 /* DistanceField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8705C27BFFA4E00775F31 /* DistanceField.swift */; };
+ B9D8706327BFFA4E00775F31 /* Uniform.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8705D27BFFA4E00775F31 /* Uniform.swift */; };
+ B9D8706627BFFA4E00775F31 /* TextureUniform.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8706027BFFA4E00775F31 /* TextureUniform.swift */; };
+ B9D8706727BFFA4E00775F31 /* ARData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8706127BFFA4E00775F31 /* ARData.swift */; };
+ B9D8706A27BFFC1400775F31 /* CVPixelBuffer+MTLTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8706927BFFC1400775F31 /* CVPixelBuffer+MTLTexture.swift */; };
+ B9D8706C27BFFC1B00775F31 /* MTLTexture+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8706B27BFFC1B00775F31 /* MTLTexture+Extensions.swift */; };
+ B9D8706E27BFFD5200775F31 /* UIInterfaceOrientation+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8706D27BFFD5200775F31 /* UIInterfaceOrientation+Extensions.swift */; };
+ B9D8707027C001A000775F31 /* Float4x4+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9D8706F27C001A000775F31 /* Float4x4+Extensions.swift */; };
+ B9D8707527C0031600775F31 /* Conemarcher.metal in Sources */ = {isa = PBXBuildFile; fileRef = B9D8707427C0031600775F31 /* Conemarcher.metal */; };
+ B9D8707727C0031E00775F31 /* YCbCrToRGB.metal in Sources */ = {isa = PBXBuildFile; fileRef = B9D8707627C0031E00775F31 /* YCbCrToRGB.metal */; };
+ B9D8707927C0034100775F31 /* DistanceFields.h in Headers */ = {isa = PBXBuildFile; fileRef = B9D8707827C0034100775F31 /* DistanceFields.h */; };
+ B9D8707B27C0039C00775F31 /* Common.h in Headers */ = {isa = PBXBuildFile; fileRef = B9D8707A27C0039C00775F31 /* Common.h */; };
+ B9D8707D27C0043C00775F31 /* PostFxPass.metal in Sources */ = {isa = PBXBuildFile; fileRef = B9D8707C27C0043C00775F31 /* PostFxPass.metal */; };
+ B9D8708227C0048600775F31 /* OrientationTransforms.h in Headers */ = {isa = PBXBuildFile; fileRef = B9D8708027C0048600775F31 /* OrientationTransforms.h */; };
+ B9D8708527C0072900775F31 /* OrientationTransforms.metal in Sources */ = {isa = PBXBuildFile; fileRef = B9D8708427C0072900775F31 /* OrientationTransforms.metal */; };
+ B9D8715227C138DE00775F31 /* DistanceFields.metal in Sources */ = {isa = PBXBuildFile; fileRef = B9D8715027C138DE00775F31 /* DistanceFields.metal */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ B9D8703F27BFF97A00775F31 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = B9D8702A27BFF97900775F31 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B9D8703227BFF97900775F31;
+ remoteInfo = "AR-SDF";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ B9D8703327BFF97900775F31 /* AR_SDF.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AR_SDF.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ B9D8703627BFF97900775F31 /* AR_SDF.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AR_SDF.h; sourceTree = "<group>"; };
+ B9D8703727BFF97900775F31 /* AR_SDF.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = AR_SDF.docc; sourceTree = "<group>"; };
+ B9D8703D27BFF97A00775F31 /* AR-SDFTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "AR-SDFTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ B9D8704227BFF97A00775F31 /* AR_SDFTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AR_SDFTests.swift; sourceTree = "<group>"; };
+ B9D8704D27BFF9A300775F31 /* Conemarcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Conemarcher.swift; sourceTree = "<group>"; };
+ B9D8704E27BFF9A300775F31 /* ComputePass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComputePass.swift; sourceTree = "<group>"; };
+ B9D8704F27BFF9A300775F31 /* RendererDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RendererDelegate.swift; sourceTree = "<group>"; };
+ B9D8705027BFF9A300775F31 /* ARSDFView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ARSDFView.swift; sourceTree = "<group>"; };
+ B9D8705127BFF9A300775F31 /* MetalManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalManager.swift; sourceTree = "<group>"; };
+ B9D8705227BFF9A300775F31 /* ARManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ARManager.swift; sourceTree = "<group>"; };
+ B9D8705327BFF9A300775F31 /* MetalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = "<group>"; };
+ B9D8705C27BFFA4E00775F31 /* DistanceField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DistanceField.swift; sourceTree = "<group>"; };
+ B9D8705D27BFFA4E00775F31 /* Uniform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Uniform.swift; sourceTree = "<group>"; };
+ B9D8706027BFFA4E00775F31 /* TextureUniform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextureUniform.swift; sourceTree = "<group>"; };
+ B9D8706127BFFA4E00775F31 /* ARData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ARData.swift; sourceTree = "<group>"; };
+ B9D8706927BFFC1400775F31 /* CVPixelBuffer+MTLTexture.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CVPixelBuffer+MTLTexture.swift"; sourceTree = "<group>"; };
+ B9D8706B27BFFC1B00775F31 /* MTLTexture+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MTLTexture+Extensions.swift"; sourceTree = "<group>"; };
+ B9D8706D27BFFD5200775F31 /* UIInterfaceOrientation+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIInterfaceOrientation+Extensions.swift"; sourceTree = "<group>"; };
+ B9D8706F27C001A000775F31 /* Float4x4+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Float4x4+Extensions.swift"; sourceTree = "<group>"; };
+ B9D8707427C0031600775F31 /* Conemarcher.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Conemarcher.metal; sourceTree = "<group>"; };
+ B9D8707627C0031E00775F31 /* YCbCrToRGB.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = YCbCrToRGB.metal; sourceTree = "<group>"; };
+ B9D8707827C0034100775F31 /* DistanceFields.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DistanceFields.h; sourceTree = "<group>"; };
+ B9D8707A27C0039C00775F31 /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = "<group>"; };
+ B9D8707C27C0043C00775F31 /* PostFxPass.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = PostFxPass.metal; sourceTree = "<group>"; };
+ B9D8708027C0048600775F31 /* OrientationTransforms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OrientationTransforms.h; sourceTree = "<group>"; };
+ B9D8708427C0072900775F31 /* OrientationTransforms.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = OrientationTransforms.metal; sourceTree = "<group>"; };
+ B9D8715027C138DE00775F31 /* DistanceFields.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = DistanceFields.metal; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ B9D8703027BFF97900775F31 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D8703A27BFF97A00775F31 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D8703E27BFF97A00775F31 /* AR_SDF.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ B9D8702927BFF97900775F31 = {
+ isa = PBXGroup;
+ children = (
+ B9D8703527BFF97900775F31 /* AR-SDF */,
+ B9D8704127BFF97A00775F31 /* AR-SDFTests */,
+ B9D8703427BFF97900775F31 /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ B9D8703427BFF97900775F31 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8703327BFF97900775F31 /* AR_SDF.framework */,
+ B9D8703D27BFF97A00775F31 /* AR-SDFTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ B9D8703527BFF97900775F31 /* AR-SDF */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8707127C002EE00775F31 /* Shaders */,
+ B9D8706827BFFC0C00775F31 /* Extensions */,
+ B9D8705B27BFFA4E00775F31 /* Models */,
+ B9D8705227BFF9A300775F31 /* ARManager.swift */,
+ B9D8705027BFF9A300775F31 /* ARSDFView.swift */,
+ B9D8704E27BFF9A300775F31 /* ComputePass.swift */,
+ B9D8704D27BFF9A300775F31 /* Conemarcher.swift */,
+ B9D8705127BFF9A300775F31 /* MetalManager.swift */,
+ B9D8705327BFF9A300775F31 /* MetalView.swift */,
+ B9D8704F27BFF9A300775F31 /* RendererDelegate.swift */,
+ B9D8703627BFF97900775F31 /* AR_SDF.h */,
+ B9D8703727BFF97900775F31 /* AR_SDF.docc */,
+ );
+ path = "AR-SDF";
+ sourceTree = "<group>";
+ };
+ B9D8704127BFF97A00775F31 /* AR-SDFTests */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8704227BFF97A00775F31 /* AR_SDFTests.swift */,
+ );
+ path = "AR-SDFTests";
+ sourceTree = "<group>";
+ };
+ B9D8705B27BFFA4E00775F31 /* Models */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8705C27BFFA4E00775F31 /* DistanceField.swift */,
+ B9D8705D27BFFA4E00775F31 /* Uniform.swift */,
+ B9D8706027BFFA4E00775F31 /* TextureUniform.swift */,
+ B9D8706127BFFA4E00775F31 /* ARData.swift */,
+ );
+ path = Models;
+ sourceTree = "<group>";
+ };
+ B9D8706827BFFC0C00775F31 /* Extensions */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8706F27C001A000775F31 /* Float4x4+Extensions.swift */,
+ B9D8706D27BFFD5200775F31 /* UIInterfaceOrientation+Extensions.swift */,
+ B9D8706B27BFFC1B00775F31 /* MTLTexture+Extensions.swift */,
+ B9D8706927BFFC1400775F31 /* CVPixelBuffer+MTLTexture.swift */,
+ );
+ path = Extensions;
+ sourceTree = "<group>";
+ };
+ B9D8707127C002EE00775F31 /* Shaders */ = {
+ isa = PBXGroup;
+ children = (
+ B9D8707427C0031600775F31 /* Conemarcher.metal */,
+ B9D8707A27C0039C00775F31 /* Common.h */,
+ B9D8707827C0034100775F31 /* DistanceFields.h */,
+ B9D8715027C138DE00775F31 /* DistanceFields.metal */,
+ B9D8708027C0048600775F31 /* OrientationTransforms.h */,
+ B9D8708427C0072900775F31 /* OrientationTransforms.metal */,
+ B9D8707C27C0043C00775F31 /* PostFxPass.metal */,
+ B9D8707627C0031E00775F31 /* YCbCrToRGB.metal */,
+ );
+ path = Shaders;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ B9D8702E27BFF97900775F31 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D8708227C0048600775F31 /* OrientationTransforms.h in Headers */,
+ B9D8707927C0034100775F31 /* DistanceFields.h in Headers */,
+ B9D8704427BFF97A00775F31 /* AR_SDF.h in Headers */,
+ B9D8707B27C0039C00775F31 /* Common.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ B9D8703227BFF97900775F31 /* AR-SDF */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B9D8704727BFF97A00775F31 /* Build configuration list for PBXNativeTarget "AR-SDF" */;
+ buildPhases = (
+ B9D8702E27BFF97900775F31 /* Headers */,
+ B9D8702F27BFF97900775F31 /* Sources */,
+ B9D8703027BFF97900775F31 /* Frameworks */,
+ B9D8703127BFF97900775F31 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "AR-SDF";
+ productName = "AR-SDF";
+ productReference = B9D8703327BFF97900775F31 /* AR_SDF.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+ B9D8703C27BFF97A00775F31 /* AR-SDFTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B9D8704A27BFF97A00775F31 /* Build configuration list for PBXNativeTarget "AR-SDFTests" */;
+ buildPhases = (
+ B9D8703927BFF97A00775F31 /* Sources */,
+ B9D8703A27BFF97A00775F31 /* Frameworks */,
+ B9D8703B27BFF97A00775F31 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ B9D8704027BFF97A00775F31 /* PBXTargetDependency */,
+ );
+ name = "AR-SDFTests";
+ productName = "AR-SDFTests";
+ productReference = B9D8703D27BFF97A00775F31 /* AR-SDFTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ B9D8702A27BFF97900775F31 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1310;
+ LastUpgradeCheck = 1310;
+ TargetAttributes = {
+ B9D8703227BFF97900775F31 = {
+ CreatedOnToolsVersion = 13.1;
+ };
+ B9D8703C27BFF97A00775F31 = {
+ CreatedOnToolsVersion = 13.1;
+ };
+ };
+ };
+ buildConfigurationList = B9D8702D27BFF97900775F31 /* Build configuration list for PBXProject "AR-SDF" */;
+ compatibilityVersion = "Xcode 13.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = B9D8702927BFF97900775F31;
+ productRefGroup = B9D8703427BFF97900775F31 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ B9D8703227BFF97900775F31 /* AR-SDF */,
+ B9D8703C27BFF97A00775F31 /* AR-SDFTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ B9D8703127BFF97900775F31 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D8703B27BFF97A00775F31 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ B9D8702F27BFF97900775F31 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D8707D27C0043C00775F31 /* PostFxPass.metal in Sources */,
+ B9D8706627BFFA4E00775F31 /* TextureUniform.swift in Sources */,
+ B9D8715227C138DE00775F31 /* DistanceFields.metal in Sources */,
+ B9D8706327BFFA4E00775F31 /* Uniform.swift in Sources */,
+ B9D8707727C0031E00775F31 /* YCbCrToRGB.metal in Sources */,
+ B9D8706E27BFFD5200775F31 /* UIInterfaceOrientation+Extensions.swift in Sources */,
+ B9D8705A27BFF9A300775F31 /* MetalView.swift in Sources */,
+ B9D8703827BFF97900775F31 /* AR_SDF.docc in Sources */,
+ B9D8707027C001A000775F31 /* Float4x4+Extensions.swift in Sources */,
+ B9D8707527C0031600775F31 /* Conemarcher.metal in Sources */,
+ B9D8705927BFF9A300775F31 /* ARManager.swift in Sources */,
+ B9D8705427BFF9A300775F31 /* Conemarcher.swift in Sources */,
+ B9D8705727BFF9A300775F31 /* ARSDFView.swift in Sources */,
+ B9D8706A27BFFC1400775F31 /* CVPixelBuffer+MTLTexture.swift in Sources */,
+ B9D8705827BFF9A300775F31 /* MetalManager.swift in Sources */,
+ B9D8706227BFFA4E00775F31 /* DistanceField.swift in Sources */,
+ B9D8705527BFF9A300775F31 /* ComputePass.swift in Sources */,
+ B9D8706727BFFA4E00775F31 /* ARData.swift in Sources */,
+ B9D8705627BFF9A300775F31 /* RendererDelegate.swift in Sources */,
+ B9D8706C27BFFC1B00775F31 /* MTLTexture+Extensions.swift in Sources */,
+ B9D8708527C0072900775F31 /* OrientationTransforms.metal in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ B9D8703927BFF97A00775F31 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B9D8704327BFF97A00775F31 /* AR_SDFTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ B9D8704027BFF97A00775F31 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B9D8703227BFF97900775F31 /* AR-SDF */;
+ targetProxy = B9D8703F27BFF97A00775F31 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ B9D8704527BFF97A00775F31 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ B9D8704627BFF97A00775F31 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
+ B9D8704827BFF97A00775F31 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDF";
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ SUPPORTS_MACCATALYST = NO;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ B9D8704927BFF97A00775F31 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDF";
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ SUPPORTS_MACCATALYST = NO;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ B9D8704B27BFF97A00775F31 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ GENERATE_INFOPLIST_FILE = YES;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDFTests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ B9D8704C27BFF97A00775F31 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NQCRZ7VG59;
+ GENERATE_INFOPLIST_FILE = YES;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.connorbell.AR-SDFTests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ B9D8702D27BFF97900775F31 /* Build configuration list for PBXProject "AR-SDF" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B9D8704527BFF97A00775F31 /* Debug */,
+ B9D8704627BFF97A00775F31 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B9D8704727BFF97A00775F31 /* Build configuration list for PBXNativeTarget "AR-SDF" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B9D8704827BFF97A00775F31 /* Debug */,
+ B9D8704927BFF97A00775F31 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ B9D8704A27BFF97A00775F31 /* Build configuration list for PBXNativeTarget "AR-SDFTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B9D8704B27BFF97A00775F31 /* Debug */,
+ B9D8704C27BFF97A00775F31 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = B9D8702A27BFF97900775F31 /* Project object */;
+}
A => AR-SDF/AR-SDF.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
@@ 1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:">
+ </FileRef>
+</Workspace>
A => AR-SDF/AR-SDF.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
@@ 1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IDEDidComputeMac32BitWarning</key>
+ <true/>
+</dict>
+</plist>
A => AR-SDF/AR-SDF.xcodeproj/project.xcworkspace/xcuserdata/connorbell.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
A => AR-SDF/AR-SDF.xcodeproj/xcuserdata/connorbell.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
@@ 1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>SchemeUserState</key>
+ <dict>
+ <key>AR-SDF.xcscheme_^#shared#^_</key>
+ <dict>
+ <key>orderHint</key>
+ <integer>1</integer>
+ </dict>
+ </dict>
+</dict>
+</plist>
A => AR-SDF/AR-SDF/ARManager.swift +135 -0
@@ 1,135 @@
+//
+// ARManager.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-14.
+//
+
+import Foundation
+import ARKit
+import simd
+import CoreVideo
+
+protocol ARManagerDelegate {
+ func ARManagerDidReadyFrame(arData: ARData)
+}
+
+public class ARManager: NSObject {
+
+ var delegate: ARManagerDelegate?
+ var rendererDelegate: RendererDelegate?
+
+ public var resolution = CGSize() {
+ didSet {
+ allocTextures(size: resolution)
+ }
+ }
+
+ private var anchor: ARAnchor?
+ private let arSession: ARSession
+ private var arData = ARData()
+ private var yTexture: MTLTexture?
+ private var cbCrTexture: MTLTexture?
+
+ private var processingCenterPixels = true
+
+ private var YCyCbPass: ComputePass
+ private var lastRaycastTransform = simd_float4x4()
+
+ init(resolution: CGSize) {
+ arSession = ARSession()
+
+ self.resolution = resolution
+ YCyCbPass = ComputePass(kernelName: "convertYCbCrToRGBA",
+ linkedFunctionNames: [],
+ resolution: resolution)
+ super.init()
+ allocTextures(size: resolution)
+ arSession.delegate = self
+ }
+
+ func startAR() {
+ guard ARWorldTrackingConfiguration.supportsFrameSemantics([.sceneDepth, .smoothedSceneDepth]) else { return }
+
+ let config = ARWorldTrackingConfiguration()
+ config.isLightEstimationEnabled = true
+ config.planeDetection = [.horizontal]
+ config.frameSemantics = [.sceneDepth, .smoothedSceneDepth]
+ arSession.run(config)
+ }
+
+ func allocTextures(size: CGSize) {
+ arData.rgbTexture = MetalManager.shared.allocTexture(pixelFormat: .rgba32Float,
+ width: Int(size.width),
+ height: Int(size.height),
+ usage: [.shaderRead, .shaderWrite])
+ YCyCbPass = ComputePass(kernelName: "convertYCbCrToRGBA",
+ linkedFunctionNames: [],
+ resolution: size)
+ }
+}
+
+extension ARManager: ARSessionDelegate {
+
+ public func session(_ session: ARSession, didUpdate frame: ARFrame) {
+
+ // guard let sceneDepth = frame.sceneDepth else { return }
+ guard let rendererDelegate = rendererDelegate else { return }
+
+ if let smoothedSceneDepth = frame.smoothedSceneDepth {
+ arData.depthSmoothTexture = MetalManager.shared.createTexture(from: smoothedSceneDepth.depthMap,
+ format: .r32Float,
+ planeIndex: 0)
+ }
+
+ createRGBTextureFromYCyCb(frame: frame, from: frame.capturedImage, dest: arData.rgbTexture)
+
+ var orientation = rendererDelegate.rendererDidRequestOrientation()
+
+ if orientation == .landscapeLeft {
+ orientation = .landscapeRight
+ } else if orientation == .landscapeRight {
+ orientation = .landscapeLeft
+ }
+
+ arData.frame = frame
+ arData.intrinsics = frame.camera.intrinsics
+ arData.cameraResolution = frame.camera.imageResolution
+ arData.projectionMatrix = frame.camera.projectionMatrix(for: orientation, viewportSize: self.resolution, zNear: 0.001, zFar: 1000.0)
+ arData.camera = frame.camera.transform
+ arData.viewMatrix = frame.camera.viewMatrix(for: orientation)
+ arData.lightIntensity = Float(frame.lightEstimate!.ambientIntensity)
+ arData.lightTemperature = Float(frame.lightEstimate!.ambientColorTemperature)
+
+ delegate?.ARManagerDidReadyFrame(arData: arData)
+ }
+
+ func addAnchor() {
+ let anchor = ARAnchor(transform: lastRaycastTransform)
+ arSession.add(anchor: anchor)
+ self.anchor = anchor
+ }
+}
+
+// - Textures
+extension ARManager {
+
+ func createRGBTextureFromYCyCb(frame: ARFrame, from: CVPixelBuffer, dest: MTLTexture?) {
+ yTexture = MetalManager.shared.createTexture(from: from, format: .r8Unorm, planeIndex: 0)
+ cbCrTexture = MetalManager.shared.createTexture(from: from, format: .rg8Unorm, planeIndex: 1)
+ let textureUniform = TextureUniform(texture: dest!, index: 2)
+
+ YCyCbPass.dispatch(drawable: nil, outTexture: textureUniform) { encoder in
+ encoder.setTexture(self.yTexture, index: 0)
+ encoder.setTexture(self.cbCrTexture, index: 1)
+ encoder.setTexture(self.arData.depthSmoothTexture, index: 3)
+ if let delegate = self.rendererDelegate {
+ var interfaceOrientation = delegate.rendererDidRequestOrientation().intValue
+ encoder.setBytes(&interfaceOrientation, length: MemoryLayout<Int>.size, index: 0)
+ }
+
+ } completionBlock: { _ in
+
+ }
+ }
+}
A => AR-SDF/AR-SDF/ARSDFView.swift +102 -0
@@ 1,102 @@
+//
+// ARSDFView.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2022-02-16.
+//
+
+import ARKit
+import Foundation
+import UIKit
+
+public class ARSDFView: UIView {
+
+ /// Access the last known AR Data
+ public var lastARData: ARData?
+
+ public var arManager: ARManager?
+ public var conemarcher: Conemarcher?
+ public var metalView: MetalView?
+
+ /// Update this to render a distance field (class must have already called start() with the assigned distance field included.
+ public var activeDistanceField: DistanceField?
+
+ private var lastKnownOrientation: UIInterfaceOrientation = .portrait
+
+ /// Available distance fields are stored as an array in order for the function table creation
+ private var distanceFields: [DistanceField] = []
+
+ private var startTime = Double(0.0)
+ private var time = Double(0.0)
+
+ public override init(frame: CGRect) {
+ super.init(frame: frame)
+ self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ }
+
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+ }
+
+ /// Begin rendering distance fields. The first one will be by default. Any distance fields intended to render should be passed as well in order to create the function table.
+ public func start(distanceFields: [DistanceField]) {
+ lastKnownOrientation = lastKnownOrientation.interfaceOrientationFromCurrentDevice
+
+ self.startTime = CFAbsoluteTimeGetCurrent()
+ self.distanceFields = distanceFields
+ self.activeDistanceField = distanceFields.first
+
+ self.metalView = MetalView(frame: self.frame, device: MetalManager.shared.metalDevice)
+
+ self.addSubview(metalView!)
+
+ conemarcher = Conemarcher(resolution: self.bounds.size,
+ distanceFields: distanceFields)
+
+ conemarcher?.rendererDelegate = self
+
+ arManager = ARManager(resolution: self.bounds.size)
+ metalView?.rendererDelegate = self
+ arManager?.rendererDelegate = self
+ arManager?.delegate = self
+
+ arManager?.startAR()
+ }
+
+ public func updateResolution(resolution: CGSize) {
+ conemarcher?.fullscreenResolution = resolution
+ metalView?.resolution = resolution
+ arManager?.resolution = resolution
+ }
+}
+
+extension ARSDFView: ARManagerDelegate {
+ func ARManagerDidReadyFrame(arData: ARData) {
+ lastARData = arData
+ lastKnownOrientation = lastKnownOrientation.interfaceOrientationFromCurrentDevice
+
+ // Update Time
+ self.time = CFAbsoluteTimeGetCurrent() - startTime
+
+ // Perform conemarch render with current distance field
+ guard let distanceField = activeDistanceField else { return }
+ let distanceFieldIndex = distanceFields.firstIndex { $0 === distanceField }
+
+ guard let conemarchRender = conemarcher?.step(data: arData,
+ field: distanceField,
+ functionIndex: distanceFieldIndex!) else { return }
+
+ // Input result to metal view for post processing
+ metalView?.blit(conemarchRender: conemarchRender)
+ }
+}
+
+extension ARSDFView: RendererDelegate {
+ func rendererDidRequestOrientation() -> UIInterfaceOrientation {
+ return lastKnownOrientation
+ }
+
+ func rendererDidRequestTime() -> Double {
+ return time
+ }
+}
A => AR-SDF/AR-SDF/AR_SDF.docc/AR_SDF.md +13 -0
@@ 1,13 @@
+# ``AR_SDF``
+
+<!--@START_MENU_TOKEN@-->Summary<!--@END_MENU_TOKEN@-->
+
+## Overview
+
+<!--@START_MENU_TOKEN@-->Text<!--@END_MENU_TOKEN@-->
+
+## Topics
+
+### <!--@START_MENU_TOKEN@-->Group<!--@END_MENU_TOKEN@-->
+
+- <!--@START_MENU_TOKEN@-->``Symbol``<!--@END_MENU_TOKEN@--><
\ No newline at end of file
A => AR-SDF/AR-SDF/AR_SDF.h +18 -0
@@ 1,18 @@
+//
+// AR_SDF.h
+// AR-SDF
+//
+// Created by Connor Bell on 2022-02-18.
+//
+
+#import <Foundation/Foundation.h>
+
+//! Project version number for AR_SDF.
+FOUNDATION_EXPORT double AR_SDFVersionNumber;
+
+//! Project version string for AR_SDF.
+FOUNDATION_EXPORT const unsigned char AR_SDFVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import <AR_SDF/PublicHeader.h>
+
+
A => AR-SDF/AR-SDF/ComputePass.swift +141 -0
@@ 1,141 @@
+//
+// ComputePass.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-20.
+//
+
+import CoreVideo
+import Metal
+import MetalKit
+
+/// Compute pass encapsulates a Metal compute kernel
+class ComputePass {
+
+ /// Pipeline state for compute kernel
+ let pipelineState: MTLComputePipelineState
+
+ /// The metal function name to execute
+ let kernelName: String
+
+ /// Threadgroup information
+ var threadsPerThreadGroup = MTLSize()
+ var threadsPerGrid = MTLSize()
+
+ /// Resolution of the expected render texture. Setting updates threadgroups
+ var resolution: CGSize {
+ didSet {
+ updateThreadgroups()
+ }
+ }
+
+ /// Function pointers and table to reference functions utilized by kernel
+ var linkedPostFunctions = MTLLinkedFunctions()
+ var visibleFunctionTable: MTLVisibleFunctionTable?
+ var visibleFunctionTableIndex: Int
+
+ /// Updated each pass to provide performance info
+ var lastExecutionTime: CFTimeInterval = 0.0
+ var executionCompletionBlock: (() -> Void)?
+
+ init(kernelName: String, linkedFunctionNames: [String], resolution: CGSize, visibleFunctionTableIndex: Int = 0) {
+ self.kernelName = kernelName
+ self.resolution = resolution
+ self.visibleFunctionTableIndex = visibleFunctionTableIndex
+
+ // Create linked functions
+ var functions: [MTLFunction] = []
+
+ for functionName in linkedFunctionNames {
+ if let postFunction = MetalManager.shared.createLinkedFunction(name: functionName, options: []) {
+ functions.append(postFunction)
+ }
+ }
+ linkedPostFunctions.functions = functions
+
+ // Create pipeline state with linked functions
+ self.pipelineState = MetalManager.shared.createComputePipelineState(name: kernelName, linkedFunctions: linkedPostFunctions)!
+
+ // Build virtual function table from the pipeline's function handles
+ let vTableDescriptor = MTLVisibleFunctionTableDescriptor()
+ vTableDescriptor.functionCount = linkedPostFunctions.functions!.count
+
+ let vTable = pipelineState.makeVisibleFunctionTable(descriptor: vTableDescriptor)
+ var index = 0
+
+ for postFxFunction in linkedPostFunctions.functions! {
+ let functionHandle = pipelineState.functionHandle(function: postFxFunction)
+ vTable?.setFunction(functionHandle, index: index)
+ index+=1
+ }
+
+ self.visibleFunctionTable = vTable
+
+ updateThreadgroups()
+ }
+
+ /// Schedules the task to GPU and output to either the drawable or texture.
+ func dispatch(drawable: CAMetalDrawable?,
+ outTexture: TextureUniform?,
+ waitUntilCompleted: Bool = false,
+ updateUniformsBlock: ((MTLComputeCommandEncoder) -> Void)?,
+ completionBlock: ((MTLTexture?) -> Void)?) {
+
+ guard let commandBuffer = MetalManager.shared.commandQueue.makeCommandBuffer(),
+ let computeCommandEncoder = commandBuffer.makeComputeCommandEncoder() else { return }
+
+ computeCommandEncoder.setComputePipelineState(pipelineState)
+
+ if let outTexture = outTexture {
+ computeCommandEncoder.setTextureUniform(uniform: outTexture)
+ }
+
+ computeCommandEncoder.setVisibleFunctionTable(visibleFunctionTable, bufferIndex: visibleFunctionTableIndex)
+
+ if let uniformsBlock = updateUniformsBlock {
+ uniformsBlock(computeCommandEncoder)
+ }
+
+ computeCommandEncoder.dispatchThreads(threadsPerGrid, threadsPerThreadgroup: threadsPerThreadGroup)
+ computeCommandEncoder.endEncoding()
+
+ // Add completion handler to update the execution time
+ commandBuffer.addCompletedHandler { buffer in
+ self.lastExecutionTime = buffer.gpuEndTime - buffer.gpuStartTime
+ if let completionBlock = self.executionCompletionBlock {
+ completionBlock()
+ }
+ }
+
+ if let drawable = drawable {
+ commandBuffer.present(drawable)
+ }
+
+ commandBuffer.commit()
+
+ if waitUntilCompleted {
+ commandBuffer.waitUntilCompleted()
+ }
+
+ if let completionBlock = completionBlock {
+ if let drawable = drawable {
+ completionBlock(drawable.texture)
+ } else {
+ completionBlock(outTexture?.texture)
+ }
+ }
+ }
+
+ func updateThreadgroups() {
+ let w = pipelineState.threadExecutionWidth
+ let h = pipelineState.maxTotalThreadsPerThreadgroup / w
+ self.threadsPerThreadGroup = MTLSize(width: w, height: h, depth: 1)
+ self.threadsPerGrid = MTLSize(width: Int(resolution.width), height: Int(resolution.height), depth: 1)
+ }
+}
+
+extension MTLComputeCommandEncoder {
+ func setTextureUniform(uniform: TextureUniform) {
+ self.setTexture(uniform.texture, index: uniform.index)
+ }
+}
A => AR-SDF/AR-SDF/Conemarcher.swift +232 -0
@@ 1,232 @@
+//
+// Conemarcher.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-14.
+//
+
+import Foundation
+import Metal
+import simd
+import CoreVideo
+
+// This data struct gets passed to the conemarch kernel and needs to match the struct in Conemarcher.metal
+struct ConemarchParameters {
+ var maxDist = simd_float1(0.0)
+ var minDist = simd_float1(0.0)
+ var coneWidth = simd_float1(0.0)
+ var inverseProjectionMatrix = simd_float4x4(0.0)
+ var inverseViewMatrix = simd_float4x4(0.0)
+ var viewMatrix = simd_float4x4(0.0)
+ var projectionMatrix = simd_float4x4(0.0)
+ var camera = simd_float4x4(0.0)
+ var computeColor = simd_int1(0)
+ var time = Float(CFAbsoluteTimeGetCurrent())
+ var lightTemperature = simd_float1(0.0)
+ var lightIntensity = simd_float1(0.0)
+}
+
+public class Conemarcher {
+
+ /// Number of times resulting depth data is propigated to a higher resolution.
+ let passes = 9
+
+ /// Width of starting resolution
+ var startWidth = 3
+
+ /// Height of starting resolution
+ var startHeight = 2
+
+ /// Multiplier for the cone width
+ let coneWidthScale = 2.0
+
+ /// Max distance to cast rays before exiting traversal
+ let maxDist = 50.0
+
+ /// Min distance to surface for a ray
+ let minDist = 0.001
+
+ /// Step counts for each pass. If there's more passes than step counts, the step count is the last value.
+ var stepCounts = [50, 40, 35, 30, 25, 20, 15, 10]
+
+ var rendererDelegate: RendererDelegate?
+
+ /// Callback which invokes each
+ var executionTimeUpdated: ((CFTimeInterval) -> Void)?
+
+ /// Conemarch parameter buffer pointer to update GPU memory
+ private let bufferPointer: UnsafeMutablePointer<ConemarchParameters>
+
+ /// Width of the cones for each pass
+ private var coneWidths: [Float] = []
+
+ /// Compute passes for each resolution
+ private var computePasses: [ComputePass] = []
+
+ /// Persistent parameter buffer
+ private let conemarchParamsBuffer: MTLBuffer
+
+ /// Parameter struct to be encoded into buffer
+ private var conemarchParameters = ConemarchParameters()
+
+ /// The names of the distance field functions the function table will be composed of
+ public var linkedFunctionNames: [String] = []
+
+ /// Render textures for the outputs of each pass
+ private var textureUniforms: [TextureUniform] = []
+
+ /// Updating resets starting texture size based on orientation
+ var fullscreenResolution: CGSize {
+ didSet {
+ if fullscreenResolution.height > fullscreenResolution.width {
+ startWidth = 3
+ startHeight = 2
+ } else {
+ startWidth = 2
+ startHeight = 3
+ }
+ allocTexturesAndPasses()
+ computeConeWidths()
+ }
+ }
+
+ init(resolution: CGSize, distanceFields: [DistanceField]) {
+ for distanceField in distanceFields {
+ linkedFunctionNames.append(distanceField.kernelName)
+ }
+
+ self.fullscreenResolution = resolution
+
+ conemarchParameters.maxDist = Float(maxDist)
+ conemarchParameters.minDist = Float(minDist)
+
+ conemarchParamsBuffer = MetalManager.shared.metalDevice.makeBuffer(bytes: &self.conemarchParameters,
+ length: MemoryLayout<ConemarchParameters>.stride,
+ options:[])!
+
+ bufferPointer = conemarchParamsBuffer.contents().bindMemory(to: ConemarchParameters.self, capacity: 1)
+
+ allocTexturesAndPasses()
+ computeConeWidths()
+ registerExecutionTimeCallbacks()
+ }
+
+ /// Returns a texture with the rendered SDF composed with the AR Data
+ func step(data: ARData, field: DistanceField, functionIndex: Int) -> MTLTexture? {
+
+ guard let time = rendererDelegate?.rendererDidRequestTime() else { return nil }
+
+ // Update buffer with relevant parameters
+ bufferPointer.pointee.time = Float(time)
+ bufferPointer.pointee.camera = data.camera
+ bufferPointer.pointee.inverseProjectionMatrix = simd_inverse(data.projectionMatrix)
+ bufferPointer.pointee.inverseViewMatrix = simd_inverse(data.viewMatrix)
+ bufferPointer.pointee.computeColor = 0
+ bufferPointer.pointee.lightTemperature = data.lightTemperature
+ bufferPointer.pointee.lightIntensity = data.lightIntensity
+ bufferPointer.pointee.viewMatrix = data.viewMatrix
+ bufferPointer.pointee.projectionMatrix = data.projectionMatrix
+
+ // Progressively render each pass with the last pass as input
+ for i in 0...passes {
+
+ bufferPointer.pointee.coneWidth = self.coneWidths[i]
+
+ computePasses[i].dispatch(drawable: nil,
+ outTexture: textureUniforms[i],
+ waitUntilCompleted: true) { commandEncoder in
+
+ commandEncoder.setTexture(data.rgbTexture, index: 2)
+
+ var distFunctionIndex = functionIndex
+ commandEncoder.setBytes(&distFunctionIndex, length: MemoryLayout<Int>.stride, index: 3)
+
+ field.encodeUniforms(encoder: commandEncoder)
+
+ // Set previous depth texture
+ if i > 0 {
+ commandEncoder.setTexture(self.textureUniforms[i-1].texture, index: 0)
+ }
+
+ // Compute color if final pass
+ if i == self.passes {
+ self.bufferPointer.pointee.computeColor = 1
+ }
+
+ commandEncoder.setBuffer(self.conemarchParamsBuffer, offset: 0, index: 0)
+
+ } completionBlock: { _ in
+
+ }
+ }
+
+ return textureUniforms[passes].texture
+ }
+
+ func registerExecutionTimeCallbacks() {
+ var completedPasses = 0
+ let executionCompletionBlock: () -> Void = {
+ completedPasses += 1
+
+ if completedPasses == self.passes {
+ var totalExecutionTime = 0.0
+ for pass in self.computePasses {
+ totalExecutionTime += pass.lastExecutionTime
+ }
+ if let completionBlock = self.executionTimeUpdated {
+ completionBlock(totalExecutionTime)
+ }
+ }
+ }
+
+ for pass in computePasses {
+ pass.executionCompletionBlock = executionCompletionBlock
+ }
+ }
+}
+
+extension Conemarcher {
+ func allocTexturesAndPasses() {
+
+ var resolution = (startWidth, startHeight)
+ textureUniforms = []
+ computePasses = []
+
+ for _ in 0...passes {
+ let texture = MetalManager.shared.allocTexture(pixelFormat: .rgba32Float,
+ width: resolution.0,
+ height: resolution.1,
+ usage: [.shaderRead, .shaderWrite])
+ let uniform = TextureUniform(texture: texture, index: 1)
+ textureUniforms.append(uniform)
+
+ let pass = ComputePass(kernelName: "conemarchKernel",
+ linkedFunctionNames: linkedFunctionNames,
+ resolution: CGSize(width: resolution.0, height: resolution.1),
+ visibleFunctionTableIndex: 2)
+
+ computePasses.append(pass)
+ resolution.0 *= 2
+ resolution.1 *= 2
+ }
+ }
+
+ func computeConeWidths() {
+
+ coneWidths = []
+
+ for i in 0...passes {
+ let texel = CGSize(width: CGFloat(1.0) / CGFloat(textureUniforms[i].texture.width),
+ height: CGFloat(1.0) / CGFloat(textureUniforms[i].texture.height))
+
+ let x = simd_float3(simd_float1(texel.width), 0.0, 0.0)
+ let y = simd_float3(0.0, simd_float1(texel.height), 0.0)
+ let z = simd_float3(0.0, 0.0, -1.0)
+ let basis = normalize(simd_float3(x + y + z))
+ let theta = acos(simd_dot(simd_float3(0.0, 0.0, -1.0), basis));
+ let cw = tan(theta);
+
+ coneWidths.append(cw * Float(coneWidthScale))
+ }
+ }
+}
A => AR-SDF/AR-SDF/Extensions/CVPixelBuffer+MTLTexture.swift +23 -0
@@ 1,23 @@
+//
+// CVPixelBuffer+MTLTexture.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-16.
+//
+
+import CoreVideo
+
+extension CVPixelBuffer {
+
+ func texture(withFormat pixelFormat: MTLPixelFormat, planeIndex: Int, addToCache cache: CVMetalTextureCache) -> MTLTexture? {
+
+ let width = CVPixelBufferGetWidthOfPlane(self, planeIndex)
+ let height = CVPixelBufferGetHeightOfPlane(self, planeIndex)
+
+ var cvtexture: CVMetalTexture?
+ CVMetalTextureCacheCreateTextureFromImage(nil, cache, self, nil, pixelFormat, width, height, planeIndex, &cvtexture)
+ let texture = CVMetalTextureGetTexture(cvtexture!)
+
+ return texture
+ }
+}
A => AR-SDF/AR-SDF/Extensions/Float4x4+Extensions.swift +54 -0
@@ 1,54 @@
+//
+// simd+ext.swift
+//
+// Created by Kaz Yoshikawa on 11/6/15.
+//
+// https://gist.github.com/codelynx/908fd30c93e40ea6408b
+
+import Foundation
+import simd
+import GLKit
+
+extension simd_float4x4 {
+
+ static func makeScale(x: Float, _ y: Float, _ z: Float) -> simd_float4x4 {
+ return unsafeBitCast(GLKMatrix4MakeScale(x, y, z), to: simd_float4x4.self)
+ }
+
+ static func makeRotate(radians: Float, _ x: Float, _ y: Float, _ z: Float) -> simd_float4x4 {
+ return unsafeBitCast(GLKMatrix4MakeRotation(radians, x, y, z), to: simd_float4x4.self)
+ }
+
+ static func makeTranslation(x: Float, _ y: Float, _ z: Float) -> simd_float4x4 {
+ return unsafeBitCast(GLKMatrix4MakeTranslation(x, y, z), to: simd_float4x4.self)
+ }
+
+ static func makePerspective(fovyRadians: Float, _ aspect: Float, _ nearZ: Float, _ farZ: Float) -> simd_float4x4 {
+ return unsafeBitCast(GLKMatrix4MakePerspective(fovyRadians, aspect, nearZ, farZ), to: simd_float4x4.self)
+ }
+
+ static func makeFrustum(left: Float, _ right: Float, _ bottom: Float, _ top: Float, _ nearZ: Float, _ farZ: Float) -> simd_float4x4 {
+ return unsafeBitCast(GLKMatrix4MakeFrustum(left, right, bottom, top, nearZ, farZ), to: simd_float4x4.self)
+ }
+
+ static func makeOrtho(left: Float, _ right: Float, _ bottom: Float, _ top: Float, _ nearZ: Float, _ farZ: Float) -> simd_float4x4 {
+ return unsafeBitCast(GLKMatrix4MakeOrtho(left, right, bottom, top, nearZ, farZ), to: simd_float4x4.self)
+ }
+
+ static func makeLookAt(eyeX: Float, _ eyeY: Float, _ eyeZ: Float, _ centerX: Float, _ centerY: Float, _ centerZ: Float, _ upX: Float, _ upY: Float, _ upZ: Float) -> simd_float4x4 {
+ return unsafeBitCast(GLKMatrix4MakeLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ), to: simd_float4x4.self)
+ }
+
+
+ func scale(x: Float, y: Float, z: Float) -> simd_float4x4 {
+ return self * simd_float4x4.makeScale(x: x, y, z)
+ }
+
+ func rotate(radians: Float, _ x: Float, _ y: Float, _ z: Float) -> simd_float4x4 {
+ return self * simd_float4x4.makeRotate(radians: radians, x, y, z)
+ }
+
+ func translate(x: Float, _ y: Float, _ z: Float) -> simd_float4x4 {
+ return self * simd_float4x4.makeTranslation(x: x, y, z)
+ }
+}
A => AR-SDF/AR-SDF/Extensions/MTLTexture+Extensions.swift +22 -0
@@ 1,22 @@
+//
+// MTLTexture+Extensions.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-10.
+//
+
+import Metal
+
+// from https://stackoverflow.com/questions/41577800/why-cant-i-read-those-mtltexture-pixels
+extension MTLTexture {
+ func getPixels<T> (_ region: MTLRegion? = nil, mipmapLevel: Int = 0) -> UnsafeMutablePointer<T> {
+ let fromRegion = region ?? MTLRegionMake2D(0, 0, self.width, self.height)
+ let width = fromRegion.size.width
+ let height = fromRegion.size.height
+ let bytesPerRow = MemoryLayout<T>.stride * width
+ let data = UnsafeMutablePointer<T>.allocate(capacity: bytesPerRow * height)
+
+ self.getBytes(data, bytesPerRow: bytesPerRow, from: fromRegion, mipmapLevel: mipmapLevel)
+ return data
+ }
+}
A => AR-SDF/AR-SDF/Extensions/UIInterfaceOrientation+Extensions.swift +46 -0
@@ 1,46 @@
+//
+// UIInterfaceOrientation+Extensions.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-25.
+//
+
+import UIKit
+
+extension UIInterfaceOrientation {
+
+ public var interfaceOrientationFromCurrentDevice: UIInterfaceOrientation {
+ switch UIDevice.current.orientation {
+ case .landscapeLeft:
+ return UIInterfaceOrientation.landscapeLeft
+ case .landscapeRight:
+ return UIInterfaceOrientation.landscapeRight
+ case .portrait:
+ return UIInterfaceOrientation.portrait
+ case .portraitUpsideDown:
+ return UIInterfaceOrientation.portraitUpsideDown
+ default:
+ return self
+ }
+ }
+
+ public var description: String {
+ switch self {
+ case .landscapeLeft: return "landscapeLeft"
+ case .landscapeRight: return "landscapeRight"
+ case .portrait: return "portrait"
+ case .portraitUpsideDown: return "portraitUpsideDown"
+ case .unknown: return "unknown"
+ }
+ }
+
+ public var intValue: Int {
+ switch self {
+ case .landscapeLeft: return 0
+ case .landscapeRight: return 2
+ case .portrait: return 1
+ case .portraitUpsideDown: return 3
+ case .unknown: return 0
+ }
+ }
+}
A => AR-SDF/AR-SDF/MetalManager.swift +129 -0
@@ 1,129 @@
+//
+// MetalProvider.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-15.
+//
+
+import Foundation
+import Metal
+import CoreVideo
+import MetalKit
+import AVFoundation
+
+final class MetalManager {
+
+ static let shared = MetalManager()
+
+ var metalDevice: MTLDevice
+ var commandQueue: MTLCommandQueue
+ var functionLibrary: MTLLibrary
+
+ var textureLoader: MTKTextureLoader?
+ private var textureCache: CVMetalTextureCache?
+ private var pipelineStateCache: [String: MTLComputePipelineState] = [:]
+
+ init() {
+
+ metalDevice = MTLCreateSystemDefaultDevice()!
+
+ let frameworkBundle = Bundle(for: MetalManager.self)
+
+ // Thanks Warren Moore!
+ guard let defaultLibrary = try? metalDevice.makeDefaultLibrary(bundle: frameworkBundle) else {
+ fatalError("Could not load default library from specified bundle")
+ }
+
+ commandQueue = metalDevice.makeCommandQueue()!
+
+ functionLibrary = defaultLibrary
+ textureLoader = MTKTextureLoader(device: metalDevice)
+
+ createTextureCache()
+ }
+
+ /// Creates a pipeline state, caching the state by name.
+ func createComputePipelineState(name: String, linkedFunctions: MTLLinkedFunctions?) -> MTLComputePipelineState? {
+
+ if let cachedState = pipelineStateCache[name] {
+ return cachedState
+ }
+
+ do {
+ let descriptor = MTLFunctionDescriptor()
+ descriptor.name = name
+
+ let function = try functionLibrary.makeFunction(descriptor: descriptor)
+
+ let computeDescriptor = MTLComputePipelineDescriptor()
+ computeDescriptor.computeFunction = function
+ if let linkedFunctions = linkedFunctions {
+ computeDescriptor.linkedFunctions = linkedFunctions
+ }
+ do {
+ let state = try metalDevice.makeComputePipelineState(descriptor: computeDescriptor, options: [], reflection: nil)
+ pipelineStateCache[name] = state
+ return state
+ }
+ catch {
+ print(error)
+ return nil
+ }
+
+ } catch {
+ print(error)
+ return nil
+ }
+ }
+
+ func createLinkedFunction(name: String, options: MTLFunctionOptions) -> MTLFunction? {
+
+ let descriptor = MTLFunctionDescriptor()
+ descriptor.name = name
+ descriptor.options = options
+
+ do {
+ return try functionLibrary.makeFunction(descriptor: descriptor)
+ } catch {
+
+ }
+ return nil
+ }
+
+ func createTextureCache() {
+ var textCache: CVMetalTextureCache?
+ if CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self.metalDevice, nil, &textCache) != kCVReturnSuccess {
+ print("Unable to allocate texture cache")
+ }
+ else {
+ guard let textureCache = textCache else { return }
+ self.textureCache = textureCache
+ }
+ }
+
+ func allocTexture(pixelFormat: MTLPixelFormat, width: Int, height: Int, usage: MTLTextureUsage) -> MTLTexture {
+ let descriptor: MTLTextureDescriptor = MTLTextureDescriptor()
+ descriptor.pixelFormat = pixelFormat
+ descriptor.width = width
+ descriptor.height = height
+ descriptor.usage = usage
+ let resTexture = metalDevice.makeTexture(descriptor: descriptor)
+ return resTexture!
+ }
+
+ func createTexture(from: CVPixelBuffer, format: MTLPixelFormat, planeIndex: Int) -> MTLTexture {
+ return from.texture(withFormat: format, planeIndex: planeIndex, addToCache: textureCache!)!
+ }
+
+ func createTexture(fileName: String) -> MTLTexture? {
+ let imagePath = Bundle(for: MetalManager.self).path(forResource: fileName, ofType: "png")!
+ let image = UIImage(contentsOfFile: imagePath)!
+
+ do {
+ return (try textureLoader?.newTexture(cgImage: image.cgImage!,
+ options: [MTKTextureLoader.Option.SRGB : NSNumber(value: false)]))!
+ } catch {
+ return nil
+ }
+ }
+}
A => AR-SDF/AR-SDF/MetalView.swift +112 -0
@@ 1,112 @@
+//
+// MetalView.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-14.
+//
+
+import Foundation
+import Metal
+import MetalKit
+import MetalPerformanceShaders
+import ARKit
+
+public class MetalView: MTKView {
+
+ /// Used to obtain orientation and time
+ var rendererDelegate: RendererDelegate?
+
+ /// The input texture to be processed. Use "blit" function to render
+ private var inputConemarchResult: MTLTexture?
+
+ /// The compute pass to apply the post effect
+ private var postFxPass: ComputePass?
+
+ /// Used as render target between post-fx and lighting passes
+ private var renderTexture: TextureUniform?
+
+ var resolution: CGSize {
+ didSet {
+ allocTexturesAndPasses()
+ }
+ }
+
+ public override init(frame frameRect: CGRect, device: MTLDevice?) {
+ self.resolution = frameRect.size
+ super.init(frame: frameRect, device: device)
+ self.backgroundColor = .systemBlue
+
+ self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+
+ setup()
+ }
+
+ required init(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ public override func layoutSubviews() {
+ super.layoutSubviews()
+ self.drawableSize = CGSize(width: frame.size.width, height: frame.size.height)
+ }
+
+ func setup() {
+
+ postFxPass = ComputePass(kernelName: "PostFxPass",
+ linkedFunctionNames: [],
+ resolution: resolution)
+
+ let rt = MetalManager.shared.allocTexture(pixelFormat: .rgba32Float,
+ width: Int(resolution.width),
+ height: Int(resolution.height),
+ usage: [.shaderRead, .shaderWrite])
+
+ renderTexture = TextureUniform(texture: rt, index: 4)
+
+ self.framebufferOnly = false
+ }
+
+ public override func draw(_ rect: CGRect) {
+ if rect.width > 0 && rect.height > 0 {
+ self.render()
+ }
+ }
+
+ private func render() {
+ guard let drawable: CAMetalDrawable = self.currentDrawable,
+ var time = rendererDelegate?.rendererDidRequestTime() else { return }
+
+ let drawableTextureUniform = TextureUniform(texture: drawable.texture, index: 1)
+
+ postFxPass?.dispatch(drawable: drawable,
+ outTexture: drawableTextureUniform,
+ updateUniformsBlock: { [self]
+
+ computeCommandEncoder in
+
+ computeCommandEncoder.setTexture(self.inputConemarchResult, index: 0)
+ computeCommandEncoder.setBytes(&time, length: MemoryLayout<Float>.size, index: 1)
+
+ }, completionBlock: { texture in
+
+ })
+ }
+
+ func blit(conemarchRender: MTLTexture?) {
+ self.inputConemarchResult = conemarchRender
+ setNeedsDisplay()
+ }
+
+ func allocTexturesAndPasses() {
+
+ postFxPass?.resolution = resolution
+
+ let rt = MetalManager.shared.allocTexture(pixelFormat: .rgba32Float,
+ width: Int(resolution.width),
+ height: Int(resolution.height),
+ usage: [.shaderRead, .shaderWrite])
+
+ renderTexture = TextureUniform(texture: rt, index: 4)
+ }
+}
+
A => AR-SDF/AR-SDF/Models/ARData.swift +40 -0
@@ 1,40 @@
+//
+// ARData.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2022-02-17.
+//
+
+import CoreGraphics
+import Metal
+import simd
+import ARKit
+
+public class ARData {
+ var depthTexture: MTLTexture?
+ var depthSmoothTexture: MTLTexture?
+ var rgbTexture: MTLTexture?
+ var confidenceTexture: MTLTexture?
+ var confidenceSmoothTexture: MTLTexture?
+ var cameraIntrinsics = simd_float3x3()
+ var cameraResolution = CGSize()
+ var projectionMatrix = simd_float4x4()
+ var viewMatrix = simd_float4x4()
+ var intrinsics = simd_float3x3()
+ var lightTemperature = simd_float1()
+ var lightIntensity = simd_float1()
+ var distanceToRaycast = simd_float1()
+ var frame: ARFrame?
+
+ var camera = simd_float4x4()
+ var raycastPosition = simd_float3()
+
+ public func camPos() -> simd_float3 {
+ return simd_float3(camera.columns.3.x, camera.columns.3.y, camera.columns.3.z)
+ }
+ public func objectTarget() -> simd_float4x4 {
+ let forward = simd_float3(camera.columns.2.x, camera.columns.2.y, camera.columns.2.z)
+ let objectTransform = camera.translate(x: forward.x, forward.y, forward.z)
+ return objectTransform
+ }
+}
A => AR-SDF/AR-SDF/Models/DistanceField.swift +134 -0
@@ 1,134 @@
+//
+// DistanceField.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-16.
+//
+
+import CoreVideo
+import Foundation
+import Metal
+import simd
+
+public struct DistanceFieldParameters {
+ var param1 = simd_float4()
+ var param2 = simd_float4()
+ var param3 = simd_float4()
+ var param4 = simd_float4()
+
+ var transform = simd_float4x4(simd_float4(1.0, 0.0, 0.0, 0.0),
+ simd_float4(0.0, 1.0, 0.0, 0.0),
+ simd_float4(0.0, 0.0, 1.0, 0.0),
+ simd_float4(0.0, 0.0, 0.0, 1.0))
+
+ var scale = simd_float1(1.0)
+ var steps = simd_int1(25)
+ var fudge = simd_float1(1.0)
+
+ public init() {
+
+ }
+}
+
+public class DistanceField {
+
+ /// Parameters to encode in the buffer
+ public var uniforms: [Uniform] = []
+
+ /// Number of raymarch steps for the final pass
+ public var steps: Int {
+ get {
+ return Int(parameterBufferPointer.pointee.steps)
+ }
+ set(newValue) {
+ parameterBufferPointer.pointee.steps = simd_int1(newValue)
+ }
+ }
+
+ /// Transform for the distance field
+ public var transform: simd_float4x4 {
+ get {
+ return parameterBufferPointer.pointee.transform
+ }
+ set(newValue) {
+ parameterBufferPointer.pointee.transform = newValue
+ }
+ }
+
+ /// Scale of the distance field
+ public var scale: simd_float1 {
+ get {
+ return parameterBufferPointer.pointee.scale
+ }
+ set(newValue) {
+ parameterBufferPointer.pointee.scale = newValue
+ }
+ }
+
+ /// Name of the visible function
+ public var kernelName = ""
+
+ /// Reference to buffer for updating values
+ private var parameterBufferPointer: UnsafeMutablePointer<DistanceFieldParameters>
+
+ /// Parameters to encode in the buffer
+ private var parameters = DistanceFieldParameters()
+
+ /// The visible function of the distance field
+ private var distanceFieldFunction: MTLFunction?
+
+ /// Buffer to send to GPU
+ private var parameterBuffer: MTLBuffer
+
+ public init(kernelName: String, uniforms: [Uniform]) {
+
+ if uniforms.count > 4 {
+ fatalError("Distance Fields can have a maximum of 4 Float4 uniforms")
+ }
+
+ self.kernelName = kernelName
+ self.uniforms = uniforms
+
+ parameterBuffer = MetalManager.shared.metalDevice.makeBuffer(bytes: &self.parameters,
+ length: MemoryLayout<DistanceFieldParameters>.stride,
+ options: [])!
+
+ parameterBufferPointer = parameterBuffer.contents().bindMemory(to: DistanceFieldParameters.self, capacity: 1)
+
+ distanceFieldFunction = MetalManager.shared.createLinkedFunction(name: kernelName, options: [])
+ }
+
+ /// Update the uniforms pre-dispatch
+ func encodeUniforms(encoder: MTLComputeCommandEncoder) {
+ if uniforms.count > 0 {
+ uniforms[0].assignToBufferValue(val: ¶meterBufferPointer.pointee.param1)
+ }
+ if uniforms.count > 1 {
+ uniforms[1].assignToBufferValue(val: ¶meterBufferPointer.pointee.param2)
+ }
+ if uniforms.count > 2 {
+ uniforms[2].assignToBufferValue(val: ¶meterBufferPointer.pointee.param3)
+ }
+ if uniforms.count > 3 {
+ uniforms[3].assignToBufferValue(val: ¶meterBufferPointer.pointee
+ .param4)
+ }
+
+ encoder.setBuffer(parameterBuffer, offset: 0, index: 1)
+ }
+
+ /// Translate the position of the distance field
+ func translate(translation: simd_float3) {
+ parameterBufferPointer.pointee.transform = parameterBufferPointer.pointee.transform.translate(x: translation.x, translation.y, translation.z)
+ }
+
+ /// Rotate the distance field around an axis
+ func rotate(radians: Float, x: Float, y: Float, z: Float) {
+ parameterBufferPointer.pointee.transform = parameterBufferPointer.pointee.transform.rotate(radians: radians, x, y, z)
+ }
+
+ /// Scale the distance field by some delta
+ func scale(delta: simd_float1) {
+ self.parameterBufferPointer.pointee.scale = simd_clamp(self.parameterBufferPointer.pointee.scale + delta, 0.25, 2.0)
+ }
+}
A => AR-SDF/AR-SDF/Models/TextureUniform.swift +19 -0
@@ 1,19 @@
+//
+// TextureUniform.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-20.
+//
+
+import Foundation
+import Metal
+
+class TextureUniform: Uniform {
+ let texture: MTLTexture
+
+ init(texture: MTLTexture, index: Int) {
+ self.texture = texture
+ super.init(index: index, name: "", range: .zero)
+ self.index = index
+ }
+}
A => AR-SDF/AR-SDF/Models/Uniform.swift +94 -0
@@ 1,94 @@
+//
+// Uniform.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-09-15.
+//
+
+import simd
+import Metal
+import UIKit
+
+public class Uniform {
+ public var index: Int = 0
+ public var name: String = ""
+ public var range = CGSize()
+
+ init(index: Int, name: String, range: CGSize) {
+ self.index = index
+ self.name = name
+ self.range = range
+ }
+
+ func assignToBufferValue(val: inout simd_float4) {
+ // :) fatalError("Must Override")
+ }
+
+ func numValues() -> Int {
+ return 1
+ }
+}
+
+public class FloatUniform: Uniform {
+ public var currentValue: Float = 0.0
+
+ public init(name: String, range: CGSize, value: Float) {
+ super.init(index: 0, name: name, range: range)
+ currentValue = value
+ }
+
+ override func assignToBufferValue(val: inout simd_float4) {
+ val = simd_float4(currentValue, 0.0, 0.0, 0.0)
+ }
+}
+
+public class Float2Uniform: Uniform {
+ public var currentValue = simd_float2()
+
+ public init(name: String, range: CGSize, value: simd_float2) {
+ super.init(index: 0, name: name, range: range)
+ currentValue = value
+ }
+
+ override func assignToBufferValue(val: inout simd_float4) {
+ val = simd_float4(currentValue.x, currentValue.y, 0.0, 0.0)
+ }
+
+ override func numValues() -> Int {
+ return 2
+ }
+}
+
+public class Float3Uniform: Uniform {
+ public var currentValue = simd_float3()
+
+ public init(name: String, range: CGSize, value: simd_float3) {
+ super.init(index: 0, name: name, range: range)
+ currentValue = value
+ }
+
+ override func assignToBufferValue(val: inout simd_float4) {
+ val = simd_float4(currentValue.x, currentValue.y, currentValue.z, 0.0)
+ }
+
+ override func numValues() -> Int {
+ return 3
+ }
+}
+
+public class Float4Uniform: Uniform {
+ public var currentValue = simd_float4()
+
+ public init(name: String, range: CGSize, value: simd_float4) {
+ super.init(index: 0, name: name, range: range)
+ currentValue = value
+ }
+
+ override func assignToBufferValue(val: inout simd_float4) {
+ val = simd_float4(currentValue.x, currentValue.y, currentValue.z, currentValue.w)
+ }
+
+ override func numValues() -> Int {
+ return 4
+ }
+}
A => AR-SDF/AR-SDF/RendererDelegate.swift +13 -0
@@ 1,13 @@
+//
+// RenderTargetDelegate.swift
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-25.
+//
+
+import UIKit
+
+protocol RendererDelegate {
+ func rendererDidRequestOrientation() -> UIInterfaceOrientation
+ func rendererDidRequestTime() -> Double
+}
A => AR-SDF/AR-SDF/Shaders/Common.h +35 -0
@@ 1,35 @@
+//
+// Common.h
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-11-14.
+//
+
+#ifndef Common_h
+#define Common_h
+
+struct RaymarchResult {
+ float3 position;
+ float distToSurface;
+ float depth;
+};
+
+struct ScreenSpaceInfo {
+ float3 rayDir;
+ RaymarchResult raymarchResult;
+};
+
+// From https://www.shadertoy.com/view/4sc3D7
+// Valid from 1000 to 40000 K (and additionally 0 for pure full white)
+float3 colorTemperatureToRGB(const float temperature){
+ // Values from: http://blenderartists.org/forum/showthread.php?270332-OSL-Goodness&p=2268693&viewfull=1#post2268693
+ float3x3 m = (temperature <= 6500.0) ? float3x3(float3(0.0, -2902.1955373783176, -8257.7997278925690),
+ float3(0.0, 1669.5803561666639, 2575.2827530017594),
+ float3(1.0, 1.3302673723350029, 1.8993753891711275)) :
+ float3x3(float3(1745.0425298314172, 1216.6168361476490, -8257.7997278925690),
+ float3(-2666.3474220535695, -2173.1012343082230, 2575.2827530017594),
+ float3(0.55995389139931482, 0.70381203140554553, 1.8993753891711275));
+ return mix(clamp(float3(m[0] / (float3(clamp(temperature, 1000.0, 40000.0)) + m[1]) + m[2]), float3(0.0), float3(1.0)), float3(1.0), smoothstep(1000.0, 0.0, temperature));
+}
+
+#endif /* Common_h */
A => AR-SDF/AR-SDF/Shaders/Conemarcher.metal +230 -0
@@ 1,230 @@
+//
+// Conemarcher.metal
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-15.
+//
+
+#include <metal_stdlib>
+#include "DistanceFields.h"
+#include "Common.h"
+
+using namespace metal;
+
+struct ConemarchParameters {
+ float maxDist;
+ float minDist;
+ float coneWidth;
+ float4x4 inverseProjectionMatrix;
+ float4x4 inverseViewMatrix;
+ float4x4 viewMatrix;
+ float4x4 projectionMatrix;
+ float4x4 camera;
+ int computeColor;
+ float time;
+ float lightTemperature;
+ float lightIntensity;
+};
+
+float map(float3 pos,
+ float time,
+ DistanceFieldParams distParams,
+ DistanceFieldFunction distanceFieldFunction) {
+
+ float scale = distParams.scale;
+ float3 transformedPos = (distParams.transform * float4(pos, 1.0) * scale).xyz;
+
+ return distanceFieldFunction(transformedPos, time, distParams) / scale;
+}
+
+RaymarchResult conemarch(const float3 pos,
+ const float3 rayDir,
+ const float prevDist,
+ device ConemarchParameters &conemarchParams,
+ DistanceFieldParams distanceFieldParams,
+ DistanceFieldFunction distanceFieldFunction) {
+
+ RaymarchResult ray;
+ ray.position = pos;
+ ray.depth = prevDist;
+
+ for (int i = 0; i < distanceFieldParams.steps; i++) {
+
+ float3 p = pos + rayDir * ray.depth;
+ float res = map(p, conemarchParams.time, distanceFieldParams, distanceFieldFunction)*0.8;
+ float cone = max(ray.depth * conemarchParams.coneWidth, conemarchParams.minDist);
+
+ if (res < cone) {
+ break;
+ }
+
+ float sum = ray.depth + res;
+
+ if (sum > conemarchParams.maxDist) {
+ break;
+ }
+ ray.distToSurface = res;
+ ray.position = p;
+ ray.depth = sum;
+ }
+
+ return ray;
+}
+
+RaymarchResult raymarch(const float3 pos,
+ const float3 rayDir,
+ const float prevDist,
+ const float maxDist,
+ device ConemarchParameters &conemarchParams,
+ DistanceFieldParams distFieldParams,
+ DistanceFieldFunction distanceFieldFunction) {
+
+ RaymarchResult ray;
+ ray.position = pos;
+ ray.depth = prevDist;
+ float stepLength = 0.0;
+
+ for (int i = 0; i < distFieldParams.steps; i++) {
+
+ ray.position = pos + rayDir * ray.depth;
+ float newDist = map(ray.position, conemarchParams.time, distFieldParams, distanceFieldFunction) * distFieldParams.fudge;
+
+ ray.distToSurface = newDist;
+
+ if (newDist < conemarchParams.minDist) {
+ break;
+ }
+ float sum = ray.depth + stepLength;
+
+ if (sum > conemarchParams.maxDist) {
+ break;
+ }
+
+ ray.depth = sum;
+ }
+
+ return ray;
+}
+
+float3 calcNormal(float3 pos, float time, DistanceFieldParams distParams, DistanceFieldFunction distanceFieldFunction) {
+ const float3 eps = float3(0.001, 0., 0.);
+ float3 nor = float3(map(pos+eps.xyy,
+ time, distParams,
+ distanceFieldFunction) - map(pos-eps.xyy, time, distParams, distanceFieldFunction),
+ map(pos+eps.yxy,
+ time, distParams,
+ distanceFieldFunction) - map(pos-eps.yxy, time, distParams, distanceFieldFunction),
+ map(pos+eps.yyx,
+ time, distParams,
+ distanceFieldFunction) - map(pos-eps.yyx, time, distParams, distanceFieldFunction));
+ return normalize(nor);
+}
+
+float3 refractSample(float3 pos, float3 rayDir, float3 nor, float ior, float4x4 projMatrix, float4x4 viewMatrix, texture2d<float, access::sample> rgbTexture) {
+ constexpr sampler s(coord::normalized, address::mirrored_repeat, filter::linear);
+ float3 refractedDir = refract(rayDir, nor, ior);
+ float3 refractedPos = pos + normalize(refractedDir);
+ float4 clipPos = projMatrix * (viewMatrix * float4(refractedPos, 1.0));
+ float2 screenSpaceUv = saturate((clipPos.xy / clipPos.w + 1.0) * 0.5);
+ screenSpaceUv.y = 1.0 - screenSpaceUv.y;
+ return rgbTexture.sample(s, screenSpaceUv).rgb;
+}
+
+float4 color(device ConemarchParameters &conemarchParams,
+ device DistanceFieldParams &distanceFieldParams,
+ DistanceFieldFunction distanceFieldFunction,
+ float3 camPos,
+ float3 rayDir,
+ float2 uv,
+ float4 worldColor,
+ float lastDepth,
+ texture2d<float, access::sample> rgbTexture) {
+
+ // Only compute depth if not computing color
+ if (!conemarchParams.computeColor) {
+ return conemarch(camPos, rayDir, lastDepth, conemarchParams, distanceFieldParams, distanceFieldFunction).depth;
+ }
+
+ // Compute the depth
+ RaymarchResult res = raymarch(camPos, rayDir, lastDepth, worldColor.a, conemarchParams, distanceFieldParams, distanceFieldFunction);
+
+ float depth = res.depth;
+ float4 color = float4(0.0, 0.0, 0.0, depth);
+
+ // Only shade the surface if
+ // 1. The resulting ray position isn't occluded by lidar depth data.
+ if (depth < worldColor.a) {
+
+ // Shade each color channel with 3 refracted samples
+ float3 normal = calcNormal(res.position, conemarchParams.time, distanceFieldParams, distanceFieldFunction);
+
+ color.rgb = refractSample(res.position, rayDir, normal, 0.98, conemarchParams.projectionMatrix, conemarchParams.viewMatrix, rgbTexture).rgb;
+ color.rgb *= saturate(0.25+0.5*dot(normal, normalize(float3(0.05, 1.0, 0.1)-res.position)));
+ color.rgb *= colorTemperatureToRGB(conemarchParams.lightTemperature);
+
+ } else {
+ color = worldColor;
+ }
+
+ return color;
+}
+
+kernel void conemarchKernel(texture2d<float, access::sample> previousTexture [[texture(0)]],
+ texture2d<float, access::write> outTexture [[texture(1)]],
+ texture2d<float, access::sample> rgbTexture [[texture(2)]],
+ device ConemarchParameters *conemarchParameters [[buffer(0)]],
+ device DistanceFieldParams *distanceFieldParameters [[buffer(1)]],
+ visible_function_table<DistanceFieldFunction> distanceFieldFunctions [[buffer(2)]],
+ device const int &distanceFieldIndex [[buffer(3)]],
+ uint2 gid [[ thread_position_in_grid ]]) {
+
+ // Cone testing passes require nearest sampling.
+ constexpr sampler linearSampler(coord::normalized, address::repeat, filter::linear);
+ constexpr sampler nearestSampler(coord::normalized, address::repeat, filter::nearest);
+
+ float2 textureSize = float2(outTexture.get_width(), outTexture.get_height());
+ float2 uv = float2(gid) / textureSize;
+
+ // Compute last depth if texture exists
+ float lastDepth = conemarchParameters->minDist;
+
+ if (!is_null_texture(previousTexture)) {
+ if (conemarchParameters->computeColor) {
+ lastDepth = previousTexture.sample(linearSampler, uv).a;
+ } else {
+ lastDepth = previousTexture.sample(nearestSampler, uv).a;
+ }
+ }
+
+ // uv coordinate centered at 0,0
+ float2 uv_c = uv * 2.0 - 1.0;
+ uv_c.y = -uv_c.y;
+
+ // Project a ray into the world space
+ float4 rayEye = (conemarchParameters->inverseProjectionMatrix * float4(uv_c,1.0,1.0));
+ float3 rdCam = rayEye.xyz / rayEye.w;
+ float3 rayWorld = normalize((conemarchParameters->inverseViewMatrix * float4(rdCam,1.0)).xyz);
+
+ // Reference the distance field function pointer from the function table.
+ DistanceFieldFunction *distanceFieldFunction = distanceFieldFunctions[0];
+
+ float3 camPos = float3(conemarchParameters->camera[3][0],
+ conemarchParameters->camera[3][1],
+ conemarchParameters->camera[3][2]);
+
+ // Sample "real world" color and depth
+ float4 worldColor = rgbTexture.sample(linearSampler, uv);
+ worldColor.a = min(conemarchParameters->maxDist, worldColor.a);
+
+ float4 result = color(*conemarchParameters,
+ *distanceFieldParameters,
+ distanceFieldFunction,
+ camPos,
+ rayWorld,
+ uv,
+ worldColor,
+ lastDepth,
+ rgbTexture);
+
+ outTexture.write(result, gid);
+}
A => AR-SDF/AR-SDF/Shaders/DistanceFields.h +28 -0
@@ 1,28 @@
+//
+// DistanceFields.h
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-15.
+//
+
+#ifndef DistanceFields_h
+#define DistanceFields_h
+
+using namespace metal;
+struct DistanceFieldParams;
+using DistanceFieldFunction = float(float3 p, float time, DistanceFieldParams params);
+
+struct DistanceFieldParams {
+ float4 param1;
+ float4 param2;
+ float4 param3;
+ float4 param4;
+
+ float4x4 transform;
+
+ float scale;
+ int steps;
+ float fudge;
+};
+
+#endif /* DistanceFields_h */
A => AR-SDF/AR-SDF/Shaders/DistanceFields.metal +85 -0
@@ 1,85 @@
+//
+// DistanceFields.metal
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-15.
+//
+
+#include <metal_stdlib>
+#include "DistanceFields.h"
+
+using namespace metal;
+
+float2 mod(float2 x, float2 y) {
+ return x - y * floor(x/y);
+}
+
+float3 mod(float3 x, float3 y) {
+ return x - y * floor(x/y);
+}
+
+float sdBox( float3 p, float3 b )
+{
+ float3 q = abs(p) - b;
+ return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
+}
+
+float sdSphere(float3 pos, float radius) {
+ return length(pos) - radius;
+}
+
+float hash(float v) {
+ return fract(sin(v) * 6209323.042);
+}
+
+[[visible]]
+float sphere(float3 p, float time, DistanceFieldParams params) {
+ float dist = length(p) - 0.5;
+ return dist;
+}
+
+float length2(float2 p) {
+ return sqrt( p.x*p.x + p.y*p.y );
+}
+
+float length8(float2 p) {
+ p = p*p; p = p*p; p = p*p;
+ return pow( p.x + p.y, 1.0/8.0 );
+}
+
+float sdTorus82(float3 p, float2 t) {
+ float2 q = float2(length2(p.xz)-t.x,p.y);
+ return length8(q)-t.y;
+}
+
+float opS( float d1, float d2 ) {
+ return max(-d2,d1);
+}
+
+[[visible]]
+float gasket(float3 p, float time, DistanceFieldParams params) {
+ float s = dot(p, p)*0.75;
+
+ float radius = params.param1.x;
+ float4 pos = float4(p / s, 1.0);
+ pos.xyz += float3(time * 0.25, 0., time * 0.25);
+
+ pos.xyz = mod(pos.xyz, 2.)-1.;
+
+ for (int i = 0; i < 9; i++) {
+ pos.xyz = clamp(pos.xyz, -1., 1.) * 2. - pos.xyz;
+ pos *= radius/dot(pos.xyz,pos.xyz);
+ }
+ return (0.25*abs(length(pos.xyz))/pos.w) * s;
+}
+
+[[visible]]
+float tunnel(float3 pos, float time, DistanceFieldParams params) {
+ float3 spaceSize = float3(0.25);
+ //pos.xy = pR(pos.xy, pos.z*0.1);
+ float3 p = mod(pos, spaceSize*2.0) - spaceSize;
+
+ float dist = sdBox(p, spaceSize * 0.4);
+
+ return dist;
+}
A => AR-SDF/AR-SDF/Shaders/OrientationTransforms.h +21 -0
@@ 1,21 @@
+//
+// OrientationTransforms.h
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-25.
+//
+
+#ifndef OrientationTransforms_h
+#define OrientationTransforms_h
+
+using namespace metal;
+
+typedef enum {
+ landscapeLeft = 0,
+ portrait,
+ landscapeRight
+} Orientation;
+
+float2 transformedTo(Orientation target, float2 uv);
+
+#endif /* OrientationTransforms_h */
A => AR-SDF/AR-SDF/Shaders/OrientationTransforms.metal +20 -0
@@ 1,20 @@
+//
+// OrientationTransforms.metal
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-10-25.
+//
+
+#include "OrientationTransforms.h"
+
+#include <metal_stdlib>
+using namespace metal;
+
+float2 transformedTo(Orientation target, float2 uv) {
+ if (target == portrait) {
+ return -float2(uv.x, 1-uv.y).yx;
+ } else if (target == landscapeRight) {
+ return 1. - uv;
+ }
+ return uv;
+}
A => AR-SDF/AR-SDF/Shaders/PostFxPass.metal +57 -0
@@ 1,57 @@
+//
+// Compositor.metal
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-18.
+//
+
+#include <metal_stdlib>
+#include "OrientationTransforms.h"
+#include "DistanceFields.h"
+
+using namespace metal;
+
+constexpr sampler colorSampler(coord::normalized,
+ address::clamp_to_border,
+ filter::linear);
+
+float3 postFx_blackAndWhite(texture2d<float, access::sample> conemarchTexture,
+ float2 _uv,
+ float time) {
+ float2 uv = (_uv- 0.5) * 2.0;
+ uv *= 0.975 + pow(abs(float2(uv.y, uv.x)) / float2(5.0, 4.0),2.0);
+
+ float2 ratio = float2(conemarchTexture.get_width() / conemarchTexture.get_height(), 1.0);
+ float vignette = 1.-smoothstep(0.75, 2.5, length(uv * ratio) * length(uv * ratio));
+
+ uv = uv / 2.0 + 0.5;
+ float4 col = conemarchTexture.sample(colorSampler, uv);
+
+ float3 output = mix(col.rgb, sqrt(dot(col.rgb*col.rgb, float3(.299, .587, .114))), 0.5);
+ float strength = 16.0;
+
+ float x = (uv.x + 4.0 ) * (uv.y + 4.0 ) * (time * 10.0);
+ float grain = (fmod((fmod(x, 13.0) + 1.0) * (fmod(x, 123.0) + 1.0), 0.01)-0.005) * strength;
+ output.rgb *= 1.0 - grain;
+
+ output.rgb *= .85 + sin(uv.y*1000.0)*0.15;
+ output.rgb *= vignette;
+ return output;
+}
+
+[[kernel]]
+kernel void PostFxPass(texture2d<float, access::sample> conemarchTexture [[texture(0)]],
+ texture2d<float, access::write> outTexture [[texture(1)]],
+ device const float &time [[buffer(1)]],
+ uint2 gid [[ thread_position_in_grid ]]) {
+
+ float2 outSize = float2(outTexture.get_width(), outTexture.get_height());
+ float2 uv = float2(gid) / outSize;
+
+ float4 col = conemarchTexture.sample(colorSampler, uv);
+ //col.rgb = postFx_blackAndWhite(conemarchTexture, uv, time);
+
+ col.a = 1.0;
+
+ outTexture.write(col, gid);
+}
A => AR-SDF/AR-SDF/Shaders/YCbCrToRGB.metal +47 -0
@@ 1,47 @@
+//
+// YCbCrToRGB.metal
+// conemarch-ar
+//
+// Created by Connor Bell on 2021-07-16.
+// From Apple's pointCloudSample project
+
+#include <metal_stdlib>
+#include "OrientationTransforms.h"
+
+using namespace metal;
+
+// Convert from YCbCr to rgb.
+float4 ycbcrToRGBTransform(float4 y, float4 CbCr) {
+ const float4x4 ycbcrToRGBTransform = float4x4(
+ float4(+1.0000f, +1.0000f, +1.0000f, +0.0000f),
+ float4(+0.0000f, -0.3441f, +1.7720f, +0.0000f),
+ float4(+1.4020f, -0.7141f, +0.0000f, +0.0000f),
+ float4(-0.7010f, +0.5291f, -0.8860f, +1.0000f)
+ );
+
+ float4 ycbcr = float4(y.r, CbCr.rg, 1.0);
+ return ycbcrToRGBTransform * ycbcr;
+}
+
+// Convert the Y and CbCr textures into a single RGBA texture. Also rotates to resulting image.
+kernel void convertYCbCrToRGBA(texture2d<float, access::sample> colorYtexture [[texture(0)]],
+ texture2d<float, access::sample> colorCbCrtexture [[texture(1)]],
+ texture2d<float, access::write> colorRGBTexture [[texture(2)]],
+ texture2d<float, access::sample> depthTexture [[texture(3)]],
+ device const Orientation &orientation [[buffer(0)]],
+ uint2 gid [[thread_position_in_grid]])
+{
+ constexpr sampler s(address::repeat, filter::linear);
+ float2 uv = float2(gid) / float2(colorRGBTexture.get_width(), colorRGBTexture.get_height());
+ uv = transformedTo(orientation, uv);
+
+ // Sample this pixel's camera image color.
+ float4 rgb = ycbcrToRGBTransform(
+ colorYtexture.sample(s, uv),
+ colorCbCrtexture.sample(s, uv)
+ );
+
+ rgb.a = depthTexture.sample(s, uv).r;
+
+ colorRGBTexture.write(rgb, gid.xy);
+}
A => AR-SDF/AR-SDFTests/AR_SDFTests.swift +33 -0
@@ 1,33 @@
+//
+// AR_SDFTests.swift
+// AR-SDFTests
+//
+// Created by Connor Bell on 2022-02-18.
+//
+
+import XCTest
+@testable import AR_SDF
+
+class AR_SDFTests: XCTestCase {
+
+ override func setUpWithError() throws {
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+ }
+
+ override func tearDownWithError() throws {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ }
+
+ func testExample() throws {
+ // This is an example of a functional test case.
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
+ }
+
+ func testPerformanceExample() throws {
+ // This is an example of a performance test case.
+ self.measure {
+ // Put the code you want to measure the time of here.
+ }
+ }
+
+}