diff --git a/Euclid.xcodeproj/project.pbxproj b/Euclid.xcodeproj/project.pbxproj index 3d083bd1..869e917f 100644 --- a/Euclid.xcodeproj/project.pbxproj +++ b/Euclid.xcodeproj/project.pbxproj @@ -73,6 +73,14 @@ 01FAE7BD29744E08008DB288 /* PolygonCSGTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FAE7BB29744C22008DB288 /* PolygonCSGTests.swift */; }; 0A240137256A64FB00C1535C /* AngleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A240136256A64FB00C1535C /* AngleTests.swift */; }; 0A24013F256A671600C1535C /* Angle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A24013E256A671600C1535C /* Angle.swift */; }; + 2B4F06BC2B981DD30025DDF2 /* ExampleVisionOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B4F06BB2B981DD30025DDF2 /* ExampleVisionOSApp.swift */; }; + 2B4F06BE2B981DD30025DDF2 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B4F06BD2B981DD30025DDF2 /* ContentView.swift */; }; + 2B4F06C22B981DD40025DDF2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2B4F06C12B981DD40025DDF2 /* Assets.xcassets */; }; + 2B4F06C52B981DD40025DDF2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2B4F06C42B981DD40025DDF2 /* Preview Assets.xcassets */; }; + 2B4F06CD2B9831960025DDF2 /* Euclid.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 016FAB2921BFE78100AF60DC /* Euclid.framework */; }; + 2B4F06CE2B9831960025DDF2 /* Euclid.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 016FAB2921BFE78100AF60DC /* Euclid.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 2B4F06D32B9831F50025DDF2 /* EuclidMesh.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B4F06D22B9831F50025DDF2 /* EuclidMesh.swift */; }; + 2B6474662B994019006D0E09 /* VolumetricView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B6474652B994019006D0E09 /* VolumetricView.swift */; }; 52A3852E238D6E5700BE8407 /* LineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A3852D238D6E5700BE8407 /* LineTests.swift */; }; 52A663A123857D5300FACF9D /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A663A023857D5300FACF9D /* Line.swift */; }; 52C844E223854CDF009C0A73 /* VectorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C844E023854C87009C0A73 /* VectorTests.swift */; }; @@ -94,6 +102,13 @@ remoteGlobalIDString = 016FAB2821BFE78100AF60DC; remoteInfo = Euclid; }; + 2B4F06CF2B9831960025DDF2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 016FAB2021BFE78100AF60DC /* Project object */; + proxyType = 1; + remoteGlobalIDString = 016FAB2821BFE78100AF60DC; + remoteInfo = Euclid; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -108,6 +123,17 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + 2B4F06D12B9831960025DDF2 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 2B4F06CE2B9831960025DDF2 /* Euclid.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -180,6 +206,14 @@ 01FAE7BB29744C22008DB288 /* PolygonCSGTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonCSGTests.swift; sourceTree = ""; }; 0A240136256A64FB00C1535C /* AngleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AngleTests.swift; sourceTree = ""; }; 0A24013E256A671600C1535C /* Angle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Angle.swift; sourceTree = ""; }; + 2B4F06B52B981DD30025DDF2 /* ExampleVisionOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleVisionOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 2B4F06BB2B981DD30025DDF2 /* ExampleVisionOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleVisionOSApp.swift; sourceTree = ""; }; + 2B4F06BD2B981DD30025DDF2 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 2B4F06C12B981DD40025DDF2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 2B4F06C42B981DD40025DDF2 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 2B4F06C62B981DD40025DDF2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2B4F06D22B9831F50025DDF2 /* EuclidMesh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EuclidMesh.swift; sourceTree = ""; }; + 2B6474652B994019006D0E09 /* VolumetricView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumetricView.swift; sourceTree = ""; }; 52A3852D238D6E5700BE8407 /* LineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineTests.swift; sourceTree = ""; }; 52A663A023857D5300FACF9D /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; 52C844E023854C87009C0A73 /* VectorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VectorTests.swift; sourceTree = ""; }; @@ -210,6 +244,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2B4F06B22B981DD30025DDF2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B4F06CD2B9831960025DDF2 /* Euclid.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -226,6 +268,7 @@ 016FAB2B21BFE78100AF60DC /* Sources */, 016FAB3621BFE78100AF60DC /* Tests */, 016FABEB21C078E400AF60DC /* Example */, + 2B4F06B62B981DD30025DDF2 /* ExampleVisionOS */, 016FAB2A21BFE78100AF60DC /* Products */, 0162A09523795E260078AE84 /* Frameworks */, ); @@ -239,6 +282,7 @@ 016FAB2921BFE78100AF60DC /* Euclid.framework */, 016FAB3221BFE78100AF60DC /* EuclidTests.xctest */, 016FABEA21C078E400AF60DC /* EuclidExample.app */, + 2B4F06B52B981DD30025DDF2 /* ExampleVisionOS.app */, ); name = Products; sourceTree = ""; @@ -334,6 +378,28 @@ path = Example; sourceTree = ""; }; + 2B4F06B62B981DD30025DDF2 /* ExampleVisionOS */ = { + isa = PBXGroup; + children = ( + 2B4F06BB2B981DD30025DDF2 /* ExampleVisionOSApp.swift */, + 2B4F06BD2B981DD30025DDF2 /* ContentView.swift */, + 2B6474652B994019006D0E09 /* VolumetricView.swift */, + 2B4F06D22B9831F50025DDF2 /* EuclidMesh.swift */, + 2B4F06C12B981DD40025DDF2 /* Assets.xcassets */, + 2B4F06C62B981DD40025DDF2 /* Info.plist */, + 2B4F06C32B981DD40025DDF2 /* Preview Content */, + ); + path = ExampleVisionOS; + sourceTree = ""; + }; + 2B4F06C32B981DD40025DDF2 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 2B4F06C42B981DD40025DDF2 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -405,6 +471,27 @@ productReference = 016FABEA21C078E400AF60DC /* EuclidExample.app */; productType = "com.apple.product-type.application"; }; + 2B4F06B42B981DD30025DDF2 /* ExampleVisionOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2B4F06C92B981DD40025DDF2 /* Build configuration list for PBXNativeTarget "ExampleVisionOS" */; + buildPhases = ( + 2B4F06B12B981DD30025DDF2 /* Sources */, + 2B4F06B22B981DD30025DDF2 /* Frameworks */, + 2B4F06B32B981DD30025DDF2 /* Resources */, + 2B4F06D12B9831960025DDF2 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 2B4F06D02B9831960025DDF2 /* PBXTargetDependency */, + ); + name = ExampleVisionOS; + packageProductDependencies = ( + ); + productName = ExampleVisionOS; + productReference = 2B4F06B52B981DD30025DDF2 /* ExampleVisionOS.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -412,7 +499,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 1400; + LastSwiftUpdateCheck = 1530; LastUpgradeCheck = 1500; ORGANIZATIONNAME = "Nick Lockwood"; TargetAttributes = { @@ -428,6 +515,9 @@ CreatedOnToolsVersion = 10.1; LastSwiftMigration = 1240; }; + 2B4F06B42B981DD30025DDF2 = { + CreatedOnToolsVersion = 15.3; + }; }; }; buildConfigurationList = 016FAB2321BFE78100AF60DC /* Build configuration list for PBXProject "Euclid" */; @@ -446,6 +536,7 @@ 016FAB2821BFE78100AF60DC /* Euclid */, 016FAB3121BFE78100AF60DC /* EuclidTests */, 016FABE921C078E400AF60DC /* Example */, + 2B4F06B42B981DD30025DDF2 /* ExampleVisionOS */, ); }; /* End PBXProject section */ @@ -475,6 +566,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2B4F06B32B981DD30025DDF2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B4F06C52B981DD40025DDF2 /* Preview Assets.xcassets in Resources */, + 2B4F06C22B981DD40025DDF2 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -603,6 +703,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2B4F06B12B981DD30025DDF2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B4F06BE2B981DD30025DDF2 /* ContentView.swift in Sources */, + 2B4F06D32B9831F50025DDF2 /* EuclidMesh.swift in Sources */, + 2B4F06BC2B981DD30025DDF2 /* ExampleVisionOSApp.swift in Sources */, + 2B6474662B994019006D0E09 /* VolumetricView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -616,6 +727,11 @@ target = 016FAB2821BFE78100AF60DC /* Euclid */; targetProxy = 0162A09723795E820078AE84 /* PBXContainerItemProxy */; }; + 2B4F06D02B9831960025DDF2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 016FAB2821BFE78100AF60DC /* Euclid */; + targetProxy = 2B4F06CF2B9831960025DDF2 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -906,7 +1022,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 8VQKF583ED; + DEVELOPMENT_TEAM = TW8SJXYFP5; INFOPLIST_FILE = Example/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Euclid Example"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; @@ -919,11 +1035,11 @@ PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.EuclidExample; PRODUCT_NAME = EuclidExample; SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,7"; + TARGETED_DEVICE_FAMILY = "1,2"; TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Debug; @@ -934,7 +1050,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 8VQKF583ED; + DEVELOPMENT_TEAM = TW8SJXYFP5; INFOPLIST_FILE = Example/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Euclid Example"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; @@ -947,16 +1063,84 @@ PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.EuclidExample; PRODUCT_NAME = EuclidExample; SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,7"; + TARGETED_DEVICE_FAMILY = "1,2"; TVOS_DEPLOYMENT_TARGET = 12.0; VALIDATE_PRODUCT = YES; }; name = Release; }; + 2B4F06C72B981DD40025DDF2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"ExampleVisionOS/Preview Content\""; + DEVELOPMENT_TEAM = TW8SJXYFP5; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.ExampleVisionOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 1.1; + }; + name = Debug; + }; + 2B4F06C82B981DD40025DDF2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"ExampleVisionOS/Preview Content\""; + DEVELOPMENT_TEAM = TW8SJXYFP5; + ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.charcoaldesign.ExampleVisionOS; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + VALIDATE_PRODUCT = YES; + XROS_DEPLOYMENT_TARGET = 1.1; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -996,6 +1180,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 2B4F06C92B981DD40025DDF2 /* Build configuration list for PBXNativeTarget "ExampleVisionOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2B4F06C72B981DD40025DDF2 /* Debug */, + 2B4F06C82B981DD40025DDF2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 016FAB2021BFE78100AF60DC /* Project object */; diff --git a/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 00000000..04056a54 --- /dev/null +++ b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json new file mode 100644 index 00000000..950af4d8 --- /dev/null +++ b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "layers" : [ + { + "filename" : "Front.solidimagestacklayer" + }, + { + "filename" : "Middle.solidimagestacklayer" + }, + { + "filename" : "Back.solidimagestacklayer" + } + ] +} diff --git a/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 00000000..04056a54 --- /dev/null +++ b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 00000000..04056a54 --- /dev/null +++ b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/ExampleVisionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleVisionOS/Assets.xcassets/Contents.json b/ExampleVisionOS/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/ExampleVisionOS/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleVisionOS/ContentView.swift b/ExampleVisionOS/ContentView.swift new file mode 100644 index 00000000..573e2c14 --- /dev/null +++ b/ExampleVisionOS/ContentView.swift @@ -0,0 +1,22 @@ +// +// ContentView.swift +// ExampleVisionOS +// +// Created by Hal Mueller on 3/5/24. +// Copyright © 2024 Nick Lockwood. All rights reserved. +// + +import RealityKit +import SwiftUI + +struct ContentView: View { + @State private var enlarge = false + + var body: some View { + VolumetricView() + } +} + +#Preview(windowStyle: .volumetric) { + ContentView() +} diff --git a/ExampleVisionOS/EuclidMesh.swift b/ExampleVisionOS/EuclidMesh.swift new file mode 100644 index 00000000..a6a1b4f1 --- /dev/null +++ b/ExampleVisionOS/EuclidMesh.swift @@ -0,0 +1,26 @@ +// +// EuclidMesh.swift +// ExampleVisionOS +// +// Created by Hal Mueller on 3/5/24. +// Copyright © 2024 Nick Lockwood. All rights reserved. +// + +import CoreGraphics +import Euclid + +let euclidMesh: Mesh = { + let start = CFAbsoluteTimeGetCurrent() + + // create some geometry using Euclid + let cube = Mesh.cube(size: 0.8, material: Color.red) + let sphere = Mesh.sphere(slices: 120, material: CGImage.checkerboard()) + let mesh = cube.subtracting(sphere).makeWatertight() + + print("Time:", CFAbsoluteTimeGetCurrent() - start) + print("Polygons:", mesh.polygons.count) + print("Triangles:", mesh.triangulate().polygons.count) + print("Watertight:", mesh.isWatertight) + + return mesh +}() diff --git a/ExampleVisionOS/ExampleVisionOSApp.swift b/ExampleVisionOS/ExampleVisionOSApp.swift new file mode 100644 index 00000000..ca90e25e --- /dev/null +++ b/ExampleVisionOS/ExampleVisionOSApp.swift @@ -0,0 +1,20 @@ +// +// ExampleVisionOSApp.swift +// ExampleVisionOS +// +// Created by Hal Mueller on 3/5/24. +// Copyright © 2024 Nick Lockwood. All rights reserved. +// + +import SwiftUI + +@main +struct ExampleVisionOSApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + .windowStyle(.volumetric) + .defaultSize(width: 1.5, height: 1.5, depth: 1.5, in: .meters) + } +} diff --git a/ExampleVisionOS/Info.plist b/ExampleVisionOS/Info.plist new file mode 100644 index 00000000..ceaba04b --- /dev/null +++ b/ExampleVisionOS/Info.plist @@ -0,0 +1,15 @@ + + + + + UIApplicationSceneManifest + + UIApplicationPreferredDefaultSceneSessionRole + UIWindowSceneSessionRoleVolumetricApplication + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + + + diff --git a/ExampleVisionOS/Preview Content/Preview Assets.xcassets/Contents.json b/ExampleVisionOS/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/ExampleVisionOS/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ExampleVisionOS/VolumetricView.swift b/ExampleVisionOS/VolumetricView.swift new file mode 100644 index 00000000..56a3f891 --- /dev/null +++ b/ExampleVisionOS/VolumetricView.swift @@ -0,0 +1,53 @@ +// +// VolumetricView.swift +// ExampleVisionOS +// +// Created by Hal Mueller on 3/6/24. +// Copyright © 2024 Nick Lockwood. All rights reserved. +// + +import RealityKit +import SwiftUI + +struct VolumetricView: View { + @State private var spinX = 0.0 + @State private var spinY = 0.0 + + var body: some View { + RealityView { content in + if let demoBoxEntity = try? ModelEntity(euclidMesh.scaled(by: 0.5)) { + // for more realism, add a shadow + demoBoxEntity.components.set(GroundingShadowComponent(castsShadow: true)) + + // needed for tap detection/response + demoBoxEntity.generateCollisionShapes(recursive: true) + + // for gesture targeting + demoBoxEntity.components.set(InputTargetComponent()) + + content.add(demoBoxEntity) + } + } update: { content in + guard let entity = content.entities.first else { return } + + let pitch = Transform(pitch: Float(spinX * -1)).matrix + let yaw = Transform(yaw: Float(spinY)).matrix + entity.transform.matrix = pitch * yaw + } + .gesture( + DragGesture(minimumDistance: 0) + .targetedToAnyEntity() + .onChanged { value in + let startLocation = value.convert(value.startLocation3D, from: .local, to: .scene) + let currentLocation = value.convert(value.location3D, from: .local, to: .scene) + let delta = currentLocation - startLocation + spinX = Double(delta.y) * 5 + spinY = Double(delta.x) * 5 + } + ) + } +} + +#Preview { + VolumetricView() +} diff --git a/README.md b/README.md index e83dbe8d..206cf233 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,10 @@ Feel free to open an issue in Github if you have questions about how to use the If you wish to contribute improvements to the documentation or the code itself, that's great! But please read the [CONTRIBUTING.md](CONTRIBUTING.md) file before submitting a pull request. -# Example +# Example and ExampleVisionOS -See the included project for an example of how Euclid can be used in conjunction with SceneKit or RealityKit to generate and render a nontrivial 3D shape on iOS. +See the included projects for examples of how Euclid can be used in conjunction with SceneKit or RealityKit to generate and render a nontrivial 3D shape. `Example` uses storyboards, is built for iOS, and runs in "Designed for iPad" mode on macOS and visionOS. +`ExampleVisionPro` uses SwiftUI and a RealityView in a volumetric window, and runs only on visionOS. # Documentation