├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── arkit_plugin.iml ├── build.yaml ├── example ├── .gitignore ├── .metadata ├── README.md ├── ios │ ├── Flutter │ │ ├── .last_build_id │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ ├── AR Resources.arresourcegroup │ │ │ ├── Contents.json │ │ │ └── earth2.arreferenceimage │ │ │ │ ├── Contents.json │ │ │ │ └── earth2.jpg │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ ├── Contents.json │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── earth.jpg │ │ ├── earth2.jpg │ │ ├── main.m │ │ ├── models.scnassets │ │ ├── dash.dae │ │ ├── dash_color.png │ │ ├── idleFixed.dae │ │ ├── textures │ │ │ ├── t_dante_hair_black_dm.tga │ │ │ ├── t_dante_hair_s.tga │ │ │ ├── t_eye_d.tga │ │ │ ├── t_obeseMale_dm.tga │ │ │ ├── t_obeseMale_s.tga │ │ │ └── t_obeseMale_teeth_d.tga │ │ └── twist_danceFixed.dae │ │ └── photo360.jpg ├── lib │ ├── ArMeasurementScreen.dart │ └── main.dart └── pubspec.yaml ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── ArkitPlugin.h │ ├── ArkitPlugin.m │ ├── ConfigurationBuilders │ │ ├── BodyTrackingConfigurationBuilder.swift │ │ ├── FaceTrackingConfigurationBuilder.swift │ │ ├── ImageTrackingConfigurationBuilder.swift │ │ └── WorldTrackingConfigurationBuilder.swift │ ├── Extensions │ │ └── UIColorExtensions.swift │ ├── FlutterArkitView+ARSCNViewDelegate.swift │ ├── FlutterArkitView+GesutreRecognizer.swift │ ├── FlutterArkitView+Handlers.swift │ ├── FlutterArkitView+Initialization.swift │ ├── FlutterArkitView.swift │ ├── GeometryBuilders │ │ ├── Geometries.swift │ │ └── GeometryBuilder.swift │ ├── NodeBuilder.swift │ ├── Serializers │ │ ├── AnchorSerializer.swift │ │ ├── Deserializers.swift │ │ └── Serializers.swift │ ├── SwiftArkitPlugin+configurationCheck.swift │ ├── SwiftArkitPlugin.swift │ └── Utils │ │ ├── ARHitResultsHelper.swift │ │ ├── ErrorLogger.swift │ │ ├── ImageParser.swift │ │ └── ReferenceImagesParser.swift └── arkit_plugin.podspec ├── lib ├── arkit_node.dart ├── arkit_plugin.dart ├── arkit_reference_node.dart ├── geometries │ ├── arkit_anchor.dart │ ├── arkit_anchor.g.dart │ ├── arkit_box.dart │ ├── arkit_box.g.dart │ ├── arkit_capsule.dart │ ├── arkit_capsule.g.dart │ ├── arkit_cone.dart │ ├── arkit_cone.g.dart │ ├── arkit_cylinder.dart │ ├── arkit_cylinder.g.dart │ ├── arkit_face.dart │ ├── arkit_face.g.dart │ ├── arkit_geometry.dart │ ├── arkit_geometry.g.dart │ ├── arkit_line.dart │ ├── arkit_line.g.dart │ ├── arkit_plane.dart │ ├── arkit_plane.g.dart │ ├── arkit_pyramid.dart │ ├── arkit_pyramid.g.dart │ ├── arkit_skeleton.dart │ ├── arkit_skeleton.g.dart │ ├── arkit_sphere.dart │ ├── arkit_sphere.g.dart │ ├── arkit_text.dart │ ├── arkit_text.g.dart │ ├── arkit_torus.dart │ ├── arkit_torus.g.dart │ ├── arkit_tube.dart │ ├── arkit_tube.g.dart │ └── material │ │ ├── arkit_blend_mode.dart │ │ ├── arkit_color_mask.dart │ │ ├── arkit_cull_mode.dart │ │ ├── arkit_fill_mode.dart │ │ ├── arkit_lighting_model.dart │ │ ├── arkit_material.dart │ │ ├── arkit_material.g.dart │ │ ├── arkit_material_property.dart │ │ ├── arkit_material_property.g.dart │ │ └── arkit_transparency_mode.dart ├── hit │ ├── arkit_hit_test_result.dart │ ├── arkit_hit_test_result.g.dart │ ├── arkit_hit_test_result_type.dart │ ├── arkit_node_pan_result.dart │ ├── arkit_node_pan_result.g.dart │ ├── arkit_node_pinch_result.dart │ ├── arkit_node_pinch_result.g.dart │ ├── arkit_node_rotation_result.dart │ └── arkit_node_rotation_result.g.dart ├── light │ ├── arkit_light.dart │ ├── arkit_light.g.dart │ ├── arkit_light_estimate.dart │ ├── arkit_light_estimate.g.dart │ └── arkit_light_type.dart ├── physics │ ├── arkit_physics_body.dart │ ├── arkit_physics_body.g.dart │ ├── arkit_physics_body_type.dart │ ├── arkit_physics_shape.dart │ └── arkit_physics_shape.g.dart ├── utils │ ├── json_converters.dart │ ├── matrix4_ext.dart │ └── random_string.dart └── widget │ ├── ar_tracking_state.dart │ ├── arkit_arplane_detection.dart │ ├── arkit_configuration.dart │ ├── arkit_reference_image.dart │ ├── arkit_reference_image.g.dart │ ├── arkit_scene_view.dart │ └── arkit_world_alignment.dart └── pubspec.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Database 22 | node_modules/ 23 | package-lock.json 24 | 25 | # Flutter/Dart/Pub related 26 | **/doc/api/ 27 | .dart_tool/ 28 | .flutter-plugins 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | build/ 33 | lcov.info 34 | 35 | # Android related 36 | **/android/**/gradle-wrapper.jar 37 | **/android/.gradle 38 | **/android/captures/ 39 | **/android/gradlew 40 | **/android/gradlew.bat 41 | **/android/local.properties 42 | **/android/**/GeneratedPluginRegistrant.java 43 | **/android/.project 44 | **/android/.settings/org.eclipse.buildship.core.prefs 45 | 46 | # iOS/XCode related 47 | **/ios/**/*.mode1v3 48 | **/ios/**/*.mode2v3 49 | **/ios/**/*.moved-aside 50 | **/ios/**/*.pbxuser 51 | **/ios/**/*.perspectivev3 52 | **/ios/**/*sync/ 53 | **/ios/**/.sconsign.dblite 54 | **/ios/**/.tags* 55 | **/ios/**/.vagrant/ 56 | **/ios/**/DerivedData/ 57 | **/ios/**/Icon? 58 | **/ios/**/Pods/ 59 | **/ios/**/.symlinks/ 60 | **/ios/**/profile 61 | **/ios/**/xcuserdata 62 | **/ios/.generated/ 63 | **/ios/Flutter/App.framework 64 | **/ios/Flutter/Flutter.framework 65 | **/ios/Flutter/Generated.xcconfig 66 | **/ios/Flutter/app.flx 67 | **/ios/Flutter/app.zip 68 | **/ios/Flutter/flutter_assets/ 69 | **/ios/ServiceDefinitions.json 70 | **/ios/Runner/GeneratedPluginRegistrant.* 71 | **/ios/Flutter/flutter_export_environment.sh 72 | 73 | # Exceptions to above rules. 74 | !**/ios/**/default.mode1v3 75 | !**/ios/**/default.mode2v3 76 | !**/ios/**/default.pbxuser 77 | !**/ios/**/default.perspectivev3 78 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 79 | example/.flutter-plugins-dependencies 80 | example/ios/Flutter/Flutter.podspec 81 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/LICENSE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ar_distance_measurement_app 2 | 3 | Flutter Augmented Reality Distance Tracker App using Apple ArKit Pluggin from Coding Cafe 4 | 5 | 6 | 7 | 8 | ## Join our other New Complete Courses Here 9 | 10 | 11 | ## Flutter ARCore - Build 10+ Augmented Reality Apps 12 | 13 | If you want to become Flutter AR developer and if you want to learn & build 10+ Flutter AR Apps 14 | then please join our Augmented Reality Complete Course: 15 | 16 | - [Build your own 15+ Flutter AR Apps](https://www.udemy.com/course/flutter-augmented-reality-course-build-10-android-ar-apps/?referralCode=4AF65A8713DB39563807) 17 | - [Join our Augmented Reality Complete Course](https://www.udemy.com/course/flutter-augmented-reality-course-build-10-android-ar-apps/?referralCode=4AF65A8713DB39563807) 18 | 19 | 20 | ## Flutter ARKit Augmented Reality Apps Development Course 21 | 22 | If you want to become Flutter AR developer and if you want to learn & build 15+ Flutter AR Apps 23 | then please join our Augmented Reality Complete Course: 24 | 25 | - [Build your own 15+ Flutter AR Apps](https://www.udemy.com/course/flutter-arkit-course-build-15-augmented-reality-ios-apps/?referralCode=B8190D9CECB8D5771B4A) 26 | - [Join our Augmented Reality Complete Course](https://www.udemy.com/course/flutter-arkit-course-build-15-augmented-reality-ios-apps/?referralCode=B8190D9CECB8D5771B4A) 27 | 28 | 29 | ## Flutter Android & iOS Augmented Reality More Courses to Follow 30 | 31 | - [Build your own Snapchat Face Mask Filters App](https://www.udemy.com/course/build-flutter-ar-face-filters-app-like-snapchat-filters-2021/?referralCode=380AF6E44C2BAB2A6040) 32 | - [Join Complete Course, Please Click Here](https://www.udemy.com/course/build-flutter-ar-face-filters-app-like-snapchat-filters-2021/?referralCode=380AF6E44C2BAB2A6040) 33 | 34 | 35 | 36 | ## Flutter Android & iOS AI Deep Learning & Machine Learning Courses - 15+ Ai Apps 37 | 38 | - [Build 15+ Ai Deep Learning & Machine Learning Apps](https://www.udemy.com/course/flutter-artificial-intelligence-course-build-15-ai-apps/?referralCode=477033A2DC5E6E8BF740) 39 | - [Join Complete Course here, Please Click Here](https://www.udemy.com/course/flutter-artificial-intelligence-course-build-15-ai-apps/?referralCode=477033A2DC5E6E8BF740) 40 | 41 | 42 | 43 | ## Flutter Android & iOS Deep Learning Sketch to Real Life Human Face Generator App 44 | 45 | - [Join Complete Course here, Please Click Here](https://www.udemy.com/course/build-drawing-to-real-life-generator-app-using-flutter/?referralCode=2B3114D7C89C0BEDBCF0) 46 | 47 | 48 | ## Learn Flutter & Firebase and Build your own Car Selling App 49 | 50 | If you want to become Flutter developer and if you want to learn & build Apps for WEB, Android, iOS 51 | from single code base then please join our Complete Course here: 52 | 53 | - [Build your own Flutter Car Selling App](https://www.udemy.com/course/learn-flutter-20-firebase-build-android-ios-web-apps/?referralCode=D9E5CE37FF4EB80E7021) 54 | - [Join our Complete Course here](https://www.udemy.com/course/learn-flutter-20-firebase-build-android-ios-web-apps/?referralCode=D9E5CE37FF4EB80E7021) 55 | 56 | 57 | ## Flutter OLX Clone App using Firebase 58 | 59 | Complete Course here: 60 | 61 | - [Build your own Olx Clone App](https://www.udemy.com/course/build-olx-clone-app-with-admin-panel-with-flutter-firebase/?referralCode=76150526E260789B7888) 62 | - [Join our Complete Course here](https://www.udemy.com/course/build-olx-clone-app-with-admin-panel-with-flutter-firebase/?referralCode=76150526E260789B7888) 63 | 64 | 65 | ## Flutter Augmented Reality AR Furniture App 66 | 67 | - [Build your own AR Furniture App like iKEA AR App Clone](https://www.udemy.com/course/flutter-augmented-reality-ar-furniture-app-using-arcore/?referralCode=3761B3E00A1F5D259DDD) 68 | - [Join our Complete Course here](https://www.udemy.com/course/flutter-augmented-reality-ar-furniture-app-using-arcore/?referralCode=3761B3E00A1F5D259DDD) 69 | 70 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:pedantic/analysis_options.1.9.0.yaml 2 | 3 | analyzer: 4 | exclude: 5 | # workaround for https://github.com/dart-lang/sdk/issues/42910 6 | - 'example/**' 7 | - '**/*.g.dart' -------------------------------------------------------------------------------- /arkit_plugin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | builders: 4 | json_serializable: 5 | options: 6 | any_map: false 7 | checked: false 8 | create_factory: true 9 | create_to_json: true 10 | disallow_unrecognized_keys: false 11 | explicit_to_json: false 12 | field_rename: none 13 | ignore_unannotated: false 14 | include_if_null: false 15 | nullable: false -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .flutter-plugins-dependencies 26 | .packages 27 | .pub-cache/ 28 | .pub/ 29 | /build/ 30 | 31 | # Android related 32 | **/android/**/gradle-wrapper.jar 33 | **/android/.gradle 34 | **/android/captures/ 35 | **/android/gradlew 36 | **/android/gradlew.bat 37 | **/android/local.properties 38 | **/android/**/GeneratedPluginRegistrant.java 39 | 40 | # iOS/XCode related 41 | **/ios/**/*.mode1v3 42 | **/ios/**/*.mode2v3 43 | **/ios/**/*.moved-aside 44 | **/ios/**/*.pbxuser 45 | **/ios/**/*.perspectivev3 46 | **/ios/**/*sync/ 47 | **/ios/**/.sconsign.dblite 48 | **/ios/**/.tags* 49 | **/ios/**/.vagrant/ 50 | **/ios/**/DerivedData/ 51 | **/ios/**/Icon? 52 | **/ios/**/Pods/ 53 | **/ios/**/.symlinks/ 54 | **/ios/**/profile 55 | **/ios/**/xcuserdata 56 | **/ios/.generated/ 57 | **/ios/Flutter/App.framework 58 | **/ios/Flutter/Flutter.framework 59 | **/ios/Flutter/Generated.xcconfig 60 | **/ios/Flutter/app.flx 61 | **/ios/Flutter/app.zip 62 | **/ios/Flutter/flutter_assets/ 63 | **/ios/Flutter/Flutter.podspec 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: e5b1ed7a7f7b85c1877e09a9495681f719be5578 8 | channel: beta 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # ar_distance_measurement_app 2 | 3 | Flutter Augmented Reality Distance Tracker App using Apple ArKit Pluggin from Coding Cafe 4 | 5 | ## Join Complete Course Here 6 | 7 | If you want to become Flutter AR developer and if you want to learn & build 15+ Flutter AR Apps 8 | then please join our Augmented Reality Complete Course: 9 | 10 | - [Build your own 15+ Flutter AR Apps](https://www.udemy.com/course/flutter-arkit-course-build-15-augmented-reality-ios-apps/?referralCode=B8190D9CECB8D5771B4A) 11 | - [Join our Augmented Reality Complete Course](https://www.udemy.com/course/flutter-arkit-course-build-15-augmented-reality-ios-apps/?referralCode=B8190D9CECB8D5771B4A) 12 | 13 | 14 | ## Flutter Android & iOS Augmented Reality More Courses to Follow 15 | 16 | - [Build your own Snapchat Face Mask Filters App](https://www.udemy.com/course/build-flutter-ar-face-filters-app-like-snapchat-filters-2021/?referralCode=380AF6E44C2BAB2A6040) 17 | - [Join Complete Course, Please Click Here](https://www.udemy.com/course/build-flutter-ar-face-filters-app-like-snapchat-filters-2021/?referralCode=380AF6E44C2BAB2A6040) 18 | 19 | 20 | ## Flutter Android & iOS AI Deep Learning & Machine Learning Courses - 15+ Ai Apps 21 | 22 | - [Build 15+ Ai Deep Learning & Machine Learning Apps](https://www.udemy.com/course/flutter-artificial-intelligence-course-build-15-ai-apps/?referralCode=477033A2DC5E6E8BF740) 23 | - [Join Complete Course here, Please Click Here](https://www.udemy.com/course/flutter-artificial-intelligence-course-build-15-ai-apps/?referralCode=477033A2DC5E6E8BF740) 24 | 25 | 26 | ## Flutter Android & iOS Deep Learning Sketch to Real Life Human Face Generator App 27 | 28 | - [Join Complete Course here, Please Click Here](https://www.udemy.com/course/build-drawing-to-real-life-generator-app-using-flutter/?referralCode=2B3114D7C89C0BEDBCF0) 29 | -------------------------------------------------------------------------------- /example/ios/Flutter/.last_build_id: -------------------------------------------------------------------------------- 1 | 2c76bf960b8e75857295fe7a6578e59a -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | 84 | post_install do |installer| 85 | installer.pods_project.targets.each do |target| 86 | target.build_configurations.each do |config| 87 | config.build_settings['ENABLE_BITCODE'] = 'NO' 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AR Resources.arresourcegroup/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "resources" : [ 7 | { 8 | "filename" : "earth2.arreferenceimage" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AR Resources.arresourcegroup/earth2.arreferenceimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "earth2.jpg" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "width" : 20, 14 | "unit" : "centimeters" 15 | } 16 | } -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AR Resources.arresourcegroup/earth2.arreferenceimage/earth2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AR Resources.arresourcegroup/earth2.arreferenceimage/earth2.jpg -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Ar Measurement App 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | arkit_plugin_example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | NSCameraUsageDescription 28 | 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UIViewControllerBasedStatusBarAppearance 47 | 48 | io.flutter.embedded_views_preview 49 | YES 50 | 51 | 52 | -------------------------------------------------------------------------------- /example/ios/Runner/earth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/earth.jpg -------------------------------------------------------------------------------- /example/ios/Runner/earth2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/earth2.jpg -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/ios/Runner/models.scnassets/dash_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/models.scnassets/dash_color.png -------------------------------------------------------------------------------- /example/ios/Runner/models.scnassets/textures/t_dante_hair_black_dm.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/models.scnassets/textures/t_dante_hair_black_dm.tga -------------------------------------------------------------------------------- /example/ios/Runner/models.scnassets/textures/t_eye_d.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/models.scnassets/textures/t_eye_d.tga -------------------------------------------------------------------------------- /example/ios/Runner/models.scnassets/textures/t_obeseMale_dm.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/models.scnassets/textures/t_obeseMale_dm.tga -------------------------------------------------------------------------------- /example/ios/Runner/models.scnassets/textures/t_obeseMale_s.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/models.scnassets/textures/t_obeseMale_s.tga -------------------------------------------------------------------------------- /example/ios/Runner/models.scnassets/textures/t_obeseMale_teeth_d.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/models.scnassets/textures/t_obeseMale_teeth_d.tga -------------------------------------------------------------------------------- /example/ios/Runner/photo360.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/example/ios/Runner/photo360.jpg -------------------------------------------------------------------------------- /example/lib/ArMeasurementScreen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math' as math; 2 | import 'package:arkit_plugin/arkit_plugin.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:vector_math/vector_math_64.dart' as vector; 5 | 6 | class ArMeasurementScreen extends StatefulWidget { 7 | @override 8 | _ArMeasurementScreenState createState() => _ArMeasurementScreenState(); 9 | } 10 | 11 | class _ArMeasurementScreenState extends State 12 | { 13 | ARKitController arkitController; 14 | ARKitPlane plane; 15 | ARKitNode node; 16 | String anchorId; 17 | vector.Vector3 lastPosition; 18 | 19 | @override 20 | Widget build(BuildContext context) => Scaffold( 21 | appBar: AppBar(title: const Text('Distance Tracker App')), 22 | body: Container( 23 | child: ARKitSceneView( 24 | showFeaturePoints: true, 25 | planeDetection: ARPlaneDetection.horizontal, 26 | onARKitViewCreated: onARKitViewCreated, 27 | enableTapRecognizer: true, 28 | ), 29 | ), 30 | ); 31 | 32 | void onARKitViewCreated(ARKitController arkitController) 33 | { 34 | this.arkitController = arkitController; 35 | this.arkitController.onAddNodeForAnchor = _handleAddAnchor; 36 | this.arkitController.onUpdateNodeForAnchor = _handleUpdateAnchor; 37 | this.arkitController.onARTap = (List ar) { 38 | final planeTap = ar.firstWhere( 39 | (tap) => tap.type == ARKitHitTestResultType.existingPlaneUsingExtent, 40 | orElse: () => null, 41 | ); 42 | if (planeTap != null) { 43 | _onPlaneTapHandler(planeTap.worldTransform); 44 | } 45 | }; 46 | } 47 | 48 | void _handleAddAnchor(ARKitAnchor anchor) 49 | { 50 | if (!(anchor is ARKitPlaneAnchor)) { 51 | return; 52 | } 53 | _addPlane(arkitController, anchor); 54 | } 55 | 56 | void _handleUpdateAnchor(ARKitAnchor anchor) 57 | { 58 | if (anchor.identifier != anchorId) { 59 | return; 60 | } 61 | final ARKitPlaneAnchor planeAnchor = anchor; 62 | node.position = 63 | vector.Vector3(planeAnchor.center.x, 0, planeAnchor.center.z); 64 | plane.width.value = planeAnchor.extent.x; 65 | plane.height.value = planeAnchor.extent.z; 66 | } 67 | 68 | void _addPlane(ARKitController controller, ARKitPlaneAnchor anchor) 69 | { 70 | anchorId = anchor.identifier; 71 | plane = ARKitPlane( 72 | width: anchor.extent.x, 73 | height: anchor.extent.z, 74 | materials: [ 75 | ARKitMaterial( 76 | transparency: 0.5, 77 | diffuse: ARKitMaterialProperty(color: Colors.white), 78 | ) 79 | ], 80 | ); 81 | 82 | node = ARKitNode( 83 | geometry: plane, 84 | position: vector.Vector3(anchor.center.x, 0, anchor.center.z), 85 | rotation: vector.Vector4(1, 0, 0, -math.pi / 2), 86 | ); 87 | controller.add(node, parentNodeName: anchor.nodeName); 88 | } 89 | 90 | void _onPlaneTapHandler(Matrix4 transform) 91 | { 92 | final position = vector.Vector3( 93 | transform.getColumn(3).x, 94 | transform.getColumn(3).y, 95 | transform.getColumn(3).z, 96 | ); 97 | final material = ARKitMaterial( 98 | lightingModelName: ARKitLightingModel.constant, 99 | diffuse: 100 | ARKitMaterialProperty(color: const Color.fromRGBO(255, 153, 83, 1)), 101 | ); 102 | final sphere = ARKitSphere( 103 | radius: 0.003, 104 | materials: [material], 105 | ); 106 | final node = ARKitNode( 107 | geometry: sphere, 108 | position: position, 109 | ); 110 | arkitController.add(node); 111 | if (lastPosition != null) { 112 | final line = ARKitLine( 113 | fromVector: lastPosition, 114 | toVector: position, 115 | ); 116 | final lineNode = ARKitNode(geometry: line); 117 | arkitController.add(lineNode); 118 | 119 | final distance = _calculateDistanceBetweenPoints(position, lastPosition); 120 | final point = _getMiddleVector(position, lastPosition); 121 | _drawText(distance, point); 122 | } 123 | lastPosition = position; 124 | } 125 | 126 | String _calculateDistanceBetweenPoints(vector.Vector3 A, vector.Vector3 B) 127 | { 128 | final length = A.distanceTo(B); 129 | return '${(length * 100).toStringAsFixed(2)} cm'; 130 | } 131 | 132 | vector.Vector3 _getMiddleVector(vector.Vector3 A, vector.Vector3 B) 133 | { 134 | return vector.Vector3((A.x + B.x) / 2, (A.y + B.y) / 2, (A.z + B.z) / 2); 135 | } 136 | 137 | void _drawText(String text, vector.Vector3 point) 138 | { 139 | final textGeometry = ARKitText( 140 | text: text, 141 | extrusionDepth: 1, 142 | materials: [ 143 | ARKitMaterial( 144 | diffuse: ARKitMaterialProperty(color: Colors.red), 145 | ) 146 | ], 147 | ); 148 | const scale = 0.001; 149 | final vectorScale = vector.Vector3(scale, scale, scale); 150 | final node = ARKitNode( 151 | geometry: textGeometry, 152 | position: point, 153 | scale: vectorScale, 154 | ); 155 | arkitController 156 | .getNodeBoundingBox(node) 157 | .then((List result) { 158 | final minVector = result[0]; 159 | final maxVector = result[1]; 160 | final dx = (maxVector.x - minVector.x) / 2 * scale; 161 | final dy = (maxVector.y - minVector.y) / 2 * scale; 162 | final position = vector.Vector3( 163 | node.position.x - dx, 164 | node.position.y - dy, 165 | node.position.z, 166 | ); 167 | node.position = position; 168 | }); 169 | arkitController.add(node); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'ArMeasurementScreen.dart'; 3 | 4 | 5 | void main() { 6 | runApp(MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | // This widget is the root of your application. 11 | @override 12 | Widget build(BuildContext context) { 13 | return MaterialApp( 14 | title: 'ARKit Flutter App', 15 | home: ArMeasurementScreen(), 16 | ); 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: arkit_plugin_example 2 | description: Demonstrates how to use the arkit_plugin plugin. 3 | publish_to: 'none' 4 | 5 | environment: 6 | sdk: ">=2.1.0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | 12 | # The following adds the Cupertino Icons font to your application. 13 | # Use with the CupertinoIcons class for iOS style icons. 14 | cupertino_icons: ^0.1.2 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | 20 | arkit_plugin: 21 | path: ../ 22 | 23 | # For information on the generic Dart part of this file, see the 24 | # following page: https://www.dartlang.org/tools/pub/pubspec 25 | 26 | # The following section is specific to Flutter. 27 | flutter: 28 | 29 | # The following line ensures that the Material Icons font is 30 | # included with your application, so that you can use the icons in 31 | # the material Icons class. 32 | uses-material-design: true 33 | 34 | # To add assets to your application, add an assets section, like this: 35 | # assets: 36 | # - images/a_dot_burr.jpeg 37 | # - images/a_dot_ham.jpeg 38 | 39 | # An image asset can refer to one or more resolution-specific "variants", see 40 | # https://flutter.io/assets-and-images/#resolution-aware. 41 | 42 | # For details regarding adding assets from package dependencies, see 43 | # https://flutter.io/assets-and-images/#from-packages 44 | 45 | # To add custom fonts to your application, add a fonts section here, 46 | # in this "flutter" section. Each entry in this list should have a 47 | # "family" key with the font family name, and a "fonts" key with a 48 | # list giving the asset and other descriptors for the font. For 49 | # example: 50 | # fonts: 51 | # - family: Schyler 52 | # fonts: 53 | # - asset: fonts/Schyler-Regular.ttf 54 | # - asset: fonts/Schyler-Italic.ttf 55 | # style: italic 56 | # - family: Trajan Pro 57 | # fonts: 58 | # - asset: fonts/TrajanPro.ttf 59 | # - asset: fonts/TrajanPro_Bold.ttf 60 | # weight: 700 61 | # 62 | # For details regarding fonts from package dependencies, 63 | # see https://flutter.io/custom-fonts/#from-packages 64 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingcafe1/ArDistanceTrackerApp/5c7444d566427f2c53b9261ac0f57ff1321115e1/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/ArkitPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ArkitPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/ArkitPlugin.m: -------------------------------------------------------------------------------- 1 | #import "ArkitPlugin.h" 2 | #if __has_include() 3 | #import 4 | #else 5 | // Support project import fallback if the generated compatibility header 6 | // is not copied when this plugin is created as a library. 7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 8 | #import "arkit_plugin-Swift.h" 9 | #endif 10 | 11 | @implementation ArkitPlugin 12 | + (void)registerWithRegistrar:(NSObject*)registrar { 13 | [SwiftArkitPlugin registerWithRegistrar:registrar]; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /ios/Classes/ConfigurationBuilders/BodyTrackingConfigurationBuilder.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ARKit 3 | 4 | @available(iOS 13.0, *) 5 | func createBodyTrackingConfiguration(_ arguments: Dictionary) -> ARBodyTrackingConfiguration? { 6 | if(ARBodyTrackingConfiguration.isSupported) { 7 | return ARBodyTrackingConfiguration() 8 | } 9 | return nil 10 | } 11 | -------------------------------------------------------------------------------- /ios/Classes/ConfigurationBuilders/FaceTrackingConfigurationBuilder.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ARKit 3 | 4 | #if !DISABLE_TRUEDEPTH_API 5 | func createFaceTrackingConfiguration(_ arguments: Dictionary) -> ARFaceTrackingConfiguration? { 6 | if(ARFaceTrackingConfiguration.isSupported) { 7 | return ARFaceTrackingConfiguration() 8 | } 9 | return nil 10 | } 11 | #endif 12 | -------------------------------------------------------------------------------- /ios/Classes/ConfigurationBuilders/ImageTrackingConfigurationBuilder.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ARKit 3 | 4 | @available(iOS 12.0, *) 5 | func createImageTrackingConfiguration(_ arguments: Dictionary) -> ARImageTrackingConfiguration? { 6 | if(ARImageTrackingConfiguration.isSupported) { 7 | let imageTrackingConfiguration = ARImageTrackingConfiguration() 8 | 9 | if let trackingImagesGroupName = arguments["trackingImagesGroupName"] as? String, 10 | let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: trackingImagesGroupName, bundle: nil) { 11 | imageTrackingConfiguration.trackingImages = referenceImages 12 | } 13 | if let trackingImages = arguments["trackingImages"] as? Array> { 14 | imageTrackingConfiguration.trackingImages = parseReferenceImagesSet(trackingImages) 15 | } 16 | if let maximumNumberOfTrackedImages = arguments["maximumNumberOfTrackedImages"] as? Int { 17 | imageTrackingConfiguration.maximumNumberOfTrackedImages = maximumNumberOfTrackedImages 18 | } 19 | return imageTrackingConfiguration 20 | } 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /ios/Classes/ConfigurationBuilders/WorldTrackingConfigurationBuilder.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ARKit 3 | 4 | func createWorldTrackingConfiguration(_ arguments: Dictionary) -> ARWorldTrackingConfiguration? { 5 | if(ARWorldTrackingConfiguration.isSupported) { 6 | let worldTrackingConfiguration = ARWorldTrackingConfiguration() 7 | if let planeDetection = arguments["planeDetection"] as? Int { 8 | if planeDetection == 1 { 9 | worldTrackingConfiguration.planeDetection = .horizontal 10 | } 11 | if planeDetection == 2 { 12 | if #available(iOS 11.3, *) { 13 | worldTrackingConfiguration.planeDetection = .vertical 14 | } 15 | } 16 | if planeDetection == 3 { 17 | if #available(iOS 11.3, *) { 18 | worldTrackingConfiguration.planeDetection = [.horizontal, .vertical] 19 | } 20 | } 21 | } 22 | if #available(iOS 11.3, *) { 23 | if let detectionImagesGroupName = arguments["detectionImagesGroupName"] as? String { 24 | worldTrackingConfiguration.detectionImages = ARReferenceImage.referenceImages(inGroupNamed: detectionImagesGroupName, bundle: nil) 25 | } 26 | if let detectionImages = arguments["detectionImages"] as? Array> { 27 | worldTrackingConfiguration.detectionImages = parseReferenceImagesSet(detectionImages) 28 | } 29 | } 30 | if #available(iOS 12.0, *) { 31 | if let maximumNumberOfTrackedImages = arguments["maximumNumberOfTrackedImages"] as? Int { 32 | worldTrackingConfiguration.maximumNumberOfTrackedImages = maximumNumberOfTrackedImages 33 | } 34 | } 35 | return worldTrackingConfiguration 36 | } 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /ios/Classes/Extensions/UIColorExtensions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import UIKit 3 | 4 | extension UIColor { 5 | convenience init(rgb: UInt) { 6 | self.init( 7 | red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0, 8 | green: CGFloat((rgb & 0x00FF00) >> 8) / 255.0, 9 | blue: CGFloat(rgb & 0x0000FF) / 255.0, 10 | alpha: CGFloat(1.0) 11 | ) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Classes/FlutterArkitView+ARSCNViewDelegate.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ARKit 3 | 4 | extension FlutterArkitView: ARSCNViewDelegate { 5 | func session(_ session: ARSession, didFailWithError error: Error) { 6 | logPluginError("sessionDidFailWithError: \(error.localizedDescription)", toChannel: channel) 7 | } 8 | 9 | func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera){ 10 | var params = [String: NSNumber]() 11 | 12 | switch camera.trackingState { 13 | case .notAvailable: 14 | params["trackingState"] = 0 15 | break 16 | case .limited(let reason): 17 | params["trackingState"] = 1 18 | switch reason { 19 | case .initializing: 20 | params["reason"] = 1 21 | break 22 | case .relocalizing: 23 | params["reason"] = 2 24 | break 25 | case .excessiveMotion: 26 | params["reason"] = 3 27 | break 28 | case .insufficientFeatures: 29 | params["reason"] = 4 30 | break 31 | default: 32 | params["reason"] = 0 33 | break 34 | } 35 | break 36 | case .normal: 37 | params["trackingState"] = 2 38 | break 39 | } 40 | 41 | self.channel.invokeMethod("onCameraDidChangeTrackingState", arguments: params) 42 | } 43 | 44 | func sessionWasInterrupted(_ session: ARSession) { 45 | self.channel.invokeMethod("onSessionWasInterrupted", arguments: nil) 46 | } 47 | 48 | func sessionInterruptionEnded(_ session: ARSession) { 49 | self.channel.invokeMethod("onSessionInterruptionEnded", arguments: nil) 50 | } 51 | 52 | func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { 53 | if (node.name == nil) { 54 | node.name = NSUUID().uuidString 55 | } 56 | let params = prepareParamsForAnchorEvent(node, anchor) 57 | self.channel.invokeMethod("didAddNodeForAnchor", arguments: params) 58 | } 59 | 60 | func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { 61 | let params = prepareParamsForAnchorEvent(node, anchor) 62 | self.channel.invokeMethod("didUpdateNodeForAnchor", arguments: params) 63 | } 64 | 65 | func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) { 66 | let params = prepareParamsForAnchorEvent(node, anchor) 67 | self.channel.invokeMethod("didRemoveNodeForAnchor", arguments: params) 68 | } 69 | 70 | func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { 71 | let params = ["time": NSNumber(floatLiteral: time)] 72 | self.channel.invokeMethod("updateAtTime", arguments: params) 73 | } 74 | 75 | fileprivate func prepareParamsForAnchorEvent(_ node: SCNNode, _ anchor: ARAnchor) -> Dictionary { 76 | var serializedAnchor = serializeAnchor(anchor) 77 | serializedAnchor["nodeName"] = node.name 78 | return serializedAnchor 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ios/Classes/FlutterArkitView+GesutreRecognizer.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | extension FlutterArkitView: UIGestureRecognizerDelegate { 4 | 5 | func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 6 | return true 7 | } 8 | 9 | func initalizeGesutreRecognizers(_ arguments: Dictionary) { 10 | if let enableTap = arguments["enableTapRecognizer"] as? Bool { 11 | if (enableTap) { 12 | let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) 13 | tapGestureRecognizer.delegate = self 14 | self.sceneView.gestureRecognizers?.append(tapGestureRecognizer) 15 | } 16 | } 17 | 18 | if let enablePinch = arguments["enablePinchRecognizer"] as? Bool{ 19 | if (enablePinch) { 20 | let pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(_:))) 21 | pinchGestureRecognizer.delegate = self 22 | self.sceneView.gestureRecognizers?.append(pinchGestureRecognizer) 23 | } 24 | } 25 | 26 | if let enablePan = arguments["enablePanRecognizer"] as? Bool { 27 | if (enablePan) { 28 | let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))) 29 | panGestureRecognizer.delegate = self 30 | self.sceneView.gestureRecognizers?.append(panGestureRecognizer) 31 | } 32 | } 33 | 34 | if let enableRotation = arguments["enableRotationRecognizer"] as? Bool { 35 | if (enableRotation) { 36 | let rotationGestureRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(handleRotation(_:))) 37 | rotationGestureRecognizer.delegate = self 38 | self.sceneView.gestureRecognizers?.append(rotationGestureRecognizer) 39 | } 40 | } 41 | } 42 | 43 | 44 | @objc func handleTap(_ recognizer: UITapGestureRecognizer) { 45 | guard let sceneView = recognizer.view as? ARSCNView else { 46 | return 47 | } 48 | let touchLocation = self.forceTapOnCenter ? self.sceneView.center : recognizer.location(in: sceneView) 49 | let hitResults = sceneView.hitTest(touchLocation, options: nil) 50 | let results: Array = hitResults.compactMap { $0.node.name } 51 | if (results.count != 0) { 52 | self.channel.invokeMethod("onNodeTap", arguments: results) 53 | } 54 | 55 | let arHitResults = getARHitResultsArray(sceneView, atLocation: touchLocation) 56 | if (arHitResults.count != 0) { 57 | self.channel.invokeMethod("onARTap", arguments: arHitResults) 58 | } 59 | } 60 | 61 | @objc func handlePinch(_ recognizer: UIPinchGestureRecognizer) { 62 | guard let sceneView = recognizer.view as? ARSCNView else { 63 | return 64 | } 65 | if (recognizer.state == .changed) { 66 | let touchLocation = recognizer.location(in: sceneView) 67 | let hitResults = sceneView.hitTest(touchLocation, options: nil) 68 | let results: Array> = hitResults.compactMap { 69 | if let name = $0.node.name { 70 | return ["nodeName" : name, "scale": recognizer.scale] 71 | } else { 72 | return nil 73 | } 74 | } 75 | if (results.count != 0) { 76 | self.channel.invokeMethod("onNodePinch", arguments: results) 77 | } 78 | } 79 | } 80 | 81 | @objc func handlePan(_ recognizer: UIPanGestureRecognizer) { 82 | guard let sceneView = recognizer.view as? ARSCNView else { 83 | return 84 | } 85 | if (recognizer.state == .changed) { 86 | let touchLocation = recognizer.location(in: sceneView) 87 | let translation = recognizer.translation(in: sceneView) 88 | let hitResults = sceneView.hitTest(touchLocation, options: nil) 89 | 90 | let results: Array> = hitResults.compactMap { 91 | if let name = $0.node.name { 92 | return ["nodeName" : name, 93 | "translation": [translation.x, translation.y] 94 | ] 95 | } else { 96 | return nil 97 | } 98 | } 99 | if (results.count != 0) { 100 | self.channel.invokeMethod("onNodePan", arguments: results) 101 | } 102 | } 103 | } 104 | 105 | @objc func handleRotation(_ recognizer: UIRotationGestureRecognizer) { 106 | guard let sceneView = recognizer.view as? ARSCNView else { 107 | return 108 | } 109 | if (recognizer.state == .changed) { 110 | let touchLocation = recognizer.location(in: sceneView) 111 | let hitResults = sceneView.hitTest(touchLocation, options: nil) 112 | 113 | let results: Array> = hitResults.compactMap { 114 | if let name = $0.node.name { 115 | return ["nodeName" : name, "rotation": recognizer.rotation] 116 | } else { 117 | return nil 118 | } 119 | } 120 | if (results.count != 0) { 121 | self.channel.invokeMethod("onNodeRotation", arguments: results) 122 | } 123 | recognizer.rotation = 0 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /ios/Classes/FlutterArkitView+Initialization.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | extension FlutterArkitView { 4 | func initalize(_ arguments: Dictionary, _ result:FlutterResult) { 5 | if let showStatistics = arguments["showStatistics"] as? Bool { 6 | self.sceneView.showsStatistics = showStatistics 7 | } 8 | 9 | if let autoenablesDefaultLighting = arguments["autoenablesDefaultLighting"] as? Bool { 10 | self.sceneView.autoenablesDefaultLighting = autoenablesDefaultLighting 11 | } 12 | 13 | if let forceUserTapOnCenter = arguments["forceUserTapOnCenter"] as? Bool { 14 | self.forceTapOnCenter = forceUserTapOnCenter 15 | } 16 | 17 | initalizeGesutreRecognizers(arguments) 18 | 19 | sceneView.debugOptions = parseDebugOptions(arguments) 20 | configuration = parseConfiguration(arguments) 21 | if (configuration != nil) { 22 | self.sceneView.session.run(self.configuration!) 23 | } 24 | } 25 | 26 | func parseDebugOptions(_ arguments: Dictionary) -> SCNDebugOptions { 27 | var options = ARSCNDebugOptions().rawValue 28 | if let showFeaturePoint = arguments["showFeaturePoints"] as? Bool { 29 | if (showFeaturePoint) { 30 | options |= ARSCNDebugOptions.showFeaturePoints.rawValue 31 | } 32 | } 33 | if let showWorldOrigin = arguments["showWorldOrigin"] as? Bool { 34 | if (showWorldOrigin) { 35 | options |= ARSCNDebugOptions.showWorldOrigin.rawValue 36 | } 37 | } 38 | return ARSCNDebugOptions(rawValue: options) 39 | } 40 | 41 | func parseConfiguration(_ arguments: Dictionary) -> ARConfiguration? { 42 | let configurationType = arguments["configuration"] as! Int 43 | var configuration: ARConfiguration? = nil 44 | 45 | switch configurationType { 46 | case 0: 47 | configuration = createWorldTrackingConfiguration(arguments) 48 | break 49 | case 1: 50 | #if !DISABLE_TRUEDEPTH_API 51 | configuration = createFaceTrackingConfiguration(arguments) 52 | #else 53 | logPluginError("TRUEDEPTH_API disabled", toChannel: channel) 54 | #endif 55 | break 56 | case 2: 57 | if #available(iOS 12.0, *) { 58 | configuration = createImageTrackingConfiguration(arguments) 59 | } else { 60 | logPluginError("configuration is not supported on this device", toChannel: channel) 61 | } 62 | break 63 | case 3: 64 | if #available(iOS 13.0, *) { 65 | configuration = createBodyTrackingConfiguration(arguments) 66 | } else { 67 | logPluginError("configuration is not supported on this device", toChannel: channel) 68 | } 69 | break 70 | default: 71 | break 72 | } 73 | configuration?.worldAlignment = parseWorldAlignment(arguments) 74 | return configuration 75 | } 76 | 77 | func parseWorldAlignment(_ arguments: Dictionary) -> ARConfiguration.WorldAlignment { 78 | if let worldAlignment = arguments["worldAlignment"] as? Int { 79 | if worldAlignment == 0 { 80 | return .gravity 81 | } 82 | if worldAlignment == 1 { 83 | return .gravityAndHeading 84 | } 85 | } 86 | return .camera 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ios/Classes/FlutterArkitView.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ARKit 3 | 4 | class FlutterArkitView: NSObject, FlutterPlatformView { 5 | let sceneView: ARSCNView 6 | let channel: FlutterMethodChannel 7 | 8 | var forceTapOnCenter: Bool = false 9 | var configuration: ARConfiguration? = nil 10 | 11 | init(withFrame frame: CGRect, viewIdentifier viewId: Int64, messenger msg: FlutterBinaryMessenger) { 12 | self.sceneView = ARSCNView(frame: frame) 13 | self.channel = FlutterMethodChannel(name: "arkit_\(viewId)", binaryMessenger: msg) 14 | 15 | super.init() 16 | 17 | self.sceneView.delegate = self 18 | self.channel.setMethodCallHandler(self.onMethodCalled) 19 | } 20 | 21 | func view() -> UIView { return sceneView } 22 | 23 | func onMethodCalled(_ call :FlutterMethodCall, _ result:FlutterResult) { 24 | let arguments = call.arguments as? Dictionary 25 | 26 | if configuration == nil && call.method != "init" { 27 | logPluginError("plugin is not initialized properly", toChannel: channel) 28 | result(nil) 29 | return 30 | } 31 | 32 | switch call.method { 33 | case "init": 34 | initalize(arguments!, result) 35 | result(nil) 36 | break 37 | case "addARKitNode": 38 | onAddNode(arguments!) 39 | result(nil) 40 | break 41 | case "removeARKitNode": 42 | onRemoveNode(arguments!) 43 | result(nil) 44 | break 45 | case "removeARKitAnchor": 46 | onRemoveAnchor(arguments!) 47 | result(nil) 48 | break 49 | case "getNodeBoundingBox": 50 | onGetNodeBoundingBox(arguments!, result) 51 | break 52 | case "transformationChanged": 53 | onTransformChanged(arguments!) 54 | result(nil) 55 | break 56 | case "isHiddenChanged": 57 | onIsHiddenChanged(arguments!) 58 | result(nil) 59 | break 60 | case "updateSingleProperty": 61 | onUpdateSingleProperty(arguments!) 62 | result(nil) 63 | break 64 | case "updateMaterials": 65 | onUpdateMaterials(arguments!) 66 | result(nil) 67 | break 68 | case "performHitTest": 69 | onPerformHitTest(arguments!, result) 70 | break 71 | case "updateFaceGeometry": 72 | onUpdateFaceGeometry(arguments!) 73 | result(nil) 74 | break 75 | case "getLightEstimate": 76 | onGetLightEstimate(result) 77 | result(nil) 78 | break 79 | case "projectPoint": 80 | onProjectPoint(arguments!, result) 81 | break 82 | case "cameraProjectionMatrix": 83 | onCameraProjectionMatrix(result) 84 | break 85 | case "pointOfViewTransform": 86 | onPointOfViewTransform(result) 87 | break 88 | case "playAnimation": 89 | onPlayAnimation(arguments!) 90 | result(nil) 91 | break 92 | case "stopAnimation": 93 | onStopAnimation(arguments!) 94 | result(nil) 95 | break 96 | case "dispose": 97 | onDispose(result) 98 | result(nil) 99 | break 100 | case "cameraEulerAngles": 101 | onCameraEulerAngles(result) 102 | break 103 | default: 104 | result(FlutterMethodNotImplemented) 105 | break 106 | } 107 | } 108 | 109 | func onDispose(_ result:FlutterResult) { 110 | sceneView.session.pause() 111 | self.channel.setMethodCallHandler(nil) 112 | result(nil) 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /ios/Classes/GeometryBuilders/Geometries.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | func createSphere(_ arguments: Dictionary) -> SCNSphere { 4 | let radius = arguments["radius"] as! Double 5 | return SCNSphere(radius: CGFloat(radius)) 6 | } 7 | 8 | func createPlane(_ arguments: Dictionary) -> SCNPlane { 9 | let width = arguments["width"] as! Double 10 | let height = arguments["height"] as! Double 11 | let widthSegmentCount = arguments["widthSegmentCount"] as! Int 12 | let heightSegmentCount = arguments["heightSegmentCount"] as! Int 13 | 14 | let plane = SCNPlane(width: CGFloat(width), height: CGFloat(height)) 15 | plane.widthSegmentCount = widthSegmentCount 16 | plane.heightSegmentCount = heightSegmentCount 17 | return plane 18 | } 19 | 20 | func createText(_ arguments: Dictionary) -> SCNText { 21 | let extrusionDepth = arguments["extrusionDepth"] as! Double 22 | return SCNText(string: arguments["text"], extrusionDepth: CGFloat(extrusionDepth)) 23 | } 24 | 25 | func createBox(_ arguments: Dictionary) -> SCNBox { 26 | let width = arguments["width"] as! Double 27 | let height = arguments["height"] as! Double 28 | let length = arguments["length"] as! Double 29 | let chamferRadius = arguments["chamferRadius"] as! Double 30 | 31 | return SCNBox(width: CGFloat(width), height: CGFloat(height), length: CGFloat(length), chamferRadius: CGFloat(chamferRadius)) 32 | } 33 | 34 | func createLine(_ arguments: Dictionary) -> SCNGeometry { 35 | let fromVector = deserizlieVector3(arguments["fromVector"] as! Array) 36 | let toVector = deserizlieVector3(arguments["toVector"] as! Array) 37 | let source = SCNGeometrySource(vertices: [fromVector, toVector]) 38 | 39 | let indices: [UInt8] = [0,1] 40 | let element = SCNGeometryElement(indices: indices, primitiveType: .line) 41 | 42 | return SCNGeometry(sources: [source], elements: [element]) 43 | } 44 | 45 | func createCylinder(_ arguments: Dictionary) -> SCNCylinder { 46 | let radius = arguments["radius"] as! Double 47 | let height = arguments["height"] as! Double 48 | return SCNCylinder(radius: CGFloat(radius), height: CGFloat(height)) 49 | } 50 | 51 | func createCone(_ arguments: Dictionary) -> SCNCone { 52 | let topRadius = arguments["topRadius"] as! Double 53 | let bottomRadius = arguments["bottomRadius"] as! Double 54 | let height = arguments["height"] as! Double 55 | return SCNCone(topRadius: CGFloat(topRadius), bottomRadius: CGFloat(bottomRadius), height: CGFloat(height)) 56 | } 57 | 58 | func createPyramid(_ arguments: Dictionary) -> SCNPyramid { 59 | let width = arguments["width"] as! Double 60 | let height = arguments["height"] as! Double 61 | let length = arguments["length"] as! Double 62 | return SCNPyramid(width: CGFloat(width), height: CGFloat(height), length: CGFloat(length)) 63 | } 64 | 65 | func createTube(_ arguments: Dictionary) -> SCNTube { 66 | let innerRadius = arguments["innerRadius"] as! Double 67 | let outerRadius = arguments["outerRadius"] as! Double 68 | let height = arguments["height"] as! Double 69 | return SCNTube(innerRadius: CGFloat(innerRadius), outerRadius: CGFloat(outerRadius), height: CGFloat(height)) 70 | } 71 | 72 | func createTorus(_ arguments: Dictionary) -> SCNTorus { 73 | let ringRadius = arguments["ringRadius"] as! Double 74 | let pipeRadius = arguments["pipeRadius"] as! Double 75 | return SCNTorus(ringRadius: CGFloat(ringRadius), pipeRadius: CGFloat(pipeRadius)) 76 | } 77 | 78 | func createCapsule(_ arguments: Dictionary) -> SCNCapsule { 79 | let capRadius = arguments["capRadius"] as! Double 80 | let height = arguments["height"] as! Double 81 | return SCNCapsule(capRadius: CGFloat(capRadius), height: CGFloat(height)) 82 | } 83 | 84 | #if !DISABLE_TRUEDEPTH_API 85 | func createFace(_ device: MTLDevice?) -> ARSCNFaceGeometry { 86 | return ARSCNFaceGeometry(device: device!)! 87 | } 88 | #endif 89 | -------------------------------------------------------------------------------- /ios/Classes/GeometryBuilders/GeometryBuilder.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | func createGeometry(_ arguments: Dictionary?, withDevice device: MTLDevice?) -> SCNGeometry? { 4 | if let arguments = arguments { 5 | 6 | var geometry: SCNGeometry? 7 | let dartType = arguments["dartType"] as! String 8 | 9 | switch dartType { 10 | case "ARKitSphere": 11 | geometry = createSphere(arguments) 12 | break 13 | case "ARKitPlane": 14 | geometry = createPlane(arguments) 15 | break 16 | case "ARKitText": 17 | geometry = createText(arguments) 18 | break 19 | case "ARKitBox": 20 | geometry = createBox(arguments) 21 | break 22 | case "ARKitLine": 23 | geometry = createLine(arguments) 24 | break 25 | case "ARKitCylinder": 26 | geometry = createCylinder(arguments) 27 | break 28 | case "ARKitCone": 29 | geometry = createCone(arguments) 30 | break 31 | case "ARKitPyramid": 32 | geometry = createPyramid(arguments) 33 | break 34 | case "ARKitTube": 35 | geometry = createTube(arguments) 36 | break 37 | case "ARKitTorus": 38 | geometry = createTorus(arguments) 39 | break 40 | case "ARKitCapsule": 41 | geometry = createCapsule(arguments) 42 | break 43 | case "ARKitFace": 44 | #if !DISABLE_TRUEDEPTH_API 45 | geometry = createFace(device) 46 | #else 47 | // error 48 | #endif 49 | break 50 | default: 51 | // error 52 | break 53 | } 54 | 55 | if let materials = arguments["materials"] as? Array> { 56 | geometry?.materials = parseMaterials(materials) 57 | } 58 | 59 | return geometry 60 | } else { 61 | return nil 62 | } 63 | } 64 | 65 | func parseMaterials(_ array: Array>) -> Array { 66 | return array.map { parseMaterial($0) } 67 | } 68 | 69 | fileprivate func parseMaterial(_ dict: Dictionary) -> SCNMaterial { 70 | let material = SCNMaterial() 71 | 72 | material.shininess = CGFloat(dict["shininess"] as! Double) 73 | material.transparency = CGFloat(dict["transparency"] as! Double) 74 | material.lightingModel = parseLightingModel(dict["lightingModelName"] as? Int) 75 | material.fillMode = SCNFillMode(rawValue: UInt(dict["fillMode"] as! Int))! 76 | material.cullMode = SCNCullMode(rawValue: dict["cullMode"] as! Int)! 77 | material.transparencyMode = SCNTransparencyMode(rawValue: dict["transparencyMode"] as! Int)! 78 | material.locksAmbientWithDiffuse = dict["locksAmbientWithDiffuse"] as! Bool 79 | material.writesToDepthBuffer = dict["writesToDepthBuffer"] as! Bool 80 | material.colorBufferWriteMask = parseColorBufferWriteMask(dict["colorBufferWriteMask"] as? Int) 81 | material.blendMode = SCNBlendMode.init(rawValue: dict["blendMode"] as! Int)! 82 | material.isDoubleSided = dict["doubleSided"] as! Bool 83 | 84 | material.diffuse.contents = parsePropertyContents(dict["diffuse"]) 85 | material.ambient.contents = parsePropertyContents(dict["ambient"]) 86 | material.specular.contents = parsePropertyContents(dict["specular"]) 87 | material.emission.contents = parsePropertyContents(dict["emission"]) 88 | material.transparent.contents = parsePropertyContents(dict["transparent"]) 89 | material.reflective.contents = parsePropertyContents(dict["reflective"]) 90 | material.multiply.contents = parsePropertyContents(dict["multiply"]) 91 | material.normal.contents = parsePropertyContents(dict["normal"]) 92 | material.displacement.contents = parsePropertyContents(dict["displacement"]) 93 | material.ambientOcclusion.contents = parsePropertyContents(dict["ambientOcclusion"]) 94 | material.selfIllumination.contents = parsePropertyContents(dict["selfIllumination"]) 95 | material.metalness.contents = parsePropertyContents(dict["metalness"]) 96 | material.roughness.contents = parsePropertyContents(dict["roughness"]) 97 | 98 | return material 99 | } 100 | 101 | fileprivate func parseLightingModel(_ mode: Int?) -> SCNMaterial.LightingModel { 102 | switch mode { 103 | case 0: 104 | return .phong 105 | case 1: 106 | return .blinn 107 | case 2: 108 | return .lambert 109 | case 3: 110 | return .constant 111 | case 4: 112 | return .physicallyBased 113 | case 5: 114 | if #available(iOS 13.0, *) { 115 | return .shadowOnly 116 | } else { 117 | // error 118 | return .blinn 119 | } 120 | default: 121 | return .blinn 122 | } 123 | } 124 | 125 | fileprivate func parseColorBufferWriteMask(_ mode: Int?) -> SCNColorMask { 126 | switch mode { 127 | case 0: 128 | return .init() 129 | case 8: 130 | return .red 131 | case 4: 132 | return .green 133 | case 2: 134 | return .blue 135 | case 1: 136 | return .alpha 137 | case 15: 138 | return .all 139 | default: 140 | return .all 141 | } 142 | } 143 | 144 | fileprivate func parsePropertyContents(_ dict: Any?) -> Any? { 145 | guard let dict = dict as? Dictionary else { 146 | return nil 147 | } 148 | 149 | if let imageName = dict["image"] as? String { 150 | return getImageByName(imageName) 151 | } 152 | if let color = dict["color"] as? Int { 153 | return UIColor(rgb: UInt(color)) 154 | } 155 | if let url = dict["url"] as? String { 156 | return getImageByName(url) 157 | } 158 | return nil 159 | } 160 | -------------------------------------------------------------------------------- /ios/Classes/NodeBuilder.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | func createNode(_ geometry: SCNGeometry?, fromDict dict: Dictionary, forDevice device: MTLDevice?) -> SCNNode { 4 | let dartType = dict["dartType"] as! String 5 | 6 | let node = dartType == "ARKitReferenceNode" 7 | ? createReferenceNode(dict) 8 | : SCNNode(geometry: geometry) 9 | 10 | if let transform = dict["transform"] as? Array { 11 | node.transform = deserializeMatrix4(transform) 12 | } 13 | 14 | if let name = dict["name"] as? String { 15 | node.name = name 16 | } 17 | 18 | if let physicsBody = dict["physicsBody"] as? Dictionary { 19 | node.physicsBody = createPhysicsBody(physicsBody, forDevice: device) 20 | } 21 | 22 | if let light = dict["light"] as? Dictionary { 23 | node.light = createLight(light) 24 | } 25 | 26 | if let renderingOrder = dict["renderingOrder"] as? Int { 27 | node.renderingOrder = renderingOrder 28 | } 29 | 30 | if let isHidden = dict["isHidden"] as? Bool { 31 | node.isHidden = isHidden 32 | } 33 | 34 | return node 35 | } 36 | 37 | fileprivate func createReferenceNode(_ dict: Dictionary) -> SCNReferenceNode { 38 | let url = dict["url"] as! String 39 | var referenceUrl: URL 40 | if let bundleURL = Bundle.main.url(forResource: url, withExtension: nil){ 41 | referenceUrl = bundleURL 42 | }else{ 43 | referenceUrl = URL(fileURLWithPath: url) 44 | } 45 | let node = SCNReferenceNode(url: referenceUrl) 46 | node?.load() 47 | return node! 48 | } 49 | 50 | fileprivate func createPhysicsBody(_ dict: Dictionary, forDevice device: MTLDevice?) -> SCNPhysicsBody { 51 | var shape: SCNPhysicsShape? 52 | if let shapeDict = dict["shape"] as? Dictionary, 53 | let shapeGeometry = shapeDict["geometry"] as? Dictionary { 54 | let geometry = createGeometry(shapeGeometry, withDevice: device) 55 | shape = SCNPhysicsShape(geometry: geometry!, options: nil) 56 | } 57 | let type = dict["type"] as! Int 58 | let bodyType = SCNPhysicsBodyType(rawValue: type) 59 | let physicsBody = SCNPhysicsBody(type: bodyType!, shape: shape) 60 | if let categoryBitMack = dict["categoryBitMask"] as? Int { 61 | physicsBody.categoryBitMask = categoryBitMack 62 | } 63 | return physicsBody 64 | } 65 | 66 | fileprivate func createLight(_ dict: Dictionary) -> SCNLight { 67 | let light = SCNLight() 68 | if let type = dict["type"] as? Int { 69 | switch type { 70 | case 0: 71 | light.type = .ambient 72 | break 73 | case 1: 74 | light.type = .omni 75 | break 76 | case 2: 77 | light.type = .directional 78 | break 79 | case 3: 80 | light.type = .spot 81 | break 82 | case 4: 83 | light.type = .IES 84 | break 85 | case 5: 86 | light.type = .probe 87 | break 88 | case 6: 89 | if #available(iOS 13.0, *) { 90 | light.type = .area 91 | } else { 92 | // error 93 | light.type = .omni 94 | } 95 | break 96 | default: 97 | light.type = .omni 98 | break 99 | } 100 | } else { 101 | light.type = .omni 102 | } 103 | if let temperature = dict["temperature"] as? Double { 104 | light.temperature = CGFloat(temperature) 105 | } 106 | if let intensity = dict["intensity"] as? Double { 107 | light.intensity = CGFloat(intensity) 108 | } 109 | if let spotInnerAngle = dict["spotInnerAngle"] as? Double { 110 | light.spotInnerAngle = CGFloat(spotInnerAngle) 111 | } 112 | if let spotOuterAngle = dict["spotOuterAngle"] as? Double { 113 | light.spotOuterAngle = CGFloat(spotOuterAngle) 114 | } 115 | if let color = dict["color"] as? Int { 116 | light.color = UIColor(rgb: UInt(color)) 117 | } 118 | return light 119 | } 120 | -------------------------------------------------------------------------------- /ios/Classes/Serializers/AnchorSerializer.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ARKit 3 | 4 | func serializeAnchor(_ anchor: ARAnchor) -> Dictionary { 5 | var params = [ 6 | "identifier": anchor.identifier.uuidString, 7 | "transform": serializeMatrix(anchor.transform) 8 | ] as [String : Any] 9 | 10 | if let planeAnchor = anchor as? ARPlaneAnchor { 11 | params = serializePlaneAnchor(planeAnchor, params) 12 | } 13 | 14 | if #available(iOS 11.3, *) { 15 | if let imageAnchor = anchor as? ARImageAnchor { 16 | params = serializeImageAnchor(imageAnchor, params) 17 | } 18 | } 19 | 20 | #if !DISABLE_TRUEDEPTH_API 21 | if #available(iOS 12.0, *) { 22 | if let faceAnchor = anchor as? ARFaceAnchor { 23 | params = serializeFaceAnchor(faceAnchor, params) 24 | } 25 | } 26 | #endif 27 | 28 | if #available(iOS 13.0, *) { 29 | if let bodyAnchor = anchor as? ARBodyAnchor { 30 | params = serializeBodyAnchor(bodyAnchor, params) 31 | } 32 | } 33 | 34 | return params 35 | } 36 | 37 | fileprivate func serializePlaneAnchor(_ anchor: ARPlaneAnchor, _ params:[String : Any]) -> [String : Any]{ 38 | var params = params 39 | params["anchorType"] = "planeAnchor" 40 | params["center"] = serializeArray(anchor.center) 41 | params["extent"] = serializeArray(anchor.extent) 42 | return params 43 | } 44 | 45 | @available(iOS 11.3, *) 46 | fileprivate func serializeImageAnchor(_ anchor: ARImageAnchor, _ params:[String : Any]) -> [String : Any]{ 47 | var params = params 48 | params["anchorType"] = "imageAnchor" 49 | 50 | if let referenceImageName = anchor.referenceImage.name { 51 | params["referenceImageName"] = referenceImageName 52 | } 53 | params["isTracked"] = anchor.isTracked 54 | params["referenceImagePhysicalSize"] = [anchor.referenceImage.physicalSize.width, anchor.referenceImage.physicalSize.height] 55 | return params 56 | } 57 | 58 | #if !DISABLE_TRUEDEPTH_API 59 | @available(iOS 12.0, *) 60 | fileprivate func serializeFaceAnchor(_ anchor: ARFaceAnchor, _ params:[String : Any]) -> [String : Any]{ 61 | var params = params 62 | params["anchorType"] = "faceAnchor" 63 | params["isTracked"] = anchor.isTracked 64 | params["leftEyeTransform"] = serializeMatrix(anchor.leftEyeTransform) 65 | params["rightEyeTransform"] = serializeMatrix(anchor.rightEyeTransform) 66 | params["blendShapes"] = anchor.blendShapes 67 | return params 68 | } 69 | #endif 70 | 71 | @available(iOS 13.0, *) 72 | fileprivate func serializeBodyAnchor(_ anchor: ARBodyAnchor, _ params:[String : Any]) -> [String : Any]{ 73 | var params = params 74 | params["anchorType"] = "bodyAnchor" 75 | params["isTracked"] = anchor.isTracked 76 | 77 | let modelTransforms = [ 78 | "root": serializeMatrix(anchor.skeleton.modelTransform(for: .root) ?? simd_float4x4.init()), 79 | "head": serializeMatrix(anchor.skeleton.modelTransform(for: .head) ?? simd_float4x4.init()), 80 | "leftHand": serializeMatrix(anchor.skeleton.modelTransform(for: .leftHand) ?? simd_float4x4.init()), 81 | "rightHand": serializeMatrix(anchor.skeleton.modelTransform(for: .rightHand) ?? simd_float4x4.init()), 82 | "leftFoot": serializeMatrix(anchor.skeleton.modelTransform(for: .leftFoot) ?? simd_float4x4.init()), 83 | "rightFoot": serializeMatrix(anchor.skeleton.modelTransform(for: .rightFoot) ?? simd_float4x4.init()), 84 | "leftShoulder": serializeMatrix(anchor.skeleton.modelTransform(for: .leftShoulder) ?? simd_float4x4.init()), 85 | "rightShoulder": serializeMatrix(anchor.skeleton.modelTransform(for: .rightShoulder) ?? simd_float4x4.init()) 86 | ] 87 | let localTransforms = [ 88 | "root": serializeMatrix(anchor.skeleton.localTransform(for: .root) ?? simd_float4x4.init()), 89 | "head": serializeMatrix(anchor.skeleton.localTransform(for: .head) ?? simd_float4x4.init()), 90 | "leftHand": serializeMatrix(anchor.skeleton.localTransform(for: .leftHand) ?? simd_float4x4.init()), 91 | "rightHand": serializeMatrix(anchor.skeleton.localTransform(for: .rightHand) ?? simd_float4x4.init()), 92 | "leftFoot": serializeMatrix(anchor.skeleton.localTransform(for: .leftFoot) ?? simd_float4x4.init()), 93 | "rightFoot": serializeMatrix(anchor.skeleton.localTransform(for: .rightFoot) ?? simd_float4x4.init()), 94 | "leftShoulder": serializeMatrix(anchor.skeleton.localTransform(for: .leftShoulder) ?? simd_float4x4.init()), 95 | "rightShoulder": serializeMatrix(anchor.skeleton.localTransform(for: .rightShoulder) ?? simd_float4x4.init()) 96 | ] 97 | let skeleton = [ 98 | "modelTransforms": modelTransforms, 99 | "localTransforms": localTransforms 100 | ] 101 | params["skeleton"] = skeleton 102 | return params 103 | } 104 | -------------------------------------------------------------------------------- /ios/Classes/Serializers/Deserializers.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | func deserizlieVector3(_ coords: Array) -> SCNVector3 { 4 | let point = SCNVector3(coords[0], coords[1], coords[2]) 5 | return point 6 | } 7 | 8 | func deserizlieVector4(_ coords: Array) -> SCNVector4 { 9 | let point = SCNVector4(coords[0], coords[1], coords[2], coords[3]) 10 | return point 11 | } 12 | 13 | func deserializeMatrix4(_ c: Array) -> SCNMatrix4 { 14 | let coords = c.map({ Float(truncating: $0 )}) 15 | let matrix = SCNMatrix4(m11: coords[0], m12: coords[1],m13: coords[2], m14: coords[3], m21: coords[4], m22: coords[5], m23: coords[6], m24: coords[7], m31: coords[8], m32: coords[9], m33: coords[10], m34: coords[11], m41: coords[12], m42: coords[13], m43: coords[14], m44: coords[15]) 16 | return matrix 17 | } 18 | -------------------------------------------------------------------------------- /ios/Classes/Serializers/Serializers.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | func serializeArray(_ array: simd_float2) -> Array { 4 | return [array[0], array[1]] 5 | } 6 | 7 | func serializeArray(_ array: simd_float3) -> Array { 8 | return [array[0], array[1], array[2]] 9 | } 10 | 11 | func serializeArray(_ array: simd_float4) -> Array { 12 | return [array[0], array[1], array[2], array[3]] 13 | } 14 | 15 | func serializeVector(_ vector: SCNVector3) -> Array { 16 | return [vector.x, vector.y, vector.z] 17 | } 18 | 19 | func serializeMatrix(_ matrix: simd_float4x4) -> Array { 20 | return [matrix.columns.0, matrix.columns.1, matrix.columns.2, matrix.columns.3].flatMap { serializeArray($0) } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ios/Classes/SwiftArkitPlugin+configurationCheck.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | func checkConfiguration(_ arguments: Any?) -> Bool { 4 | guard let arguments = arguments as? Dictionary, 5 | let configurationType = arguments["configuration"] as? Int else { 6 | return false 7 | } 8 | 9 | switch configurationType { 10 | case 0: 11 | return ARWorldTrackingConfiguration.isSupported 12 | case 1: 13 | #if !DISABLE_TRUEDEPTH_API 14 | return ARFaceTrackingConfiguration.isSupported 15 | #else 16 | return false 17 | #endif 18 | case 2: 19 | if #available(iOS 12.0, *) { 20 | return ARImageTrackingConfiguration.isSupported 21 | } else { 22 | return false 23 | } 24 | case 3: 25 | if #available(iOS 13.0, *) { 26 | return ARBodyTrackingConfiguration.isSupported 27 | } else { 28 | return false 29 | } 30 | default: 31 | return false 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ios/Classes/SwiftArkitPlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import ARKit 4 | 5 | public class SwiftArkitPlugin: NSObject, FlutterPlugin { 6 | public static var registrar:FlutterPluginRegistrar? = nil 7 | 8 | public static func register(with registrar: FlutterPluginRegistrar) { 9 | SwiftArkitPlugin.registrar = registrar 10 | let arkitFactory = FlutterArkitFactory(messenger: registrar.messenger()) 11 | registrar.register(arkitFactory, withId: "arkit") 12 | 13 | let channel = FlutterMethodChannel(name: "arkit_configuration", binaryMessenger: registrar.messenger()) 14 | registrar.addMethodCallDelegate(SwiftArkitPlugin(), channel: channel) 15 | } 16 | 17 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 18 | if (call.method == "checkConfiguration") { 19 | let res = checkConfiguration(call.arguments) 20 | result(res) 21 | } else { 22 | result(FlutterMethodNotImplemented) 23 | } 24 | } 25 | 26 | 27 | } 28 | 29 | class FlutterArkitFactory :NSObject, FlutterPlatformViewFactory { 30 | let messenger: FlutterBinaryMessenger 31 | 32 | init(messenger: FlutterBinaryMessenger) { 33 | self.messenger = messenger 34 | } 35 | 36 | func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView { 37 | let view = FlutterArkitView(withFrame: frame, viewIdentifier: viewId, messenger: self.messenger) 38 | return view 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ios/Classes/Utils/ARHitResultsHelper.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | 3 | func getARHitResultsArray(_ sceneView: ARSCNView, atLocation location: CGPoint) -> Array>{ 4 | let arHitResults = getARHitResults(sceneView, atLocation: location) 5 | let results = convertHitResultsToArray(arHitResults) 6 | return results 7 | } 8 | 9 | fileprivate func getARHitResults(_ sceneView: ARSCNView, atLocation location: CGPoint) -> Array { 10 | var types = ARHitTestResult.ResultType( 11 | [.featurePoint, .estimatedHorizontalPlane, .existingPlane, .existingPlaneUsingExtent]) 12 | 13 | if #available(iOS 11.3, *) { 14 | types.insert(.estimatedVerticalPlane) 15 | types.insert(.existingPlaneUsingGeometry) 16 | } 17 | let results = sceneView.hitTest(location, types: types) 18 | return results 19 | } 20 | 21 | fileprivate func convertHitResultsToArray(_ array : Array) -> Array> { 22 | return array.map {getDictFromHitResult($0) } 23 | } 24 | 25 | fileprivate func getDictFromHitResult(_ result: ARHitTestResult) -> Dictionary { 26 | 27 | var dict = Dictionary(minimumCapacity: 4) 28 | dict["type"] = result.type.rawValue 29 | dict["distance"] = result.distance 30 | dict["localTransform"] = serializeMatrix(result.localTransform) 31 | dict["worldTransform"] = serializeMatrix(result.worldTransform) 32 | 33 | if let anchor = result.anchor { 34 | dict["anchor"] = serializeAnchor(anchor) 35 | } 36 | 37 | return dict 38 | } 39 | -------------------------------------------------------------------------------- /ios/Classes/Utils/ErrorLogger.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | func logPluginError(_ message: String, toChannel channel: FlutterMethodChannel) { 4 | let methodName = Thread.callStackSymbols[1] 5 | channel.invokeMethod("onError", arguments: "\(methodName): \(message)") 6 | } 7 | -------------------------------------------------------------------------------- /ios/Classes/Utils/ImageParser.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | func getImageByName(_ name: String) -> UIImage? { 4 | if let img = UIImage(named: name) { 5 | return img 6 | } 7 | if let path = Bundle.main.path(forResource: SwiftArkitPlugin.registrar!.lookupKey(forAsset: name), ofType: nil) { 8 | return UIImage(named: path) 9 | } 10 | do { 11 | let data = try Data.init(contentsOf: URL.init(string: name)!) 12 | return UIImage(data: data) 13 | } catch { 14 | 15 | } 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /ios/Classes/Utils/ReferenceImagesParser.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import ARKit 3 | 4 | @available(iOS 11.3, *) 5 | func parseReferenceImagesSet(_ images: Array>) -> Set { 6 | let conv = images.compactMap { parseReferenceImage($0) } 7 | return Set(conv) 8 | } 9 | 10 | @available(iOS 11.3, *) 11 | func parseReferenceImage(_ dict: Dictionary) -> ARReferenceImage? { 12 | if let physicalWidth = dict["physicalWidth"] as? Double, 13 | let name = dict["name"] as? String, 14 | let image = getImageByName(name), 15 | let cgImage = image.cgImage { 16 | 17 | let referenceImage = ARReferenceImage(cgImage, orientation: CGImagePropertyOrientation.up, physicalWidth: CGFloat(physicalWidth)) 18 | referenceImage.name = name 19 | return referenceImage 20 | } 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /ios/arkit_plugin.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint arkit_plugin.podspec' to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'arkit_plugin' 7 | s.version = '0.0.1' 8 | s.summary = 'A new flutter plugin project.' 9 | s.description = <<-DESC 10 | A new flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '11.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /lib/arkit_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/light/arkit_light.dart'; 3 | import 'package:arkit_plugin/physics/arkit_physics_body.dart'; 4 | import 'package:arkit_plugin/utils/json_converters.dart'; 5 | import 'package:arkit_plugin/utils/matrix4_ext.dart'; 6 | import 'package:flutter/widgets.dart'; 7 | import 'package:arkit_plugin/utils/random_string.dart' as random_string; 8 | import 'package:vector_math/vector_math_64.dart'; 9 | 10 | /// ARKitNode is the model class for node-tree objects. 11 | /// It encapsulates the position, rotations, and other transforms of a node, which define a coordinate system. 12 | /// The coordinate systems of all the sub-nodes are relative to the one of their parent node. 13 | class ARKitNode { 14 | ARKitNode({ 15 | this.geometry, 16 | this.physicsBody, 17 | this.light, 18 | this.renderingOrder = 0, 19 | bool isHidden = false, 20 | Vector3 position, 21 | Vector3 scale, 22 | Vector4 rotation, 23 | Vector3 eulerAngles, 24 | String name, 25 | Matrix4 transformation, 26 | }) : name = name ?? random_string.randomString(), 27 | isHidden = ValueNotifier(isHidden), 28 | transformNotifier = ValueNotifier(createTransformMatrix( 29 | transformation, position, scale, rotation, eulerAngles)); 30 | 31 | /// Returns the geometry attached to the receiver. 32 | final ARKitGeometry geometry; 33 | 34 | /// Determines the receiver's transform. 35 | /// The transform is the combination of the position, rotation and scale defined below. 36 | /// So when the transform is set, the receiver's position, rotation and scale are changed to match the new transform. 37 | Matrix4 get transform => transformNotifier.value; 38 | 39 | set transform(Matrix4 matrix) { 40 | transformNotifier.value = matrix; 41 | } 42 | 43 | /// Determines the receiver's position. 44 | Vector3 get position => transform.getTranslation(); 45 | 46 | set position(Vector3 value) { 47 | final old = Matrix4.fromFloat64List(transform.storage); 48 | final newT = old.clone(); 49 | newT.setTranslation(value); 50 | transform = newT; 51 | } 52 | 53 | /// Determines the receiver's scale. 54 | Vector3 get scale => transform.matrixScale; 55 | 56 | set scale(Vector3 value) { 57 | transform = 58 | Matrix4.compose(position, Quaternion.fromRotation(rotation), value); 59 | } 60 | 61 | /// Determines the receiver's rotation. 62 | Matrix3 get rotation => transform.getRotation(); 63 | 64 | set rotation(Matrix3 value) { 65 | transform = 66 | Matrix4.compose(position, Quaternion.fromRotation(value), scale); 67 | } 68 | 69 | /// Determines the receiver's euler angles. 70 | /// The order of components in this vector matches the axes of rotation: 71 | /// 1. Pitch (the x component) is the rotation about the node's x-axis (in radians) 72 | /// 2. Yaw (the y component) is the rotation about the node's y-axis (in radians) 73 | /// 3. Roll (the z component) is the rotation about the node's z-axis (in radians) 74 | Vector3 get eulerAngles => transform.matrixEulerAngles; 75 | 76 | set eulerAngles(Vector3 value) { 77 | final old = Matrix4.fromFloat64List(transform.storage); 78 | final newT = old.clone(); 79 | newT.matrixEulerAngles = value; 80 | transform = newT; 81 | } 82 | 83 | final ValueNotifier transformNotifier; 84 | 85 | /// Determines the name of the receiver. 86 | /// Will be autogenerated if not defined. 87 | final String name; 88 | 89 | /// The description of the physics body of the receiver. 90 | final ARKitPhysicsBody physicsBody; 91 | 92 | /// Determines the light attached to the receiver. 93 | final ARKitLight light; 94 | 95 | /// Determines the rendering order of the receiver. 96 | /// Nodes with greater rendering orders are rendered last. 97 | /// Defaults to 0. 98 | final int renderingOrder; 99 | 100 | /// Determines the visibility of the node’s contents. 101 | /// Defaults to false. 102 | final ValueNotifier isHidden; 103 | 104 | static const _boolValueNotifierConverter = ValueNotifierConverter(); 105 | static const _matrixValueNotifierConverter = MatrixValueNotifierConverter(); 106 | 107 | Map toMap() => { 108 | 'dartType': runtimeType.toString(), 109 | 'geometry': geometry?.toJson(), 110 | 'transform': _matrixValueNotifierConverter.toJson(transformNotifier), 111 | 'physicsBody': physicsBody?.toJson(), 112 | 'light': light?.toJson(), 113 | 'name': name, 114 | 'renderingOrder': renderingOrder, 115 | 'isHidden': _boolValueNotifierConverter.toJson(isHidden), 116 | }..removeWhere((String k, dynamic v) => v == null); 117 | } 118 | -------------------------------------------------------------------------------- /lib/arkit_plugin.dart: -------------------------------------------------------------------------------- 1 | export 'package:arkit_plugin/arkit_node.dart'; 2 | export 'package:arkit_plugin/arkit_reference_node.dart'; 3 | export 'package:arkit_plugin/widget/ar_tracking_state.dart'; 4 | export 'package:arkit_plugin/geometries/arkit_anchor.dart'; 5 | export 'package:arkit_plugin/geometries/arkit_box.dart'; 6 | export 'package:arkit_plugin/geometries/arkit_capsule.dart'; 7 | export 'package:arkit_plugin/geometries/arkit_cone.dart'; 8 | export 'package:arkit_plugin/geometries/arkit_cylinder.dart'; 9 | export 'package:arkit_plugin/geometries/arkit_face.dart'; 10 | export 'package:arkit_plugin/geometries/arkit_geometry.dart'; 11 | export 'package:arkit_plugin/geometries/arkit_line.dart'; 12 | export 'package:arkit_plugin/geometries/arkit_plane.dart'; 13 | export 'package:arkit_plugin/geometries/arkit_pyramid.dart'; 14 | export 'package:arkit_plugin/geometries/arkit_sphere.dart'; 15 | export 'package:arkit_plugin/geometries/arkit_text.dart'; 16 | export 'package:arkit_plugin/geometries/arkit_torus.dart'; 17 | export 'package:arkit_plugin/geometries/arkit_tube.dart'; 18 | export 'package:arkit_plugin/geometries/material/arkit_blend_mode.dart'; 19 | export 'package:arkit_plugin/geometries/material/arkit_color_mask.dart'; 20 | export 'package:arkit_plugin/geometries/material/arkit_cull_mode.dart'; 21 | export 'package:arkit_plugin/geometries/material/arkit_fill_mode.dart'; 22 | export 'package:arkit_plugin/geometries/material/arkit_lighting_model.dart'; 23 | export 'package:arkit_plugin/geometries/material/arkit_material.dart'; 24 | export 'package:arkit_plugin/geometries/material/arkit_material_property.dart'; 25 | export 'package:arkit_plugin/geometries/material/arkit_transparency_mode.dart'; 26 | export 'package:arkit_plugin/hit/arkit_hit_test_result.dart'; 27 | export 'package:arkit_plugin/hit/arkit_hit_test_result_type.dart'; 28 | export 'package:arkit_plugin/hit/arkit_node_pan_result.dart'; 29 | export 'package:arkit_plugin/hit/arkit_node_pinch_result.dart'; 30 | export 'package:arkit_plugin/hit/arkit_node_rotation_result.dart'; 31 | export 'package:arkit_plugin/light/arkit_light.dart'; 32 | export 'package:arkit_plugin/light/arkit_light_estimate.dart'; 33 | export 'package:arkit_plugin/light/arkit_light_type.dart'; 34 | export 'package:arkit_plugin/physics/arkit_physics_body.dart'; 35 | export 'package:arkit_plugin/physics/arkit_physics_body_type.dart'; 36 | export 'package:arkit_plugin/physics/arkit_physics_shape.dart'; 37 | export 'package:arkit_plugin/widget/arkit_arplane_detection.dart'; 38 | export 'package:arkit_plugin/widget/arkit_configuration.dart'; 39 | export 'package:arkit_plugin/widget/arkit_scene_view.dart'; 40 | export 'package:arkit_plugin/widget/arkit_reference_image.dart'; 41 | export 'package:arkit_plugin/widget/arkit_world_alignment.dart'; 42 | 43 | import 'package:arkit_plugin/widget/arkit_configuration.dart'; 44 | import 'package:flutter/services.dart'; 45 | 46 | class ARKitPlugin { 47 | static const MethodChannel _channel = MethodChannel('arkit_configuration'); 48 | 49 | ARKitPlugin._(); 50 | 51 | static Future checkConfiguration(ARKitConfiguration configuration) { 52 | return _channel.invokeMethod('checkConfiguration', { 53 | 'configuration': configuration.index, 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/arkit_reference_node.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/arkit_node.dart'; 2 | import 'package:arkit_plugin/light/arkit_light.dart'; 3 | import 'package:arkit_plugin/physics/arkit_physics_body.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:vector_math/vector_math_64.dart'; 6 | 7 | /// Node that references an external serialized node graph. 8 | class ARKitReferenceNode extends ARKitNode { 9 | ARKitReferenceNode({ 10 | @required this.url, 11 | ARKitPhysicsBody physicsBody, 12 | ARKitLight light, 13 | Vector3 position, 14 | Vector3 scale, 15 | Vector3 eulerAngles, 16 | String name, 17 | int renderingOrder, 18 | bool isHidden, 19 | }) : super( 20 | physicsBody: physicsBody, 21 | light: light, 22 | position: position, 23 | scale: scale, 24 | eulerAngles: eulerAngles, 25 | name: name, 26 | renderingOrder: renderingOrder, 27 | isHidden: isHidden, 28 | ); 29 | 30 | /// URL location of the Node 31 | /// Defaults to path from Main Bundle 32 | /// If path from main bundle fails, will search as full file path 33 | final String url; 34 | 35 | @override 36 | Map toMap() => { 37 | 'url': url, 38 | }..addAll(super.toMap()); 39 | } 40 | -------------------------------------------------------------------------------- /lib/geometries/arkit_anchor.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_face.dart'; 2 | import 'package:arkit_plugin/geometries/arkit_skeleton.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:json_annotation/json_annotation.dart'; 5 | import 'package:vector_math/vector_math_64.dart'; 6 | 7 | part 'arkit_anchor.g.dart'; 8 | 9 | /// Object representing a physical location and orientation in 3D space. 10 | abstract class ARKitAnchor { 11 | const ARKitAnchor( 12 | this.nodeName, 13 | this.identifier, 14 | this.transform, 15 | ); 16 | 17 | factory ARKitAnchor.fromJson(Map arguments) { 18 | final type = arguments['anchorType'].toString(); 19 | switch (type) { 20 | case 'planeAnchor': 21 | return ARKitPlaneAnchor.fromJson(arguments); 22 | case 'imageAnchor': 23 | return ARKitImageAnchor.fromJson(arguments); 24 | case 'faceAnchor': 25 | return ARKitFaceAnchor.fromJson(arguments); 26 | case 'bodyAnchor': 27 | return ARKitBodyAnchor.fromJson(arguments); 28 | } 29 | return ARKitUnkownAnchor.fromJson(arguments); 30 | } 31 | 32 | /// Represents the name of the node anchor attached to. 33 | final String nodeName; 34 | 35 | /// Unique identifier of the anchor. 36 | final String identifier; 37 | 38 | /// The transformation matrix that defines the anchor’s rotation, translation and scale in world coordinates. 39 | @MatrixConverter() 40 | final Matrix4 transform; 41 | 42 | Map toJson(); 43 | } 44 | 45 | /// The anchor of this type is not supported by the plugin yet. 46 | @JsonSerializable() 47 | class ARKitUnkownAnchor extends ARKitAnchor { 48 | const ARKitUnkownAnchor( 49 | this.anchorType, 50 | String nodeName, 51 | String identifier, 52 | Matrix4 transform, 53 | ) : super(nodeName, identifier, transform); 54 | 55 | final String anchorType; 56 | 57 | static ARKitUnkownAnchor fromJson(Map json) => 58 | _$ARKitUnkownAnchorFromJson(json); 59 | 60 | @override 61 | Map toJson() => _$ARKitUnkownAnchorToJson(this); 62 | } 63 | 64 | /// An anchor representing a planar surface in the world. 65 | /// Planes are defined in the X and Z direction, where Y is the surface’s normal. 66 | @JsonSerializable() 67 | class ARKitPlaneAnchor extends ARKitAnchor { 68 | const ARKitPlaneAnchor( 69 | this.center, 70 | this.extent, 71 | String nodeName, 72 | String identifier, 73 | Matrix4 transform, 74 | ) : super( 75 | nodeName, 76 | identifier, 77 | transform, 78 | ); 79 | 80 | /// The center of the plane in the anchor’s coordinate space. 81 | @Vector3Converter() 82 | final Vector3 center; 83 | 84 | /// The extent of the plane in the anchor’s coordinate space. 85 | @Vector3Converter() 86 | final Vector3 extent; 87 | 88 | static ARKitPlaneAnchor fromJson(Map json) => 89 | _$ARKitPlaneAnchorFromJson(json); 90 | 91 | @override 92 | Map toJson() => _$ARKitPlaneAnchorToJson(this); 93 | } 94 | 95 | /// An anchor representing an image in the world. 96 | @JsonSerializable() 97 | class ARKitImageAnchor extends ARKitAnchor { 98 | const ARKitImageAnchor( 99 | this.referenceImageName, 100 | this.referenceImagePhysicalSize, 101 | this.isTracked, 102 | String nodeName, 103 | String identifier, 104 | Matrix4 transform, 105 | ) : super( 106 | nodeName, 107 | identifier, 108 | transform, 109 | ); 110 | 111 | /// Name of the detected image (might be null). 112 | final String referenceImageName; 113 | 114 | @Vector2Converter() 115 | final Vector2 referenceImagePhysicalSize; 116 | 117 | /// Tracking state of the anchor 118 | /// The isTracked value is used to determine the anchor transform’s validity. When the object being tracked is no longer detected in the 119 | /// camera image, its anchor will return NO for isTracked. 120 | final bool isTracked; 121 | 122 | static ARKitImageAnchor fromJson(Map json) => 123 | _$ARKitImageAnchorFromJson(json); 124 | 125 | @override 126 | Map toJson() => _$ARKitImageAnchorToJson(this); 127 | } 128 | 129 | /// An anchor representing a face and its geometry. 130 | @JsonSerializable() 131 | class ARKitFaceAnchor extends ARKitAnchor { 132 | const ARKitFaceAnchor( 133 | this.geometry, 134 | this.blendShapes, 135 | this.isTracked, 136 | String nodeName, 137 | String identifier, 138 | Matrix4 transform, 139 | this.leftEyeTransform, 140 | this.rightEyeTransform, 141 | ) : super( 142 | nodeName, 143 | identifier, 144 | transform, 145 | ); 146 | 147 | /// The face geometry updated based on the computed blend shapes. 148 | final ARKitFace geometry; 149 | 150 | /// The left eye’s rotation and translation relative to the anchor’s origin. 151 | @MatrixConverter() 152 | final Matrix4 leftEyeTransform; 153 | 154 | /// The right eye’s rotation and translation relative to the anchor’s origin. 155 | @MatrixConverter() 156 | final Matrix4 rightEyeTransform; 157 | 158 | /// A dictionary of blend shape coefficients for each blend shape location. 159 | /// Blend shapes coefficients define the amount of displacement of a neutral shape at a specific location on the face. 160 | final Map blendShapes; 161 | 162 | /// Tracking state of the anchor 163 | /// The isTracked value is used to determine the anchor transform’s validity. When the object being tracked is no longer detected in the 164 | /// camera image, its anchor will return NO for isTracked. 165 | final bool isTracked; 166 | 167 | static ARKitFaceAnchor fromJson(Map json) => 168 | _$ARKitFaceAnchorFromJson(json); 169 | 170 | @override 171 | Map toJson() => _$ARKitFaceAnchorToJson(this); 172 | } 173 | 174 | /// An anchor representing a body in the world. 175 | @JsonSerializable() 176 | class ARKitBodyAnchor extends ARKitAnchor { 177 | ARKitBodyAnchor( 178 | this.skeleton, 179 | this.isTracked, 180 | String nodeName, 181 | String identifier, 182 | Matrix4 transform, 183 | ) : super( 184 | nodeName, 185 | identifier, 186 | transform, 187 | ); 188 | 189 | /// The tracked skeleton in 3D. 190 | /// The default height of this skeleton, measured from lowest to highest joint in standing position, is defined to be 1.71 meters. 191 | final ARKitSkeleton skeleton; 192 | 193 | /// Tracking state of the anchor 194 | /// The isTracked value is used to determine the anchor transform’s validity. When the object being tracked is no longer detected in the 195 | /// camera image, its anchor will return NO for isTracked. 196 | final bool isTracked; 197 | 198 | static ARKitBodyAnchor fromJson(Map json) => 199 | _$ARKitBodyAnchorFromJson(json); 200 | 201 | @override 202 | Map toJson() => _$ARKitBodyAnchorToJson(this); 203 | } 204 | -------------------------------------------------------------------------------- /lib/geometries/arkit_anchor.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_anchor.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitUnkownAnchor _$ARKitUnkownAnchorFromJson(Map json) { 10 | return ARKitUnkownAnchor( 11 | json['anchorType'] as String, 12 | json['nodeName'] as String, 13 | json['identifier'] as String, 14 | const MatrixConverter().fromJson(json['transform'] as List), 15 | ); 16 | } 17 | 18 | Map _$ARKitUnkownAnchorToJson(ARKitUnkownAnchor instance) { 19 | final val = { 20 | 'nodeName': instance.nodeName, 21 | 'identifier': instance.identifier, 22 | }; 23 | 24 | void writeNotNull(String key, dynamic value) { 25 | if (value != null) { 26 | val[key] = value; 27 | } 28 | } 29 | 30 | writeNotNull('transform', const MatrixConverter().toJson(instance.transform)); 31 | val['anchorType'] = instance.anchorType; 32 | return val; 33 | } 34 | 35 | ARKitPlaneAnchor _$ARKitPlaneAnchorFromJson(Map json) { 36 | return ARKitPlaneAnchor( 37 | const Vector3Converter().fromJson(json['center'] as List), 38 | const Vector3Converter().fromJson(json['extent'] as List), 39 | json['nodeName'] as String, 40 | json['identifier'] as String, 41 | const MatrixConverter().fromJson(json['transform'] as List), 42 | ); 43 | } 44 | 45 | Map _$ARKitPlaneAnchorToJson(ARKitPlaneAnchor instance) { 46 | final val = { 47 | 'nodeName': instance.nodeName, 48 | 'identifier': instance.identifier, 49 | }; 50 | 51 | void writeNotNull(String key, dynamic value) { 52 | if (value != null) { 53 | val[key] = value; 54 | } 55 | } 56 | 57 | writeNotNull('transform', const MatrixConverter().toJson(instance.transform)); 58 | writeNotNull('center', const Vector3Converter().toJson(instance.center)); 59 | writeNotNull('extent', const Vector3Converter().toJson(instance.extent)); 60 | return val; 61 | } 62 | 63 | ARKitImageAnchor _$ARKitImageAnchorFromJson(Map json) { 64 | return ARKitImageAnchor( 65 | json['referenceImageName'] as String, 66 | const Vector2Converter() 67 | .fromJson(json['referenceImagePhysicalSize'] as List), 68 | json['isTracked'] as bool, 69 | json['nodeName'] as String, 70 | json['identifier'] as String, 71 | const MatrixConverter().fromJson(json['transform'] as List), 72 | ); 73 | } 74 | 75 | Map _$ARKitImageAnchorToJson(ARKitImageAnchor instance) { 76 | final val = { 77 | 'nodeName': instance.nodeName, 78 | 'identifier': instance.identifier, 79 | }; 80 | 81 | void writeNotNull(String key, dynamic value) { 82 | if (value != null) { 83 | val[key] = value; 84 | } 85 | } 86 | 87 | writeNotNull('transform', const MatrixConverter().toJson(instance.transform)); 88 | val['referenceImageName'] = instance.referenceImageName; 89 | writeNotNull('referenceImagePhysicalSize', 90 | const Vector2Converter().toJson(instance.referenceImagePhysicalSize)); 91 | val['isTracked'] = instance.isTracked; 92 | return val; 93 | } 94 | 95 | ARKitFaceAnchor _$ARKitFaceAnchorFromJson(Map json) { 96 | return ARKitFaceAnchor( 97 | ARKitFace.fromJson(json['geometry'] as Map), 98 | Map.from(json['blendShapes'] as Map), 99 | json['isTracked'] as bool, 100 | json['nodeName'] as String, 101 | json['identifier'] as String, 102 | const MatrixConverter().fromJson(json['transform'] as List), 103 | const MatrixConverter().fromJson(json['leftEyeTransform'] as List), 104 | const MatrixConverter().fromJson(json['rightEyeTransform'] as List), 105 | ); 106 | } 107 | 108 | Map _$ARKitFaceAnchorToJson(ARKitFaceAnchor instance) { 109 | final val = { 110 | 'nodeName': instance.nodeName, 111 | 'identifier': instance.identifier, 112 | }; 113 | 114 | void writeNotNull(String key, dynamic value) { 115 | if (value != null) { 116 | val[key] = value; 117 | } 118 | } 119 | 120 | writeNotNull('transform', const MatrixConverter().toJson(instance.transform)); 121 | val['geometry'] = instance.geometry; 122 | writeNotNull('leftEyeTransform', 123 | const MatrixConverter().toJson(instance.leftEyeTransform)); 124 | writeNotNull('rightEyeTransform', 125 | const MatrixConverter().toJson(instance.rightEyeTransform)); 126 | val['blendShapes'] = instance.blendShapes; 127 | val['isTracked'] = instance.isTracked; 128 | return val; 129 | } 130 | 131 | ARKitBodyAnchor _$ARKitBodyAnchorFromJson(Map json) { 132 | return ARKitBodyAnchor( 133 | ARKitSkeleton.fromJson(json['skeleton'] as Map), 134 | json['isTracked'] as bool, 135 | json['nodeName'] as String, 136 | json['identifier'] as String, 137 | const MatrixConverter().fromJson(json['transform'] as List), 138 | ); 139 | } 140 | 141 | Map _$ARKitBodyAnchorToJson(ARKitBodyAnchor instance) { 142 | final val = { 143 | 'nodeName': instance.nodeName, 144 | 'identifier': instance.identifier, 145 | }; 146 | 147 | void writeNotNull(String key, dynamic value) { 148 | if (value != null) { 149 | val[key] = value; 150 | } 151 | } 152 | 153 | writeNotNull('transform', const MatrixConverter().toJson(instance.transform)); 154 | val['skeleton'] = instance.skeleton; 155 | val['isTracked'] = instance.isTracked; 156 | return val; 157 | } 158 | -------------------------------------------------------------------------------- /lib/geometries/arkit_box.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_box.g.dart'; 8 | 9 | /// ARKitBox represents a box with rectangular sides and optional chamfers. 10 | @JsonSerializable() 11 | class ARKitBox extends ARKitGeometry { 12 | ARKitBox({ 13 | double width = 1, 14 | double height = 1, 15 | double length = 1, 16 | this.chamferRadius = 0, 17 | List materials, 18 | }) : width = ValueNotifier(width), 19 | height = ValueNotifier(height), 20 | length = ValueNotifier(length), 21 | super( 22 | materials: materials, 23 | ); 24 | 25 | /// The width of the box. 26 | /// If the value is less than or equal to 0, the geometry is empty. The default value is 1. 27 | @DoubleValueNotifierConverter() 28 | final ValueNotifier width; 29 | 30 | /// The height of the box. 31 | /// If the value is less than or equal to 0, the geometry is empty. The default value is 1. 32 | @DoubleValueNotifierConverter() 33 | final ValueNotifier height; 34 | 35 | /// The length of the box. 36 | /// If the value is less than or equal to 0, the geometry is empty. The default value is 1. 37 | @DoubleValueNotifierConverter() 38 | final ValueNotifier length; 39 | 40 | /// The chamfer radius. 41 | /// If the value is strictly less than 0, the geometry is empty. The default value is 0. 42 | final double chamferRadius; 43 | 44 | static ARKitBox fromJson(Map json) => 45 | _$ARKitBoxFromJson(json); 46 | 47 | @override 48 | Map toJson() => 49 | _$ARKitBoxToJson(this)..addAll({'dartType': 'ARKitBox'}); 50 | } 51 | -------------------------------------------------------------------------------- /lib/geometries/arkit_box.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_box.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitBox _$ARKitBoxFromJson(Map json) { 10 | return ARKitBox( 11 | width: (json['width'] as num).toDouble(), 12 | height: (json['height'] as num).toDouble(), 13 | length: (json['length'] as num).toDouble(), 14 | chamferRadius: (json['chamferRadius'] as num).toDouble(), 15 | materials: (json['materials'] as List) 16 | .map((e) => ARKitMaterial.fromJson(e as Map)) 17 | .toList(), 18 | ); 19 | } 20 | 21 | Map _$ARKitBoxToJson(ARKitBox instance) { 22 | final val = {}; 23 | 24 | void writeNotNull(String key, dynamic value) { 25 | if (value != null) { 26 | val[key] = value; 27 | } 28 | } 29 | 30 | writeNotNull('materials', 31 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 32 | writeNotNull( 33 | 'width', const DoubleValueNotifierConverter().toJson(instance.width)); 34 | writeNotNull( 35 | 'height', const DoubleValueNotifierConverter().toJson(instance.height)); 36 | writeNotNull( 37 | 'length', const DoubleValueNotifierConverter().toJson(instance.length)); 38 | val['chamferRadius'] = instance.chamferRadius; 39 | return val; 40 | } 41 | -------------------------------------------------------------------------------- /lib/geometries/arkit_capsule.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_capsule.g.dart'; 8 | 9 | /// ARKitCapsule represents a capsule with controllable height and cap radius. 10 | @JsonSerializable() 11 | class ARKitCapsule extends ARKitGeometry { 12 | ARKitCapsule({ 13 | double capRadius = 0.5, 14 | double height = 2, 15 | List materials, 16 | }) : capRadius = ValueNotifier(capRadius), 17 | height = ValueNotifier(height), 18 | super( 19 | materials: materials, 20 | ); 21 | 22 | /// The cap radius of the capsule. 23 | /// If the value is less than or equal to 0, the geometry is empty. 24 | /// The default value is 0.5. 25 | @DoubleValueNotifierConverter() 26 | final ValueNotifier capRadius; 27 | 28 | /// The height of the capsule. 29 | /// If the value is less than or equal to 0, the geometry is empty. 30 | /// The default value is 2. 31 | @DoubleValueNotifierConverter() 32 | final ValueNotifier height; 33 | 34 | static ARKitCapsule fromJson(Map json) => 35 | _$ARKitCapsuleFromJson(json); 36 | 37 | @override 38 | Map toJson() => 39 | _$ARKitCapsuleToJson(this)..addAll({'dartType': 'ARKitCapsule'}); 40 | } 41 | -------------------------------------------------------------------------------- /lib/geometries/arkit_capsule.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_capsule.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitCapsule _$ARKitCapsuleFromJson(Map json) { 10 | return ARKitCapsule( 11 | capRadius: (json['capRadius'] as num).toDouble(), 12 | height: (json['height'] as num).toDouble(), 13 | materials: (json['materials'] as List) 14 | .map((e) => ARKitMaterial.fromJson(e as Map)) 15 | .toList(), 16 | ); 17 | } 18 | 19 | Map _$ARKitCapsuleToJson(ARKitCapsule instance) { 20 | final val = {}; 21 | 22 | void writeNotNull(String key, dynamic value) { 23 | if (value != null) { 24 | val[key] = value; 25 | } 26 | } 27 | 28 | writeNotNull('materials', 29 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 30 | writeNotNull('capRadius', 31 | const DoubleValueNotifierConverter().toJson(instance.capRadius)); 32 | writeNotNull( 33 | 'height', const DoubleValueNotifierConverter().toJson(instance.height)); 34 | return val; 35 | } 36 | -------------------------------------------------------------------------------- /lib/geometries/arkit_cone.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_cone.g.dart'; 8 | 9 | /// ARKitCone represents a cone with controllable height, top radius and bottom radius. 10 | @JsonSerializable() 11 | class ARKitCone extends ARKitGeometry { 12 | ARKitCone({ 13 | double height = 1, 14 | double topRadius = 0, 15 | double bottomRadius = 0.5, 16 | List materials, 17 | }) : height = ValueNotifier(height), 18 | topRadius = ValueNotifier(topRadius), 19 | bottomRadius = ValueNotifier(bottomRadius), 20 | super( 21 | materials: materials, 22 | ); 23 | 24 | /// The height of the cylinder. 25 | /// If the value is less than or equal to 0, the geometry is empty. 26 | /// The default value is 1. 27 | @DoubleValueNotifierConverter() 28 | final ValueNotifier height; 29 | 30 | /// The radius at the top of the cone. 31 | /// If the value is less than or equal to 0, the geometry is empty. 32 | /// The default value is 0. 33 | @DoubleValueNotifierConverter() 34 | final ValueNotifier topRadius; 35 | 36 | /// The radius at the bottom of the cone. 37 | /// If the value is less than or equal to 0, the geometry is empty. 38 | /// The default value is 0.5. 39 | @DoubleValueNotifierConverter() 40 | final ValueNotifier bottomRadius; 41 | 42 | static ARKitCone fromJson(Map json) => 43 | _$ARKitConeFromJson(json); 44 | 45 | @override 46 | Map toJson() => 47 | _$ARKitConeToJson(this)..addAll({'dartType': 'ARKitCone'}); 48 | } 49 | -------------------------------------------------------------------------------- /lib/geometries/arkit_cone.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_cone.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitCone _$ARKitConeFromJson(Map json) { 10 | return ARKitCone( 11 | height: (json['height'] as num).toDouble(), 12 | topRadius: (json['topRadius'] as num).toDouble(), 13 | bottomRadius: (json['bottomRadius'] as num).toDouble(), 14 | materials: (json['materials'] as List) 15 | .map((e) => ARKitMaterial.fromJson(e as Map)) 16 | .toList(), 17 | ); 18 | } 19 | 20 | Map _$ARKitConeToJson(ARKitCone instance) { 21 | final val = {}; 22 | 23 | void writeNotNull(String key, dynamic value) { 24 | if (value != null) { 25 | val[key] = value; 26 | } 27 | } 28 | 29 | writeNotNull('materials', 30 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 31 | writeNotNull( 32 | 'height', const DoubleValueNotifierConverter().toJson(instance.height)); 33 | writeNotNull('topRadius', 34 | const DoubleValueNotifierConverter().toJson(instance.topRadius)); 35 | writeNotNull('bottomRadius', 36 | const DoubleValueNotifierConverter().toJson(instance.bottomRadius)); 37 | return val; 38 | } 39 | -------------------------------------------------------------------------------- /lib/geometries/arkit_cylinder.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_cylinder.g.dart'; 8 | 9 | /// ARKitCylinder represents a cylinder with controllable height and radius. 10 | @JsonSerializable() 11 | class ARKitCylinder extends ARKitGeometry { 12 | ARKitCylinder({ 13 | double height = 1, 14 | double radius = 0.5, 15 | List materials, 16 | }) : height = ValueNotifier(height), 17 | radius = ValueNotifier(radius), 18 | super( 19 | materials: materials, 20 | ); 21 | 22 | /// The height of the cylinder. 23 | /// If the value is less than or equal to 0, the geometry is empty. 24 | /// The default value is 1. 25 | @DoubleValueNotifierConverter() 26 | final ValueNotifier height; 27 | 28 | /// The radius of the cylinder. 29 | /// If the value is less than or equal to 0, the geometry is empty. 30 | /// The default value is 0.5. 31 | @DoubleValueNotifierConverter() 32 | final ValueNotifier radius; 33 | 34 | static ARKitCylinder fromJson(Map json) => 35 | _$ARKitCylinderFromJson(json); 36 | 37 | @override 38 | Map toJson() => 39 | _$ARKitCylinderToJson(this)..addAll({'dartType': 'ARKitCylinder'}); 40 | } 41 | -------------------------------------------------------------------------------- /lib/geometries/arkit_cylinder.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_cylinder.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitCylinder _$ARKitCylinderFromJson(Map json) { 10 | return ARKitCylinder( 11 | height: (json['height'] as num).toDouble(), 12 | radius: (json['radius'] as num).toDouble(), 13 | materials: (json['materials'] as List) 14 | .map((e) => ARKitMaterial.fromJson(e as Map)) 15 | .toList(), 16 | ); 17 | } 18 | 19 | Map _$ARKitCylinderToJson(ARKitCylinder instance) { 20 | final val = {}; 21 | 22 | void writeNotNull(String key, dynamic value) { 23 | if (value != null) { 24 | val[key] = value; 25 | } 26 | } 27 | 28 | writeNotNull('materials', 29 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 30 | writeNotNull( 31 | 'height', const DoubleValueNotifierConverter().toJson(instance.height)); 32 | writeNotNull( 33 | 'radius', const DoubleValueNotifierConverter().toJson(instance.radius)); 34 | return val; 35 | } 36 | -------------------------------------------------------------------------------- /lib/geometries/arkit_face.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:json_annotation/json_annotation.dart'; 5 | 6 | part 'arkit_face.g.dart'; 7 | 8 | /// An object representing the geometry of a face. 9 | /// The face geometry will have a constant number of triangles 10 | /// and vertices, updating only the vertex positions from frame to frame. 11 | @JsonSerializable() 12 | class ARKitFace extends ARKitGeometry { 13 | ARKitFace({ 14 | List materials, 15 | }) : super( 16 | materials: materials, 17 | ); 18 | 19 | static ARKitFace fromJson(Map json) { 20 | if (json == null) { 21 | return ARKitFace(materials: []); 22 | } 23 | return _$ARKitFaceFromJson(json); 24 | } 25 | 26 | @override 27 | Map toJson() => 28 | _$ARKitFaceToJson(this)..addAll({'dartType': 'ARKitFace'}); 29 | } 30 | -------------------------------------------------------------------------------- /lib/geometries/arkit_face.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_face.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitFace _$ARKitFaceFromJson(Map json) { 10 | return ARKitFace( 11 | materials: (json['materials'] as List) 12 | .map((e) => ARKitMaterial.fromJson(e as Map)) 13 | .toList(), 14 | ); 15 | } 16 | 17 | Map _$ARKitFaceToJson(ARKitFace instance) { 18 | final val = {}; 19 | 20 | void writeNotNull(String key, dynamic value) { 21 | if (value != null) { 22 | val[key] = value; 23 | } 24 | } 25 | 26 | writeNotNull('materials', 27 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 28 | return val; 29 | } 30 | -------------------------------------------------------------------------------- /lib/geometries/arkit_geometry.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/arkit_plugin.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | import 'package:meta/meta.dart'; 7 | 8 | part 'arkit_geometry.g.dart'; 9 | 10 | /// ARKitGeometry is an abstract class that represents the geometry that can be attached to a SCNNode. 11 | abstract class ARKitGeometry { 12 | ARKitGeometry({@required List materials}) 13 | : materials = ValueNotifier(materials); 14 | 15 | factory ARKitGeometry.fromJson(Map arguments) { 16 | final type = arguments['geometryType'].toString(); 17 | switch (type) { 18 | case 'box': 19 | return ARKitBox.fromJson(arguments); 20 | case 'capsule': 21 | return ARKitCapsule.fromJson(arguments); 22 | case 'cone': 23 | return ARKitCone.fromJson(arguments); 24 | case 'cylinder': 25 | return ARKitCylinder.fromJson(arguments); 26 | case 'face': 27 | return ARKitFace.fromJson(arguments); 28 | case 'line': 29 | return ARKitLine.fromJson(arguments); 30 | case 'plane': 31 | return ARKitPlane.fromJson(arguments); 32 | case 'pyramid': 33 | return ARKitPyramid.fromJson(arguments); 34 | case 'sphere': 35 | return ARKitSphere.fromJson(arguments); 36 | case 'text': 37 | return ARKitText.fromJson(arguments); 38 | case 'torus': 39 | return ARKitTorus.fromJson(arguments); 40 | case 'tube': 41 | return ARKitTube.fromJson(arguments); 42 | } 43 | return ARKitUnkownGeometry.fromJson(arguments); 44 | } 45 | 46 | /// Specifies the receiver's materials array. 47 | /// Each geometry element can be rendered using a different material. 48 | /// The index of the material used for a geometry element is equal to the index of that element modulo the number of materials. 49 | @ListMaterialsValueNotifierConverter() 50 | final ValueNotifier> materials; 51 | 52 | Map toJson(); 53 | } 54 | 55 | @JsonSerializable() 56 | class ARKitUnkownGeometry extends ARKitGeometry { 57 | ARKitUnkownGeometry(this.geometryType); 58 | 59 | final String geometryType; 60 | 61 | static ARKitUnkownGeometry fromJson(Map json) => 62 | _$ARKitUnkownGeometryFromJson(json); 63 | 64 | @override 65 | Map toJson() => _$ARKitUnkownGeometryToJson(this); 66 | } 67 | -------------------------------------------------------------------------------- /lib/geometries/arkit_geometry.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_geometry.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitUnkownGeometry _$ARKitUnkownGeometryFromJson(Map json) { 10 | return ARKitUnkownGeometry( 11 | json['geometryType'] as String, 12 | ); 13 | } 14 | 15 | Map _$ARKitUnkownGeometryToJson( 16 | ARKitUnkownGeometry instance) => 17 | { 18 | 'geometryType': instance.geometryType, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/geometries/arkit_line.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:json_annotation/json_annotation.dart'; 5 | import 'package:meta/meta.dart'; 6 | import 'package:vector_math/vector_math_64.dart'; 7 | 8 | part 'arkit_line.g.dart'; 9 | 10 | /// Represents a line between 2 vectors 11 | @JsonSerializable() 12 | class ARKitLine extends ARKitGeometry { 13 | ARKitLine({ 14 | @required this.fromVector, 15 | @required this.toVector, 16 | List materials, 17 | }) : super( 18 | materials: materials, 19 | ); 20 | 21 | /// Line initial vector position 22 | @Vector3Converter() 23 | final Vector3 fromVector; 24 | 25 | /// Line final vector positon 26 | @Vector3Converter() 27 | final Vector3 toVector; 28 | 29 | static ARKitLine fromJson(Map json) => 30 | _$ARKitLineFromJson(json); 31 | 32 | @override 33 | Map toJson() => 34 | _$ARKitLineToJson(this)..addAll({'dartType': 'ARKitLine'}); 35 | } 36 | -------------------------------------------------------------------------------- /lib/geometries/arkit_line.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_line.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitLine _$ARKitLineFromJson(Map json) { 10 | return ARKitLine( 11 | fromVector: const Vector3Converter().fromJson(json['fromVector'] as List), 12 | toVector: const Vector3Converter().fromJson(json['toVector'] as List), 13 | materials: (json['materials'] as List) 14 | .map((e) => ARKitMaterial.fromJson(e as Map)) 15 | .toList(), 16 | ); 17 | } 18 | 19 | Map _$ARKitLineToJson(ARKitLine instance) { 20 | final val = {}; 21 | 22 | void writeNotNull(String key, dynamic value) { 23 | if (value != null) { 24 | val[key] = value; 25 | } 26 | } 27 | 28 | writeNotNull('materials', 29 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 30 | writeNotNull( 31 | 'fromVector', const Vector3Converter().toJson(instance.fromVector)); 32 | writeNotNull('toVector', const Vector3Converter().toJson(instance.toVector)); 33 | return val; 34 | } 35 | -------------------------------------------------------------------------------- /lib/geometries/arkit_plane.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_plane.g.dart'; 8 | 9 | /// Represents a rectangle with controllable width and height. The plane has one visible side. 10 | @JsonSerializable() 11 | class ARKitPlane extends ARKitGeometry { 12 | ARKitPlane({ 13 | double width = 1, 14 | double height = 1, 15 | this.widthSegmentCount = 1, 16 | this.heightSegmentCount = 1, 17 | List materials, 18 | }) : width = ValueNotifier(width), 19 | height = ValueNotifier(height), 20 | super( 21 | materials: materials, 22 | ); 23 | 24 | /// The plane extent along the X axis. 25 | /// If the value is less than or equal to 0, the geometry is empty. 26 | /// The default value is 1. 27 | @DoubleValueNotifierConverter() 28 | final ValueNotifier width; 29 | 30 | /// The plane extent along the Y axis. 31 | /// If the value is less than or equal to 0, the geometry is empty. 32 | /// The default value is 1. 33 | @DoubleValueNotifierConverter() 34 | final ValueNotifier height; 35 | 36 | /// The number of subdivisions along the X axis. 37 | /// If the value is less than 1, the behavior is undefined. 38 | /// The default value is 1. 39 | final int widthSegmentCount; 40 | 41 | /// The number of subdivisions along the Y axis. The default value is 1. 42 | /// If the value is less than 1, the behavior is undefined. 43 | /// The default value is 1. 44 | final int heightSegmentCount; 45 | 46 | static ARKitPlane fromJson(Map json) => 47 | _$ARKitPlaneFromJson(json); 48 | 49 | @override 50 | Map toJson() => 51 | _$ARKitPlaneToJson(this)..addAll({'dartType': 'ARKitPlane'}); 52 | } 53 | -------------------------------------------------------------------------------- /lib/geometries/arkit_plane.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_plane.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitPlane _$ARKitPlaneFromJson(Map json) { 10 | return ARKitPlane( 11 | width: (json['width'] as num).toDouble(), 12 | height: (json['height'] as num).toDouble(), 13 | widthSegmentCount: json['widthSegmentCount'] as int, 14 | heightSegmentCount: json['heightSegmentCount'] as int, 15 | materials: (json['materials'] as List) 16 | .map((e) => ARKitMaterial.fromJson(e as Map)) 17 | .toList(), 18 | ); 19 | } 20 | 21 | Map _$ARKitPlaneToJson(ARKitPlane instance) { 22 | final val = {}; 23 | 24 | void writeNotNull(String key, dynamic value) { 25 | if (value != null) { 26 | val[key] = value; 27 | } 28 | } 29 | 30 | writeNotNull('materials', 31 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 32 | writeNotNull( 33 | 'width', const DoubleValueNotifierConverter().toJson(instance.width)); 34 | writeNotNull( 35 | 'height', const DoubleValueNotifierConverter().toJson(instance.height)); 36 | val['widthSegmentCount'] = instance.widthSegmentCount; 37 | val['heightSegmentCount'] = instance.heightSegmentCount; 38 | return val; 39 | } 40 | -------------------------------------------------------------------------------- /lib/geometries/arkit_pyramid.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_pyramid.g.dart'; 8 | 9 | /// ARKitPyramid represents a right pyramid with a rectangular base. 10 | @JsonSerializable() 11 | class ARKitPyramid extends ARKitGeometry { 12 | ARKitPyramid({ 13 | double height = 1, 14 | double width = 1, 15 | double length = 1, 16 | List materials, 17 | }) : height = ValueNotifier(height), 18 | width = ValueNotifier(width), 19 | length = ValueNotifier(length), 20 | super( 21 | materials: materials, 22 | ); 23 | 24 | /// The height of the pyramid. 25 | /// If the value is less than or equal to 0, the geometry is empty. 26 | /// The default value is 1. 27 | @DoubleValueNotifierConverter() 28 | final ValueNotifier height; 29 | 30 | /// The width of the pyramid base. 31 | /// If the value is less than or equal to 0, the geometry is empty. 32 | /// The default value is 1. 33 | @DoubleValueNotifierConverter() 34 | final ValueNotifier width; 35 | 36 | /// The length of the pyramid base. 37 | /// If the value is less than or equal to 0, the geometry is empty. 38 | /// The default value is 1. 39 | @DoubleValueNotifierConverter() 40 | final ValueNotifier length; 41 | 42 | static ARKitPyramid fromJson(Map json) => 43 | _$ARKitPyramidFromJson(json); 44 | 45 | @override 46 | Map toJson() => 47 | _$ARKitPyramidToJson(this)..addAll({'dartType': 'ARKitPyramid'}); 48 | } 49 | -------------------------------------------------------------------------------- /lib/geometries/arkit_pyramid.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_pyramid.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitPyramid _$ARKitPyramidFromJson(Map json) { 10 | return ARKitPyramid( 11 | height: (json['height'] as num).toDouble(), 12 | width: (json['width'] as num).toDouble(), 13 | length: (json['length'] as num).toDouble(), 14 | materials: (json['materials'] as List) 15 | .map((e) => ARKitMaterial.fromJson(e as Map)) 16 | .toList(), 17 | ); 18 | } 19 | 20 | Map _$ARKitPyramidToJson(ARKitPyramid instance) { 21 | final val = {}; 22 | 23 | void writeNotNull(String key, dynamic value) { 24 | if (value != null) { 25 | val[key] = value; 26 | } 27 | } 28 | 29 | writeNotNull('materials', 30 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 31 | writeNotNull( 32 | 'height', const DoubleValueNotifierConverter().toJson(instance.height)); 33 | writeNotNull( 34 | 'width', const DoubleValueNotifierConverter().toJson(instance.width)); 35 | writeNotNull( 36 | 'length', const DoubleValueNotifierConverter().toJson(instance.length)); 37 | return val; 38 | } 39 | -------------------------------------------------------------------------------- /lib/geometries/arkit_skeleton.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/utils/json_converters.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | import 'package:vector_math/vector_math_64.dart'; 4 | 5 | part 'arkit_skeleton.g.dart'; 6 | 7 | @JsonSerializable() 8 | class ARKitSkeleton { 9 | ARKitSkeleton(this.modelTransforms, this.localTransforms); 10 | 11 | /// The model space transforms for each joint 12 | @MapOfMatrixConverter() 13 | final Map modelTransforms; 14 | 15 | /// The local space transforms for each joint 16 | @MapOfMatrixConverter() 17 | final Map localTransforms; 18 | 19 | static ARKitSkeleton fromJson(Map json) => 20 | _$ARKitSkeletonFromJson(json); 21 | 22 | Map toJson() => _$ARKitSkeletonToJson(this); 23 | } 24 | -------------------------------------------------------------------------------- /lib/geometries/arkit_skeleton.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_skeleton.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitSkeleton _$ARKitSkeletonFromJson(Map json) { 10 | return ARKitSkeleton( 11 | const MapOfMatrixConverter() 12 | .fromJson(json['modelTransforms'] as Map>), 13 | const MapOfMatrixConverter() 14 | .fromJson(json['localTransforms'] as Map>), 15 | ); 16 | } 17 | 18 | Map _$ARKitSkeletonToJson(ARKitSkeleton instance) { 19 | final val = {}; 20 | 21 | void writeNotNull(String key, dynamic value) { 22 | if (value != null) { 23 | val[key] = value; 24 | } 25 | } 26 | 27 | writeNotNull('modelTransforms', 28 | const MapOfMatrixConverter().toJson(instance.modelTransforms)); 29 | writeNotNull('localTransforms', 30 | const MapOfMatrixConverter().toJson(instance.localTransforms)); 31 | return val; 32 | } 33 | -------------------------------------------------------------------------------- /lib/geometries/arkit_sphere.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_sphere.g.dart'; 8 | 9 | /// Represents a sphere with controllable radius 10 | @JsonSerializable() 11 | class ARKitSphere extends ARKitGeometry { 12 | ARKitSphere({ 13 | double radius = 0.5, 14 | List materials, 15 | }) : radius = ValueNotifier(radius), 16 | super( 17 | materials: materials, 18 | ); 19 | 20 | /// The sphere radius. 21 | /// If the value is less than or equal to 0, the geometry is empty. 22 | /// The default value is 0.5. 23 | @DoubleValueNotifierConverter() 24 | final ValueNotifier radius; 25 | 26 | static ARKitSphere fromJson(Map json) => 27 | _$ARKitSphereFromJson(json); 28 | 29 | @override 30 | Map toJson() => 31 | _$ARKitSphereToJson(this)..addAll({'dartType': 'ARKitSphere'}); 32 | } 33 | -------------------------------------------------------------------------------- /lib/geometries/arkit_sphere.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_sphere.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitSphere _$ARKitSphereFromJson(Map json) { 10 | return ARKitSphere( 11 | radius: (json['radius'] as num).toDouble(), 12 | materials: (json['materials'] as List) 13 | .map((e) => ARKitMaterial.fromJson(e as Map)) 14 | .toList(), 15 | ); 16 | } 17 | 18 | Map _$ARKitSphereToJson(ARKitSphere instance) { 19 | final val = {}; 20 | 21 | void writeNotNull(String key, dynamic value) { 22 | if (value != null) { 23 | val[key] = value; 24 | } 25 | } 26 | 27 | writeNotNull('materials', 28 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 29 | writeNotNull( 30 | 'radius', const DoubleValueNotifierConverter().toJson(instance.radius)); 31 | return val; 32 | } 33 | -------------------------------------------------------------------------------- /lib/geometries/arkit_text.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | import 'package:meta/meta.dart'; 7 | 8 | part 'arkit_text.g.dart'; 9 | 10 | /// Represents a block of text that has been extruded. 11 | @JsonSerializable() 12 | class ARKitText extends ARKitGeometry { 13 | ARKitText({ 14 | @required String text, 15 | @required this.extrusionDepth, 16 | List materials, 17 | }) : text = ValueNotifier(text), 18 | super( 19 | materials: materials, 20 | ); 21 | 22 | /// The text to be represented. 23 | @StringValueNotifierConverter() 24 | final ValueNotifier text; 25 | 26 | /// The extrusion depth. 27 | /// If the value is 0, we get a mono-sided, 2D version of the text. 28 | final double extrusionDepth; 29 | 30 | static ARKitText fromJson(Map json) => 31 | _$ARKitTextFromJson(json); 32 | 33 | @override 34 | Map toJson() => 35 | _$ARKitTextToJson(this)..addAll({'dartType': 'ARKitText'}); 36 | } 37 | -------------------------------------------------------------------------------- /lib/geometries/arkit_text.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_text.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitText _$ARKitTextFromJson(Map json) { 10 | return ARKitText( 11 | text: json['text'] as String, 12 | extrusionDepth: (json['extrusionDepth'] as num).toDouble(), 13 | materials: (json['materials'] as List) 14 | .map((e) => ARKitMaterial.fromJson(e as Map)) 15 | .toList(), 16 | ); 17 | } 18 | 19 | Map _$ARKitTextToJson(ARKitText instance) { 20 | final val = {}; 21 | 22 | void writeNotNull(String key, dynamic value) { 23 | if (value != null) { 24 | val[key] = value; 25 | } 26 | } 27 | 28 | writeNotNull('materials', 29 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 30 | writeNotNull( 31 | 'text', const StringValueNotifierConverter().toJson(instance.text)); 32 | val['extrusionDepth'] = instance.extrusionDepth; 33 | return val; 34 | } 35 | -------------------------------------------------------------------------------- /lib/geometries/arkit_torus.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_torus.g.dart'; 8 | 9 | /// ARKitTorus represents a torus with controllable ring radius and pipe radius. 10 | @JsonSerializable() 11 | class ARKitTorus extends ARKitGeometry { 12 | ARKitTorus({ 13 | double ringRadius = 0.5, 14 | double pipeRadius = 0.25, 15 | List materials, 16 | }) : ringRadius = ValueNotifier(ringRadius), 17 | pipeRadius = ValueNotifier(pipeRadius), 18 | super( 19 | materials: materials, 20 | ); 21 | 22 | /// The radius of the torus ring. 23 | /// If the value is less than or equal to 0, the geometry is empty. 24 | /// The default value is 0.5. 25 | @DoubleValueNotifierConverter() 26 | final ValueNotifier ringRadius; 27 | 28 | /// The radius of the torus pipe. 29 | /// If the value is less than or equal to 0, the geometry is empty. 30 | /// The default value is 0.25. 31 | @DoubleValueNotifierConverter() 32 | final ValueNotifier pipeRadius; 33 | 34 | static ARKitTorus fromJson(Map json) => 35 | _$ARKitTorusFromJson(json); 36 | 37 | @override 38 | Map toJson() => 39 | _$ARKitTorusToJson(this)..addAll({'dartType': 'ARKitTorus'}); 40 | } 41 | -------------------------------------------------------------------------------- /lib/geometries/arkit_torus.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_torus.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitTorus _$ARKitTorusFromJson(Map json) { 10 | return ARKitTorus( 11 | ringRadius: (json['ringRadius'] as num).toDouble(), 12 | pipeRadius: (json['pipeRadius'] as num).toDouble(), 13 | materials: (json['materials'] as List) 14 | .map((e) => ARKitMaterial.fromJson(e as Map)) 15 | .toList(), 16 | ); 17 | } 18 | 19 | Map _$ARKitTorusToJson(ARKitTorus instance) { 20 | final val = {}; 21 | 22 | void writeNotNull(String key, dynamic value) { 23 | if (value != null) { 24 | val[key] = value; 25 | } 26 | } 27 | 28 | writeNotNull('materials', 29 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 30 | writeNotNull('ringRadius', 31 | const DoubleValueNotifierConverter().toJson(instance.ringRadius)); 32 | writeNotNull('pipeRadius', 33 | const DoubleValueNotifierConverter().toJson(instance.pipeRadius)); 34 | return val; 35 | } 36 | -------------------------------------------------------------------------------- /lib/geometries/arkit_tube.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_material.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_tube.g.dart'; 8 | 9 | /// ARKitTube represents a tube with controllable height, inner radius and outer radius. 10 | @JsonSerializable() 11 | class ARKitTube extends ARKitGeometry { 12 | ARKitTube({ 13 | double innerRadius = 0.25, 14 | double outerRadius = 0.5, 15 | double height = 1, 16 | List materials, 17 | }) : height = ValueNotifier(height), 18 | innerRadius = ValueNotifier(innerRadius), 19 | outerRadius = ValueNotifier(outerRadius), 20 | super( 21 | materials: materials, 22 | ); 23 | 24 | /// The height of the tube. 25 | /// If the value is less than or equal to 0, the geometry is empty. 26 | /// The default value is 1. 27 | @DoubleValueNotifierConverter() 28 | final ValueNotifier height; 29 | 30 | /// The inner radius of the tube. 31 | /// If the value is less than or equal to 0, or if it is greater than or equal to the outer radius, then the geometry is empty. 32 | /// The default value is 0.25. 33 | @DoubleValueNotifierConverter() 34 | final ValueNotifier innerRadius; 35 | 36 | /// The outer radius of the tube. 37 | /// If the value is less than or equal to 0, or if it is less than or equal to the inner radius, then the geometry is empty. 38 | /// The default value is 0.5. 39 | @DoubleValueNotifierConverter() 40 | final ValueNotifier outerRadius; 41 | 42 | static ARKitTube fromJson(Map json) => 43 | _$ARKitTubeFromJson(json); 44 | 45 | @override 46 | Map toJson() => 47 | _$ARKitTubeToJson(this)..addAll({'dartType': 'ARKitTube'}); 48 | } 49 | -------------------------------------------------------------------------------- /lib/geometries/arkit_tube.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_tube.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitTube _$ARKitTubeFromJson(Map json) { 10 | return ARKitTube( 11 | innerRadius: (json['innerRadius'] as num).toDouble(), 12 | outerRadius: (json['outerRadius'] as num).toDouble(), 13 | height: (json['height'] as num).toDouble(), 14 | materials: (json['materials'] as List) 15 | .map((e) => ARKitMaterial.fromJson(e as Map)) 16 | .toList(), 17 | ); 18 | } 19 | 20 | Map _$ARKitTubeToJson(ARKitTube instance) { 21 | final val = {}; 22 | 23 | void writeNotNull(String key, dynamic value) { 24 | if (value != null) { 25 | val[key] = value; 26 | } 27 | } 28 | 29 | writeNotNull('materials', 30 | const ListMaterialsValueNotifierConverter().toJson(instance.materials)); 31 | writeNotNull( 32 | 'height', const DoubleValueNotifierConverter().toJson(instance.height)); 33 | writeNotNull('innerRadius', 34 | const DoubleValueNotifierConverter().toJson(instance.innerRadius)); 35 | writeNotNull('outerRadius', 36 | const DoubleValueNotifierConverter().toJson(instance.outerRadius)); 37 | return val; 38 | } 39 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_blend_mode.dart: -------------------------------------------------------------------------------- 1 | /// Blend modes that ARKitMaterial uses to compose with the framebuffer to produce blended colors. 2 | enum ARKitBlendMode { 3 | /// Blends the source and destination colors by adding the source multiplied by source alpha and the destination multiplied by one minus source alpha. 4 | alpha, 5 | 6 | /// Blends the source and destination colors by adding them up. 7 | add, 8 | 9 | /// Blends the source and destination colors by subtracting the source from the destination. 10 | subtract, 11 | 12 | /// Blends the source and destination colors by multiplying them. 13 | multiply, 14 | 15 | /// Blends the source and destination colors by multiplying one minus the source with the destination and adding the source. 16 | screen, 17 | 18 | /// Replaces the destination with the source (ignores alpha). 19 | replace, 20 | 21 | /// Max the destination with the source (ignores alpha). 22 | max, 23 | } 24 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_color_mask.dart: -------------------------------------------------------------------------------- 1 | enum ARKitColorMask { 2 | none, 3 | red, 4 | green, 5 | blue, 6 | alpha, 7 | all, 8 | } 9 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_cull_mode.dart: -------------------------------------------------------------------------------- 1 | enum ARKitCullMode { 2 | back, 3 | front, 4 | } 5 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_fill_mode.dart: -------------------------------------------------------------------------------- 1 | enum ARKitFillMode { 2 | fill, 3 | lines, 4 | } 5 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_lighting_model.dart: -------------------------------------------------------------------------------- 1 | /// Constants for ARKit lightingModel 2 | /// For every lighting model, the final color is computed as follows: 3 | /// finalColor = ( + color + ) * 4 | /// where 5 | /// — The 'emission' property of the SCNMaterial instance 6 | /// — The 'reflective' property of the SCNMaterial instance 7 | /// — The 'multiply' property of the SCNMaterial instance 8 | /// and 9 | /// color - The 'color' term depends on the lighting models described below 10 | enum ARKitLightingModel { 11 | /// Produces a specularly shaded surface where the specular reflection is shaded according the Phong BRDF approximation. 12 | /// The reflected color is calculated as: 13 | /// color = * al + * max(N ⋅ L, 0) + * pow(max(R ⋅ E, 0), ) 14 | /// where 15 | /// al — Sum of all ambient lights currently active (visible) in the scene 16 | /// N — Normal vector 17 | /// L — Light vector 18 | /// E — Eye vector 19 | /// R — Perfect reflection vector (reflect (L around N)) 20 | /// and 21 | /// — The 'ambient' property of the SCNMaterial instance 22 | /// — The 'diffuse' property of the SCNMaterial instance 23 | /// — The 'specular' property of the SCNMaterial instance 24 | /// — The 'shininess' property of the SCNMaterial instance 25 | phong, 26 | 27 | /// Produces a specularly shaded surface with a Blinn BRDF approximation. 28 | /// The reflected color is calculated as: 29 | /// color = * al + * max(N ⋅ L, 0) + * pow(max(H ⋅ N, 0), ) 30 | /// where 31 | /// al — Sum of all ambient lights currently active (visible) in the scene 32 | /// N — Normal vector 33 | /// L — Light vector 34 | /// E — Eye vector 35 | /// H — Half-angle vector, calculated as halfway between the unit Eye and Light vectors, using the equation H = normalize(E + L) 36 | /// and 37 | /// — The 'ambient' property of the SCNMaterial instance 38 | /// — The 'diffuse' property of the SCNMaterial instance 39 | /// — The 'specular' property of the SCNMaterial instance 40 | /// — The 'shininess' property of the SCNMaterial instance 41 | blinn, 42 | 43 | /// Produces a diffuse shaded surface with no specular reflection. 44 | /// The result is based on Lambert’s Law, which states that when light hits a rough surface, the light is reflected in all directions equally. 45 | /// The reflected color is calculated as: 46 | /// color = * al + * max(N ⋅ L, 0) 47 | /// where 48 | /// al — Sum of all ambient lights currently active (visible) in the scene 49 | /// N — Normal vector 50 | /// L — Light vector 51 | /// and 52 | /// — The 'ambient' property of the SCNMaterial instance 53 | /// — The 'diffuse' property of the SCNMaterial instance 54 | lambert, 55 | 56 | /// Produces a constantly shaded surface that is independent of lighting. 57 | /// The reflected color is calculated as: 58 | /// color = * al + 59 | /// where 60 | /// al — Sum of all ambient lights currently active (visible) in the scene 61 | /// and 62 | /// — The 'ambient' property of the SCNMaterial instance 63 | /// — The 'diffuse' property of the SCNMaterial instance 64 | constant, 65 | 66 | /// Shading based on a realistic abstraction of physical lights and materials. 67 | physicallyBased, 68 | 69 | /// iOS 13 only (switches to blinn on older OSes) 70 | shadowOnly, 71 | } 72 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_material.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/material/arkit_blend_mode.dart'; 2 | import 'package:arkit_plugin/geometries/material/arkit_color_mask.dart'; 3 | import 'package:arkit_plugin/geometries/material/arkit_cull_mode.dart'; 4 | import 'package:arkit_plugin/geometries/material/arkit_fill_mode.dart'; 5 | import 'package:arkit_plugin/geometries/material/arkit_lighting_model.dart'; 6 | import 'package:arkit_plugin/geometries/material/arkit_material_property.dart'; 7 | import 'package:arkit_plugin/geometries/material/arkit_transparency_mode.dart'; 8 | import 'package:arkit_plugin/utils/json_converters.dart'; 9 | import 'package:json_annotation/json_annotation.dart'; 10 | 11 | part 'arkit_material.g.dart'; 12 | 13 | /// An ARKitMaterial determines how a geometry is rendered. 14 | /// It encapsulates the colors and textures that define the appearance of 3d geometries. 15 | @JsonSerializable() 16 | class ARKitMaterial { 17 | ARKitMaterial({ 18 | this.diffuse, 19 | this.ambient, 20 | this.specular, 21 | this.emission, 22 | this.transparent, 23 | this.reflective, 24 | this.multiply, 25 | this.normal, 26 | this.displacement, 27 | this.ambientOcclusion, 28 | this.selfIllumination, 29 | this.metalness, 30 | this.roughness, 31 | this.shininess = 1.0, 32 | this.transparency = 1.0, 33 | this.lightingModelName = ARKitLightingModel.blinn, 34 | this.fillMode = ARKitFillMode.fill, 35 | this.cullMode = ARKitCullMode.back, 36 | this.transparencyMode = ARKitTransparencyMode.aOne, 37 | this.locksAmbientWithDiffuse = true, 38 | this.writesToDepthBuffer = true, 39 | this.colorBufferWriteMask = ARKitColorMask.all, 40 | this.doubleSided = false, 41 | this.blendMode = ARKitBlendMode.alpha, 42 | }); 43 | 44 | /// Specifies the receiver's diffuse property. 45 | /// The diffuse property specifies the amount of light diffusely reflected 46 | /// from the surface. The diffuse light is reflected equally in all directions and is 47 | /// therefore independent of the point of view. 48 | @ARKitMaterialPropertyConverter() 49 | final ARKitMaterialProperty diffuse; 50 | 51 | /// Specifies the receiver's ambient property. 52 | /// The ambient property specifies the amount of ambient light to reflect. 53 | /// This property has no visual impact on scenes that have no ambient light. 54 | /// Setting the ambient has no effect if locksAmbientWithDiffuse is set to YES. 55 | @ARKitMaterialPropertyConverter() 56 | final ARKitMaterialProperty ambient; 57 | 58 | /// Specifies the receiver's specular property. 59 | /// The specular property specifies the amount of light to reflect in a mirror-like manner. 60 | /// The specular intensity increases when the point of view lines up with the direction of the reflected light. 61 | @ARKitMaterialPropertyConverter() 62 | final ARKitMaterialProperty specular; 63 | 64 | /// The emission property specifies the amount of light the material emits. 65 | /// This emission does not light up other surfaces in the scene. 66 | @ARKitMaterialPropertyConverter() 67 | final ARKitMaterialProperty emission; 68 | 69 | /// The transparent property specifies the transparent areas of the material. 70 | @ARKitMaterialPropertyConverter() 71 | final ARKitMaterialProperty transparent; 72 | 73 | /// The reflective property specifies the reflectivity of the surface. 74 | /// The surface will not actually reflect other objects in the scene. 75 | /// This property may be used as a sphere mapping to reflect a precomputed environment. 76 | @ARKitMaterialPropertyConverter() 77 | final ARKitMaterialProperty reflective; 78 | 79 | /// The multiply property specifies a color or an image used to multiply the output fragments with. 80 | /// The computed fragments are multiplied with the multiply value to produce the final fragments. 81 | /// This property may be used for shadow maps, to fade out or tint 3d objects. 82 | @ARKitMaterialPropertyConverter() 83 | final ARKitMaterialProperty multiply; 84 | 85 | /// The normal property specifies the surface orientation. 86 | /// When an image is set on the normal property the material is automatically lit per pixel. 87 | /// Setting a color has no effect. 88 | @ARKitMaterialPropertyConverter() 89 | final ARKitMaterialProperty normal; 90 | 91 | /// The displacement property specifies how vertex are translated in tangent space. 92 | /// Pass a grayscale image for a simple 'elevation' or rgb image for a vector displacement. 93 | @ARKitMaterialPropertyConverter() 94 | final ARKitMaterialProperty displacement; 95 | 96 | /// The ambientOcclusion property specifies the ambient occlusion of the surface. 97 | /// The ambient occlusion is multiplied with the ambient light, then the result is added to the lighting contribution. 98 | /// This property has no visual impact on scenes that have no ambient light. 99 | /// When an ambient occlusion map is set, the ambient property is ignored. 100 | @ARKitMaterialPropertyConverter() 101 | final ARKitMaterialProperty ambientOcclusion; 102 | 103 | /// The selfIllumination property specifies a texture or a color that is added to the lighting contribution of the surface. 104 | /// When a selfIllumination is set, the emission property is ignored. 105 | @ARKitMaterialPropertyConverter() 106 | final ARKitMaterialProperty selfIllumination; 107 | 108 | /// The metalness property specifies how metallic the material's surface appears. 109 | /// Lower values (darker colors) cause the material to appear more like a dielectric surface. 110 | /// Higher values (brighter colors) cause the surface to appear more metallic. 111 | /// This property is only used when 'lightingModelName' is 'SCNLightingModelPhysicallyBased'. 112 | @ARKitMaterialPropertyConverter() 113 | final ARKitMaterialProperty metalness; 114 | 115 | /// The roughness property specifies the apparent smoothness of the surface. 116 | /// Lower values (darker colors) cause the material to appear shiny, with well-defined specular highlights. 117 | /// Higher values (brighter colors) cause specular highlights to spread out and the diffuse property of the material to become more retroreflective. 118 | /// This property is only used when 'lightingModelName' is 'SCNLightingModelPhysicallyBased'. 119 | @ARKitMaterialPropertyConverter() 120 | final ARKitMaterialProperty roughness; 121 | 122 | /// Specifies the receiver's shininess value. Defaults to 1.0. 123 | final double shininess; 124 | 125 | /// Specifies the receiver's transparency value. Defaults to 1.0. 126 | /// The color of the transparent property is multiplied by this property. 127 | /// The result is then used to produce the final transparency according to the rule defined by the transparencyMode property. 128 | final double transparency; 129 | 130 | /// Determines the receiver's lighting model. 131 | /// Defaults to ARKitLightingModel.blinn. 132 | @ARKitLightingModelConverter() 133 | final ARKitLightingModel lightingModelName; 134 | 135 | /// Determines of to how to rasterize the receiver's primitives. Defaults to ARKitFillMode.fill. 136 | @ARKitFillModeConverter() 137 | final ARKitFillMode fillMode; 138 | 139 | /// Determines the culling mode of the receiver. Defaults to ARKitCullMode.back; 140 | @ARKitCullModeConverter() 141 | final ARKitCullMode cullMode; 142 | 143 | /// Determines the transparency mode of the receiver. Defaults to ARKitTransparencyMode.aOne. 144 | @ARKitTransparencyModeConverter() 145 | final ARKitTransparencyMode transparencyMode; 146 | 147 | /// Makes the ambient property automatically match the diffuse property. Defaults to true. 148 | final bool locksAmbientWithDiffuse; 149 | 150 | /// Determines whether the receiver writes to the depth buffer when rendered. Defaults to true. 151 | final bool writesToDepthBuffer; 152 | 153 | /// Determines whether the receiver writes to the color buffer when rendered. Defaults to ARKitColorMask.all. 154 | @ARKitColorMaskConverter() 155 | final ARKitColorMask colorBufferWriteMask; 156 | 157 | /// Specifies the receiver's blend mode. Defaults to ARKitBlendMode.alpha. 158 | @ARKitBlendModeConverter() 159 | final ARKitBlendMode blendMode; 160 | 161 | /// Determines whether the receiver is double sided. Defaults to false. 162 | final bool doubleSided; 163 | 164 | static ARKitMaterial fromJson(Map json) => 165 | _$ARKitMaterialFromJson(json); 166 | 167 | Map toJson() => _$ARKitMaterialToJson(this); 168 | } 169 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_material.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_material.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitMaterial _$ARKitMaterialFromJson(Map json) { 10 | return ARKitMaterial( 11 | diffuse: 12 | const ARKitMaterialPropertyConverter().fromJson(json['diffuse'] as Map), 13 | ambient: 14 | const ARKitMaterialPropertyConverter().fromJson(json['ambient'] as Map), 15 | specular: const ARKitMaterialPropertyConverter() 16 | .fromJson(json['specular'] as Map), 17 | emission: const ARKitMaterialPropertyConverter() 18 | .fromJson(json['emission'] as Map), 19 | transparent: const ARKitMaterialPropertyConverter() 20 | .fromJson(json['transparent'] as Map), 21 | reflective: const ARKitMaterialPropertyConverter() 22 | .fromJson(json['reflective'] as Map), 23 | multiply: const ARKitMaterialPropertyConverter() 24 | .fromJson(json['multiply'] as Map), 25 | normal: 26 | const ARKitMaterialPropertyConverter().fromJson(json['normal'] as Map), 27 | displacement: const ARKitMaterialPropertyConverter() 28 | .fromJson(json['displacement'] as Map), 29 | ambientOcclusion: const ARKitMaterialPropertyConverter() 30 | .fromJson(json['ambientOcclusion'] as Map), 31 | selfIllumination: const ARKitMaterialPropertyConverter() 32 | .fromJson(json['selfIllumination'] as Map), 33 | metalness: const ARKitMaterialPropertyConverter() 34 | .fromJson(json['metalness'] as Map), 35 | roughness: const ARKitMaterialPropertyConverter() 36 | .fromJson(json['roughness'] as Map), 37 | shininess: (json['shininess'] as num).toDouble(), 38 | transparency: (json['transparency'] as num).toDouble(), 39 | lightingModelName: const ARKitLightingModelConverter() 40 | .fromJson(json['lightingModelName'] as int), 41 | fillMode: const ARKitFillModeConverter().fromJson(json['fillMode'] as int), 42 | cullMode: const ARKitCullModeConverter().fromJson(json['cullMode'] as int), 43 | transparencyMode: const ARKitTransparencyModeConverter() 44 | .fromJson(json['transparencyMode'] as int), 45 | locksAmbientWithDiffuse: json['locksAmbientWithDiffuse'] as bool, 46 | writesToDepthBuffer: json['writesToDepthBuffer'] as bool, 47 | colorBufferWriteMask: const ARKitColorMaskConverter() 48 | .fromJson(json['colorBufferWriteMask'] as int), 49 | doubleSided: json['doubleSided'] as bool, 50 | blendMode: 51 | const ARKitBlendModeConverter().fromJson(json['blendMode'] as int), 52 | ); 53 | } 54 | 55 | Map _$ARKitMaterialToJson(ARKitMaterial instance) { 56 | final val = {}; 57 | 58 | void writeNotNull(String key, dynamic value) { 59 | if (value != null) { 60 | val[key] = value; 61 | } 62 | } 63 | 64 | writeNotNull('diffuse', 65 | const ARKitMaterialPropertyConverter().toJson(instance.diffuse)); 66 | writeNotNull('ambient', 67 | const ARKitMaterialPropertyConverter().toJson(instance.ambient)); 68 | writeNotNull('specular', 69 | const ARKitMaterialPropertyConverter().toJson(instance.specular)); 70 | writeNotNull('emission', 71 | const ARKitMaterialPropertyConverter().toJson(instance.emission)); 72 | writeNotNull('transparent', 73 | const ARKitMaterialPropertyConverter().toJson(instance.transparent)); 74 | writeNotNull('reflective', 75 | const ARKitMaterialPropertyConverter().toJson(instance.reflective)); 76 | writeNotNull('multiply', 77 | const ARKitMaterialPropertyConverter().toJson(instance.multiply)); 78 | writeNotNull( 79 | 'normal', const ARKitMaterialPropertyConverter().toJson(instance.normal)); 80 | writeNotNull('displacement', 81 | const ARKitMaterialPropertyConverter().toJson(instance.displacement)); 82 | writeNotNull('ambientOcclusion', 83 | const ARKitMaterialPropertyConverter().toJson(instance.ambientOcclusion)); 84 | writeNotNull('selfIllumination', 85 | const ARKitMaterialPropertyConverter().toJson(instance.selfIllumination)); 86 | writeNotNull('metalness', 87 | const ARKitMaterialPropertyConverter().toJson(instance.metalness)); 88 | writeNotNull('roughness', 89 | const ARKitMaterialPropertyConverter().toJson(instance.roughness)); 90 | val['shininess'] = instance.shininess; 91 | val['transparency'] = instance.transparency; 92 | writeNotNull('lightingModelName', 93 | const ARKitLightingModelConverter().toJson(instance.lightingModelName)); 94 | writeNotNull( 95 | 'fillMode', const ARKitFillModeConverter().toJson(instance.fillMode)); 96 | writeNotNull( 97 | 'cullMode', const ARKitCullModeConverter().toJson(instance.cullMode)); 98 | writeNotNull('transparencyMode', 99 | const ARKitTransparencyModeConverter().toJson(instance.transparencyMode)); 100 | val['locksAmbientWithDiffuse'] = instance.locksAmbientWithDiffuse; 101 | val['writesToDepthBuffer'] = instance.writesToDepthBuffer; 102 | writeNotNull('colorBufferWriteMask', 103 | const ARKitColorMaskConverter().toJson(instance.colorBufferWriteMask)); 104 | writeNotNull( 105 | 'blendMode', const ARKitBlendModeConverter().toJson(instance.blendMode)); 106 | val['doubleSided'] = instance.doubleSided; 107 | return val; 108 | } 109 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_material_property.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:json_annotation/json_annotation.dart'; 5 | 6 | part 'arkit_material_property.g.dart'; 7 | 8 | /// The contents of a ARKitMaterial slot 9 | /// This can be used to specify the various properties of SCNMaterial slots such as diffuse, ambient, etc. 10 | @JsonSerializable() 11 | class ARKitMaterialProperty { 12 | ARKitMaterialProperty({this.color, this.image, this.url}); 13 | 14 | /// Specifies the receiver's color. 15 | @ColorConverter() 16 | final Color color; 17 | 18 | /// Specifies the receiver's image. 19 | /// It might be either a name of an image stored in native iOS project or 20 | /// a full path to the file in the Flutter folder (/assets/image/img.jpg) 21 | /// or URL 22 | final String image; 23 | 24 | /// Specifies the location of an image file 25 | /// Deprecated: use image field instead 26 | @deprecated 27 | final String url; 28 | 29 | static ARKitMaterialProperty fromJson(Map json) => 30 | _$ARKitMaterialPropertyFromJson(json); 31 | 32 | Map toJson() => _$ARKitMaterialPropertyToJson(this) 33 | ..removeWhere((String k, dynamic v) => v == null); 34 | } 35 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_material_property.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_material_property.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitMaterialProperty _$ARKitMaterialPropertyFromJson( 10 | Map json) { 11 | return ARKitMaterialProperty( 12 | color: const ColorConverter().fromJson(json['color'] as int), 13 | image: json['image'] as String, 14 | url: json['url'] as String, 15 | ); 16 | } 17 | 18 | Map _$ARKitMaterialPropertyToJson( 19 | ARKitMaterialProperty instance) { 20 | final val = {}; 21 | 22 | void writeNotNull(String key, dynamic value) { 23 | if (value != null) { 24 | val[key] = value; 25 | } 26 | } 27 | 28 | writeNotNull('color', const ColorConverter().toJson(instance.color)); 29 | val['image'] = instance.image; 30 | val['url'] = instance.url; 31 | return val; 32 | } 33 | -------------------------------------------------------------------------------- /lib/geometries/material/arkit_transparency_mode.dart: -------------------------------------------------------------------------------- 1 | enum ARKitTransparencyMode { 2 | /// Takes the transparency information from the alpha channel. The value 1.0 is opaque. 3 | aOne, 4 | 5 | /// Ignores the alpha channel and takes the transparency information from the luminance of the red, green, and blue channels. 6 | /// The value 0.0 is opaque. 7 | rgbZero, 8 | 9 | /// Ensures that one layer of transparency is draw correctly. 10 | singleLayer, 11 | 12 | /// Ensures that two layers of transparency are ordered and drawn correctly. 13 | /// This should be used for transparent convex objects like cubes and spheres, when you want to see both front and back faces. 14 | dualLayer, 15 | } 16 | -------------------------------------------------------------------------------- /lib/hit/arkit_hit_test_result.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_anchor.dart'; 2 | import 'package:arkit_plugin/hit/arkit_hit_test_result_type.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:json_annotation/json_annotation.dart'; 5 | import 'package:vector_math/vector_math_64.dart'; 6 | 7 | part 'arkit_hit_test_result.g.dart'; 8 | 9 | /// A result of an intersection found during a hit-test. 10 | @JsonSerializable() 11 | class ARKitTestResult { 12 | ARKitTestResult( 13 | this.type, 14 | this.distance, 15 | this.localTransform, 16 | this.worldTransform, 17 | this.anchor, 18 | ); 19 | 20 | /// The type of the hit-test result. 21 | @ARKitHitTestResultTypeConverter() 22 | final ARKitHitTestResultType type; 23 | 24 | /// The distance from the camera to the intersection in meters. 25 | final double distance; 26 | 27 | /// The transformation matrix that defines the intersection’s rotation, translation and scale 28 | /// relative to the anchor or nearest feature point. 29 | @MatrixConverter() 30 | final Matrix4 localTransform; 31 | 32 | /// The transformation matrix that defines the intersection’s rotation, translation and scale 33 | /// relative to the world. 34 | @MatrixConverter() 35 | final Matrix4 worldTransform; 36 | 37 | /// The anchor that the hit-test intersected. 38 | /// An anchor will only be provided for existing plane result types. 39 | @ARKitAnchorConverter() 40 | final ARKitAnchor anchor; 41 | 42 | static ARKitTestResult fromJson(Map json) => 43 | _$ARKitTestResultFromJson(json); 44 | 45 | Map toJson() => _$ARKitTestResultToJson(this); 46 | } 47 | -------------------------------------------------------------------------------- /lib/hit/arkit_hit_test_result.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_hit_test_result.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitTestResult _$ARKitTestResultFromJson(Map json) { 10 | return ARKitTestResult( 11 | const ARKitHitTestResultTypeConverter().fromJson(json['type'] as int), 12 | (json['distance'] as num).toDouble(), 13 | const MatrixConverter().fromJson(json['localTransform'] as List), 14 | const MatrixConverter().fromJson(json['worldTransform'] as List), 15 | const ARKitAnchorConverter().fromJson(json['anchor'] as Map), 16 | ); 17 | } 18 | 19 | Map _$ARKitTestResultToJson(ARKitTestResult instance) { 20 | final val = {}; 21 | 22 | void writeNotNull(String key, dynamic value) { 23 | if (value != null) { 24 | val[key] = value; 25 | } 26 | } 27 | 28 | writeNotNull( 29 | 'type', const ARKitHitTestResultTypeConverter().toJson(instance.type)); 30 | val['distance'] = instance.distance; 31 | writeNotNull('localTransform', 32 | const MatrixConverter().toJson(instance.localTransform)); 33 | writeNotNull('worldTransform', 34 | const MatrixConverter().toJson(instance.worldTransform)); 35 | writeNotNull('anchor', const ARKitAnchorConverter().toJson(instance.anchor)); 36 | return val; 37 | } 38 | -------------------------------------------------------------------------------- /lib/hit/arkit_hit_test_result_type.dart: -------------------------------------------------------------------------------- 1 | /// Option set of hit-test result types. 2 | enum ARKitHitTestResultType { 3 | /// If you have this value you might face a bug in the plugin, sorry. Please create an issue on GitHub. 4 | unknown, 5 | 6 | /// Result type from intersecting the nearest feature point. 7 | featurePoint, 8 | 9 | /// Result type from intersecting a horizontal plane estimate, determined for the current frame. 10 | estimatedHorizontalPlane, 11 | 12 | /// Result type from intersecting a vertical plane estimate, determined for the current frame. 13 | estimatedVerticalPlane, 14 | 15 | /// Result type from intersecting with an existing plane anchor. 16 | existingPlane, 17 | 18 | /// Result type from intersecting with an existing plane anchor, taking into account the plane’s extent. 19 | existingPlaneUsingExtent, 20 | 21 | /// Result type from intersecting with an existing plane anchor, taking into account the plane’s geometry. 22 | existingPlaneUsingGeometry, 23 | } 24 | -------------------------------------------------------------------------------- /lib/hit/arkit_node_pan_result.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/utils/json_converters.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | import 'package:vector_math/vector_math_64.dart'; 4 | 5 | part 'arkit_node_pan_result.g.dart'; 6 | 7 | /// The result of users pan gesture interaction with nodes 8 | @JsonSerializable() 9 | class ARKitNodePanResult { 10 | const ARKitNodePanResult(this.nodeName, this.translation); 11 | 12 | /// The name of the node which users is interacting with. 13 | final String nodeName; 14 | 15 | // The translation in the coordinate system of the scene view 16 | @Vector2Converter() 17 | final Vector2 translation; 18 | 19 | static ARKitNodePanResult fromJson(Map json) => 20 | _$ARKitNodePanResultFromJson(json); 21 | 22 | Map toJson() => _$ARKitNodePanResultToJson(this); 23 | } 24 | -------------------------------------------------------------------------------- /lib/hit/arkit_node_pan_result.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_node_pan_result.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitNodePanResult _$ARKitNodePanResultFromJson(Map json) { 10 | return ARKitNodePanResult( 11 | json['nodeName'] as String, 12 | const Vector2Converter().fromJson(json['translation'] as List), 13 | ); 14 | } 15 | 16 | Map _$ARKitNodePanResultToJson(ARKitNodePanResult instance) { 17 | final val = { 18 | 'nodeName': instance.nodeName, 19 | }; 20 | 21 | void writeNotNull(String key, dynamic value) { 22 | if (value != null) { 23 | val[key] = value; 24 | } 25 | } 26 | 27 | writeNotNull( 28 | 'translation', const Vector2Converter().toJson(instance.translation)); 29 | return val; 30 | } 31 | -------------------------------------------------------------------------------- /lib/hit/arkit_node_pinch_result.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'arkit_node_pinch_result.g.dart'; 4 | 5 | /// The result of users pinch gesture interaction with nodes 6 | @JsonSerializable() 7 | class ARKitNodePinchResult { 8 | const ARKitNodePinchResult(this.nodeName, this.scale); 9 | 10 | /// The name of the node which users is interacting with. 11 | final String nodeName; 12 | 13 | // The pinch scale value. 14 | final double scale; 15 | 16 | static ARKitNodePinchResult fromJson(Map json) => 17 | _$ARKitNodePinchResultFromJson(json); 18 | 19 | Map toJson() => _$ARKitNodePinchResultToJson(this); 20 | } 21 | -------------------------------------------------------------------------------- /lib/hit/arkit_node_pinch_result.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_node_pinch_result.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitNodePinchResult _$ARKitNodePinchResultFromJson(Map json) { 10 | return ARKitNodePinchResult( 11 | json['nodeName'] as String, 12 | (json['scale'] as num).toDouble(), 13 | ); 14 | } 15 | 16 | Map _$ARKitNodePinchResultToJson( 17 | ARKitNodePinchResult instance) => 18 | { 19 | 'nodeName': instance.nodeName, 20 | 'scale': instance.scale, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/hit/arkit_node_rotation_result.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'arkit_node_rotation_result.g.dart'; 4 | 5 | /// The result of users pinch gesture interaction with nodes 6 | @JsonSerializable() 7 | class ARKitNodeRotationResult { 8 | const ARKitNodeRotationResult(this.nodeName, this.rotation); 9 | 10 | /// The name of the node which users is interacting with. 11 | final String nodeName; 12 | 13 | /// The rotation value. 14 | final double rotation; 15 | 16 | static ARKitNodeRotationResult fromJson(Map json) => 17 | _$ARKitNodeRotationResultFromJson(json); 18 | 19 | Map toJson() => _$ARKitNodeRotationResultToJson(this); 20 | } 21 | -------------------------------------------------------------------------------- /lib/hit/arkit_node_rotation_result.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_node_rotation_result.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitNodeRotationResult _$ARKitNodeRotationResultFromJson( 10 | Map json) { 11 | return ARKitNodeRotationResult( 12 | json['nodeName'] as String, 13 | (json['rotation'] as num).toDouble(), 14 | ); 15 | } 16 | 17 | Map _$ARKitNodeRotationResultToJson( 18 | ARKitNodeRotationResult instance) => 19 | { 20 | 'nodeName': instance.nodeName, 21 | 'rotation': instance.rotation, 22 | }; 23 | -------------------------------------------------------------------------------- /lib/light/arkit_light.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/light/arkit_light_type.dart'; 2 | import 'package:arkit_plugin/utils/json_converters.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | 7 | part 'arkit_light.g.dart'; 8 | 9 | /// ARKitLight represents a light that can be attached to a ARKitNode. 10 | @JsonSerializable() 11 | class ARKitLight { 12 | ARKitLight({ 13 | this.type = ARKitLightType.omni, 14 | this.color = Colors.white, 15 | this.temperature = 6500, 16 | double intensity, 17 | this.spotInnerAngle = 0, 18 | this.spotOuterAngle = 45, 19 | }) : intensity = ValueNotifier(intensity ?? 1000); 20 | 21 | /// Light type. 22 | /// Defaults to ARKitLightType.omni. 23 | @ARKitLightTypeConverter() 24 | final ARKitLightType type; 25 | 26 | /// Specifies the receiver's color. 27 | /// Defaults to white. 28 | /// The renderer multiplies the light's color is by the color derived from the light's temperature. 29 | @ColorConverter() 30 | final Color color; 31 | 32 | /// This specifies the temperature of the light in Kelvin. 33 | /// The renderer multiplies the light's color by the color derived from the light's temperature. 34 | /// Defaults to 6500 (pure white). 35 | final double temperature; 36 | 37 | /// This intensity is used to modulate the light color. 38 | /// When used with a physically-based material, this corresponds to the luminous flux of the light, expressed in lumens (lm). 39 | /// Defaults to 1000. 40 | @DoubleValueNotifierConverter() 41 | final ValueNotifier intensity; 42 | 43 | /// The angle in degrees between the spot direction and the lit element below which the lighting is at full strength. 44 | /// Defaults to 0. 45 | final double spotInnerAngle; 46 | 47 | /// The angle in degrees between the spot direction and the lit element after which the lighting is at zero strength. 48 | /// Defaults to 45 degrees. 49 | final double spotOuterAngle; 50 | 51 | static ARKitLight fromJson(Map json) => 52 | _$ARKitLightFromJson(json); 53 | 54 | Map toJson() => _$ARKitLightToJson(this); 55 | } 56 | -------------------------------------------------------------------------------- /lib/light/arkit_light.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_light.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitLight _$ARKitLightFromJson(Map json) { 10 | return ARKitLight( 11 | type: const ARKitLightTypeConverter().fromJson(json['type'] as int), 12 | color: const ColorConverter().fromJson(json['color'] as int), 13 | temperature: (json['temperature'] as num).toDouble(), 14 | intensity: (json['intensity'] as num).toDouble(), 15 | spotInnerAngle: (json['spotInnerAngle'] as num).toDouble(), 16 | spotOuterAngle: (json['spotOuterAngle'] as num).toDouble(), 17 | ); 18 | } 19 | 20 | Map _$ARKitLightToJson(ARKitLight instance) { 21 | final val = {}; 22 | 23 | void writeNotNull(String key, dynamic value) { 24 | if (value != null) { 25 | val[key] = value; 26 | } 27 | } 28 | 29 | writeNotNull('type', const ARKitLightTypeConverter().toJson(instance.type)); 30 | writeNotNull('color', const ColorConverter().toJson(instance.color)); 31 | val['temperature'] = instance.temperature; 32 | writeNotNull('intensity', 33 | const DoubleValueNotifierConverter().toJson(instance.intensity)); 34 | val['spotInnerAngle'] = instance.spotInnerAngle; 35 | val['spotOuterAngle'] = instance.spotOuterAngle; 36 | return val; 37 | } 38 | -------------------------------------------------------------------------------- /lib/light/arkit_light_estimate.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'arkit_light_estimate.g.dart'; 4 | 5 | /// A light estimate representing the light in the scene. 6 | @JsonSerializable() 7 | class ARKitLightEstimate { 8 | const ARKitLightEstimate({ 9 | this.ambientIntensity, 10 | this.ambientColorTemperature, 11 | }); 12 | 13 | /// Ambient intensity of the lighting. 14 | /// In a well lit environment, this value is close to 1000. 15 | /// It typically ranges from 0 (very dark) to around 2000 (very bright). 16 | final double ambientIntensity; 17 | 18 | /// The ambient color temperature of the lighting. 19 | /// This specifies the ambient color temperature of the lighting in Kelvin (6500 corresponds to pure white). 20 | final double ambientColorTemperature; 21 | 22 | static ARKitLightEstimate fromJson(Map map) => 23 | _$ARKitLightEstimateFromJson(map); 24 | 25 | Map toJson() => _$ARKitLightEstimateToJson(this); 26 | } 27 | -------------------------------------------------------------------------------- /lib/light/arkit_light_estimate.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_light_estimate.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitLightEstimate _$ARKitLightEstimateFromJson(Map json) { 10 | return ARKitLightEstimate( 11 | ambientIntensity: (json['ambientIntensity'] as num).toDouble(), 12 | ambientColorTemperature: 13 | (json['ambientColorTemperature'] as num).toDouble(), 14 | ); 15 | } 16 | 17 | Map _$ARKitLightEstimateToJson(ARKitLightEstimate instance) => 18 | { 19 | 'ambientIntensity': instance.ambientIntensity, 20 | 'ambientColorTemperature': instance.ambientColorTemperature, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/light/arkit_light_type.dart: -------------------------------------------------------------------------------- 1 | /// Describes the various light types available. 2 | enum ARKitLightType { 3 | ambient, 4 | omni, 5 | directional, 6 | spot, 7 | ies, 8 | probe, 9 | area, 10 | } 11 | -------------------------------------------------------------------------------- /lib/physics/arkit_physics_body.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/physics/arkit_physics_body_type.dart'; 2 | import 'package:arkit_plugin/physics/arkit_physics_shape.dart'; 3 | import 'package:arkit_plugin/utils/json_converters.dart'; 4 | import 'package:json_annotation/json_annotation.dart'; 5 | 6 | part 'arkit_physics_body.g.dart'; 7 | 8 | /// The ARKitPhysicsBody class describes the physics properties (such as mass, friction...) of a node. 9 | @JsonSerializable() 10 | class ARKitPhysicsBody { 11 | const ARKitPhysicsBody( 12 | this.type, { 13 | this.shape, 14 | this.categoryBitMask, 15 | }); 16 | 17 | /// Specifies the type of the receiver. 18 | @ARKitPhysicsBodyTypeConverter() 19 | final ARKitPhysicsBodyType type; 20 | 21 | /// Specifies the shape of the receiver. 22 | @ARKitPhysicsShapeConverter() 23 | final ARKitPhysicsShape shape; 24 | 25 | /// Defines what logical 'categories' this body belongs to. 26 | /// Defaults to SCNPhysicsCollisionCategoryStatic for static bodies and SCNPhysicsCollisionCategoryDefault for the other body types. 27 | final int categoryBitMask; 28 | 29 | static ARKitPhysicsBody fromJson(Map json) => 30 | _$ARKitPhysicsBodyFromJson(json); 31 | 32 | Map toJson() => _$ARKitPhysicsBodyToJson(this); 33 | } 34 | -------------------------------------------------------------------------------- /lib/physics/arkit_physics_body.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_physics_body.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitPhysicsBody _$ARKitPhysicsBodyFromJson(Map json) { 10 | return ARKitPhysicsBody( 11 | const ARKitPhysicsBodyTypeConverter().fromJson(json['type'] as int), 12 | shape: const ARKitPhysicsShapeConverter().fromJson(json['shape'] as Map), 13 | categoryBitMask: json['categoryBitMask'] as int, 14 | ); 15 | } 16 | 17 | Map _$ARKitPhysicsBodyToJson(ARKitPhysicsBody instance) { 18 | final val = {}; 19 | 20 | void writeNotNull(String key, dynamic value) { 21 | if (value != null) { 22 | val[key] = value; 23 | } 24 | } 25 | 26 | writeNotNull( 27 | 'type', const ARKitPhysicsBodyTypeConverter().toJson(instance.type)); 28 | writeNotNull( 29 | 'shape', const ARKitPhysicsShapeConverter().toJson(instance.shape)); 30 | val['categoryBitMask'] = instance.categoryBitMask; 31 | return val; 32 | } 33 | -------------------------------------------------------------------------------- /lib/physics/arkit_physics_body_type.dart: -------------------------------------------------------------------------------- 1 | /// Physics Body type 2 | enum ARKitPhysicsBodyType { 3 | staticType, 4 | dynamicType, 5 | kinematic, 6 | } 7 | -------------------------------------------------------------------------------- /lib/physics/arkit_physics_shape.dart: -------------------------------------------------------------------------------- 1 | import 'package:arkit_plugin/geometries/arkit_geometry.dart'; 2 | import 'package:arkit_plugin/utils/json_converters.dart'; 3 | import 'package:json_annotation/json_annotation.dart'; 4 | 5 | part 'arkit_physics_shape.g.dart'; 6 | 7 | /// ARKitPhysicsShape represents the shape of a physics body. 8 | @JsonSerializable() 9 | class ARKitPhysicsShape { 10 | const ARKitPhysicsShape(this.geometry); 11 | 12 | @ARKitGeometryConverter() 13 | final ARKitGeometry geometry; 14 | 15 | static ARKitPhysicsShape fromJson(Map json) => 16 | _$ARKitPhysicsShapeFromJson(json); 17 | 18 | Map toJson() => _$ARKitPhysicsShapeToJson(this); 19 | } 20 | -------------------------------------------------------------------------------- /lib/physics/arkit_physics_shape.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_physics_shape.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitPhysicsShape _$ARKitPhysicsShapeFromJson(Map json) { 10 | return ARKitPhysicsShape( 11 | const ARKitGeometryConverter().fromJson(json['geometry'] as Map), 12 | ); 13 | } 14 | 15 | Map _$ARKitPhysicsShapeToJson(ARKitPhysicsShape instance) { 16 | final val = {}; 17 | 18 | void writeNotNull(String key, dynamic value) { 19 | if (value != null) { 20 | val[key] = value; 21 | } 22 | } 23 | 24 | writeNotNull( 25 | 'geometry', const ARKitGeometryConverter().toJson(instance.geometry)); 26 | return val; 27 | } 28 | -------------------------------------------------------------------------------- /lib/utils/matrix4_ext.dart: -------------------------------------------------------------------------------- 1 | import 'package:vector_math/vector_math_64.dart'; 2 | import 'dart:math' as math; 3 | 4 | Matrix4 createTransformMatrix(Matrix4 origin, Vector3 position, Vector3 scale, 5 | Vector4 rotation, Vector3 eulerAngles) { 6 | final transform = origin ?? Matrix4.identity(); 7 | 8 | if (position != null) { 9 | transform.setTranslation(position); 10 | } 11 | if (rotation != null) { 12 | transform.rotate( 13 | Vector3(rotation[0], rotation[1], rotation[2]), rotation[3]); 14 | } 15 | if (eulerAngles != null) { 16 | transform.matrixEulerAngles = eulerAngles; 17 | } 18 | if (scale != null) { 19 | transform.scale(scale); 20 | } else { 21 | transform.scale(1.0); 22 | } 23 | return transform; 24 | } 25 | 26 | extension Matrix4Extenstion on Matrix4 { 27 | Vector3 get matrixScale { 28 | final scale = Vector3.zero(); 29 | decompose(Vector3.zero(), Quaternion(0, 0, 0, 0), scale); 30 | return scale; 31 | } 32 | 33 | Vector3 get matrixEulerAngles { 34 | final q = Quaternion(0, 0, 0, 0); 35 | decompose(Vector3.zero(), q, Vector3.zero()); 36 | 37 | final t = q.x; 38 | q.x = q.y; 39 | q.y = t; 40 | 41 | final angles = Vector3.zero(); 42 | 43 | // roll (x-axis rotation) 44 | final sinr_cosp = 2 * (q.w * q.x + q.y * q.z); 45 | final cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y); 46 | angles[0] = math.atan2(sinr_cosp, cosr_cosp); 47 | 48 | // pitch (y-axis rotation) 49 | final sinp = 2 * (q.w * q.y - q.z * q.x); 50 | if (sinp.abs() >= 1) { 51 | angles[1] = 52 | _copySign(math.pi / 2, sinp); // use 90 degrees if out of range 53 | } else { 54 | angles[1] = math.asin(sinp); 55 | } 56 | // yaw (z-axis rotation) 57 | final siny_cosp = 2 * (q.w * q.z + q.x * q.y); 58 | final cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z); 59 | angles[2] = math.atan2(siny_cosp, cosy_cosp); 60 | 61 | return angles; 62 | } 63 | 64 | set matrixEulerAngles(Vector3 angles) { 65 | final translation = Vector3.zero(); 66 | final scale = Vector3.zero(); 67 | decompose(translation, Quaternion(0, 0, 0, 0), scale); 68 | final r = Quaternion.euler(angles[0], angles[1], angles[2]); 69 | setFromTranslationRotationScale(translation, r, scale); 70 | } 71 | } 72 | 73 | // https://scidart.org/docs/scidart/numdart/copySign.html 74 | double _copySign(double magnitude, double sign) { 75 | // The highest order bit is going to be zero if the 76 | // highest order bit of m and s is the same and one otherwise. 77 | // So (m^s) will be positive if both m and s have the same sign 78 | // and negative otherwise. 79 | /*final long m = Double.doubleToRawLongBits(magnitude); // don't care about NaN 80 | final long s = Double.doubleToRawLongBits(sign); 81 | if ((m^s) >= 0) { 82 | return magnitude; 83 | } 84 | return -magnitude; // flip sign*/ 85 | if (sign == 0.0 || sign.isNaN || magnitude.sign == sign.sign) { 86 | return magnitude; 87 | } 88 | return -magnitude; // flip sign 89 | } 90 | -------------------------------------------------------------------------------- /lib/utils/random_string.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | String randomString({int length = 16}) { 4 | final rand = Random(); 5 | final codeUnits = List.generate(length, (index) { 6 | return rand.nextInt(33) + 89; 7 | }); 8 | 9 | return String.fromCharCodes(codeUnits); 10 | } 11 | -------------------------------------------------------------------------------- /lib/widget/ar_tracking_state.dart: -------------------------------------------------------------------------------- 1 | /// A value describing the camera's tracking state. 2 | enum ARTrackingState { 3 | /// Camera position tracking is not available. 4 | notAvailable, 5 | 6 | /// Tracking is available, but the quality of results is questionable. 7 | limited, 8 | 9 | /// Camera position tracking is providing optimal results. 10 | normal, 11 | } 12 | 13 | /// The reason why ARTrackingState is limited 14 | enum ARTrackingStateReason { 15 | /// This should not happen. Please create an issue for the plugin. 16 | unknown, 17 | 18 | /// Tracking is limited due to initialization in progress. 19 | initializing, 20 | 21 | /// Tracking is limited due to a relocalization in progress. 22 | relocalizing, 23 | 24 | /// Tracking is limited due to a excessive motion of the camera. 25 | excessiveMotion, 26 | 27 | /// Tracking is limited due to a lack of features visible to the camera. 28 | insufficientFeatures, 29 | } 30 | -------------------------------------------------------------------------------- /lib/widget/arkit_arplane_detection.dart: -------------------------------------------------------------------------------- 1 | /// Indicating the type of planes to detect. 2 | enum ARPlaneDetection { 3 | /// No plane detection is run 4 | none, 5 | 6 | /// Plane detection determines horizontal planes in the scene. 7 | horizontal, 8 | 9 | /// Plane detection determines vertical planes in the scene. (iOS >= 11.3) 10 | vertical, 11 | 12 | /// Plane detection determines both horizontal and vertical planes in the scene. (iOS >= 11.3) 13 | horizontalAndVertical, 14 | } 15 | -------------------------------------------------------------------------------- /lib/widget/arkit_configuration.dart: -------------------------------------------------------------------------------- 1 | /// Determines the object type to describe and configure the Augmented Reality techniques to be used in an ARSession. 2 | enum ARKitConfiguration { 3 | /// A configuration for running world tracking. 4 | /// World tracking provides 6 degrees of freedom tracking of the device. 5 | /// By finding feature points in the scene, world tracking enables performing hit-tests against the frame. 6 | /// Tracking can no longer be resumed once the session is paused. 7 | worldTracking, 8 | 9 | /// A configuration for running face tracking. 10 | /// Face tracking uses the front facing camera to track the face in 3D providing details on the topology and expression of the face. 11 | /// A detected face will be added to the session as an ARFaceAnchor object which contains information about head pose, mesh, eye pose, and blend shape 12 | /// coefficients. If light estimation is enabled the detected face will be treated as a light probe and used to estimate the direction of incoming light. 13 | faceTracking, 14 | 15 | /// A configuration for running image tracking. 16 | /// Image tracking provides 6 degrees of freedom tracking of known images. Four images may be tracked simultaneously. 17 | imageTracking, 18 | 19 | /// A configuration for running body tracking. 20 | /// Body tracking provides 6 degrees of freedom tracking of a detected body in the scene. 21 | bodyTracking, 22 | } 23 | -------------------------------------------------------------------------------- /lib/widget/arkit_reference_image.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'arkit_reference_image.g.dart'; 4 | 5 | /// A reference image to be detected in the scene. 6 | @JsonSerializable() 7 | class ARKitReferenceImage { 8 | const ARKitReferenceImage({ 9 | this.name, 10 | this.physicalWidth, 11 | }); 12 | 13 | /// An image name for local images (bundle, asset, or url) 14 | final String name; 15 | 16 | /// The physical width of the image in meters. 17 | final double physicalWidth; 18 | 19 | static ARKitReferenceImage fromJson(Map map) => 20 | _$ARKitReferenceImageFromJson(map); 21 | 22 | Map toJson() => _$ARKitReferenceImageToJson(this); 23 | } 24 | -------------------------------------------------------------------------------- /lib/widget/arkit_reference_image.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'arkit_reference_image.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ARKitReferenceImage _$ARKitReferenceImageFromJson(Map json) { 10 | return ARKitReferenceImage( 11 | name: json['name'] as String, 12 | physicalWidth: (json['physicalWidth'] as num).toDouble(), 13 | ); 14 | } 15 | 16 | Map _$ARKitReferenceImageToJson( 17 | ARKitReferenceImage instance) => 18 | { 19 | 'name': instance.name, 20 | 'physicalWidth': instance.physicalWidth, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/widget/arkit_world_alignment.dart: -------------------------------------------------------------------------------- 1 | /// Enum constants for indicating the world alignment. 2 | enum ARWorldAlignment { 3 | /// Aligns the world with gravity that is defined by vector (0, -1, 0). 4 | gravity, 5 | 6 | /// Aligns the world with gravity that is defined by the vector (0, -1, 0) 7 | /// and heading (w.r.t. True North) that is given by the vector (0, 0, -1). 8 | gravityAndHeading, 9 | 10 | /// Aligns the world with the camera’s orientation. 11 | camera, 12 | } 13 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: arkit_plugin 2 | description: Flutter Plugin for ARKit - Apple's augmented reality (AR) development platform for iOS mobile devices. 3 | version: 0.6.1 4 | 5 | environment: 6 | sdk: ">=2.7.0 <3.0.0" 7 | flutter: ">=1.12.0 <2.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | meta: ^1.1.8 13 | vector_math: ^2.0.8 14 | json_annotation: ^3.0.1 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | build_runner: ^1.9.0 20 | json_serializable: ^3.3.0 21 | pedantic: ^1.9.0 22 | 23 | flutter: 24 | plugin: 25 | platforms: 26 | ios: 27 | pluginClass: ArkitPlugin 28 | --------------------------------------------------------------------------------