### Configure AR Session and Handle Taps in Flutter Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Shows how to configure AR session settings such as enabling animated guides, feature points, plane visualization with custom textures, world origin, and gesture handling (taps, pans, rotations). It also includes an example of handling plane or point taps to get hit test results and camera information. ```dart import 'package:ar_flutter_plugin/managers/ar_session_manager.dart'; import 'package:ar_flutter_plugin/models/ar_hittest_result.dart'; import 'package:ar_flutter_plugin/datatypes/hittest_result_types.dart'; import 'package:vector_math/vector_math_64.dart'; void setupARSession(ARSessionManager sessionManager) { // Initialize session with custom settings sessionManager.onInitialize( showAnimatedGuide: true, showFeaturePoints: true, showPlanes: true, customPlaneTexturePath: "Images/triangle.png", // Asset from your app showWorldOrigin: true, handleTaps: true, handlePans: true, // Enable dragging 3D objects handleRotation: true, // Enable rotating 3D objects ); // Handle taps on planes or feature points sessionManager.onPlaneOrPointTap = (List hits) { var planeHit = hits.firstWhere( (hit) => hit.type == ARHitTestResultType.plane, orElse: () => hits.first, ); print("Tapped at distance: ${planeHit.distance}m"); // planeHit.worldTransform contains 4x4 transformation matrix }; } // Get camera position and orientation Future getCameraInfo(ARSessionManager sessionManager) async { Matrix4? cameraPose = await sessionManager.getCameraPose(); if (cameraPose != null) { Vector3 cameraPosition = cameraPose.getTranslation(); print("Camera at: x=${cameraPosition.x}, y=${cameraPosition.y}, z=${cameraPosition.z}"); } } // Take a screenshot of the AR scene Future captureARScene(ARSessionManager sessionManager) async { try { ImageProvider screenshot = await sessionManager.snapshot(); // Use screenshot in Image widget: Image(image: screenshot) } catch (e) { print("Screenshot failed: $e"); } } ``` -------------------------------- ### Add ar_flutter_plugin Dependency (Bash) Source: https://github.com/cariuslars/ar_flutter_plugin/blob/main/README.md Installs the ar_flutter_plugin package into your Flutter project using the Flutter CLI. ```bash flutter pub add ar_flutter_plugin ``` -------------------------------- ### Manage Anchors with ARAnchorManager Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Covers the functionality of ARAnchorManager for creating, removing, and synchronizing anchors. Includes setup for Google Cloud Anchors, handling uploads, and downloading anchors for persistent AR experiences. ```dart import 'package:ar_flutter_plugin/managers/ar_anchor_manager.dart'; import 'package:ar_flutter_plugin/models/ar_anchor.dart'; import 'package:vector_math/vector_math_64.dart'; // Add an anchor to the scene Future createAnchor( ARAnchorManager anchorManager, Matrix4 transform, ) async { var anchor = ARPlaneAnchor( transformation: transform, ttl: 2, // Time to live: 2 days for cloud anchors ); bool? success = await anchorManager.addAnchor(anchor); if (success == true) { print("Anchor created: ${anchor.name}"); } } // Remove an anchor and all attached objects void removeAnchor(ARAnchorManager anchorManager, ARAnchor anchor) { anchorManager.removeAnchor(anchor); } // Setup cloud anchor functionality with Firebase void setupCloudAnchors(ARAnchorManager anchorManager) { // Initialize Google Cloud Anchor mode anchorManager.initGoogleCloudAnchorMode(); // Handle successful anchor upload anchorManager.onAnchorUploaded = (ARAnchor anchor) { if (anchor is ARPlaneAnchor) { String cloudId = anchor.cloudanchorid ?? ""; print("Anchor uploaded with cloud ID: $cloudId"); // Save cloudId to your database (Firebase, etc.) } }; // Handle anchor download and resolution anchorManager.onAnchorDownloaded = (Map serializedAnchor) { ARPlaneAnchor anchor = ARPlaneAnchor.fromJson(serializedAnchor); print("Anchor downloaded: ${anchor.cloudanchorid}"); return anchor; }; } // Upload anchor to Google Cloud Future uploadToCloud( ARAnchorManager anchorManager, ARPlaneAnchor anchor, ) async { bool? success = await anchorManager.uploadAnchor(anchor); if (success == true) { print("Upload initiated for anchor: ${anchor.name}"); // Callback onAnchorUploaded will be triggered when complete } } // Download anchor from Google Cloud Future downloadFromCloud( ARAnchorManager anchorManager, String cloudAnchorId, ) async { await anchorManager.downloadAnchor(cloudAnchorId); // Callback onAnchorDownloaded will be triggered when resolved } ``` -------------------------------- ### Calculate Distances in AR Scene Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Provides examples of calculating distances between AR anchors, anchors and the camera, and between arbitrary 3D vectors using the AR Session Manager. It also shows how to retrieve the pose (position and orientation) of an AR anchor. ```dart import 'package:ar_flutter_plugin/managers/ar_session_manager.dart'; import 'package:ar_flutter_plugin/models/ar_anchor.dart'; import 'package:vector_math/vector_math_64.dart'; // Get distance from camera to anchor Future measureDistanceToAnchor( ARSessionManager sessionManager, ARAnchor anchor, ) async { double? distance = await sessionManager.getDistanceFromAnchor(anchor); if (distance != null) { print("Anchor is ${distance.toStringAsFixed(2)} meters away"); } } // Get distance between two anchors Future measureDistanceBetweenAnchors( ARSessionManager sessionManager, ARAnchor anchor1, ARAnchor anchor2, ) async { double? distance = await sessionManager.getDistanceBetweenAnchors( anchor1, anchor2, ); if (distance != null) { print("Distance between anchors: ${distance.toStringAsFixed(2)}m"); } } // Get distance between two vectors double calculateDistance( ARSessionManager sessionManager, Vector3 point1, Vector3 point2, ) { return sessionManager.getDistanceBetweenVectors(point1, point2); } // Get anchor pose (transformation matrix) Future getAnchorPosition( ARSessionManager sessionManager, ARAnchor anchor, ) async { Matrix4? pose = await sessionManager.getPose(anchor); if (pose != null) { Vector3 position = pose.getTranslation(); print("Anchor position: x=${position.x}, y=${position.y}, z=${position.z}"); } } ``` -------------------------------- ### Add ar_flutter_plugin to pubspec.yaml (YAML) Source: https://github.com/cariuslars/ar_flutter_plugin/blob/main/README.md Manually adds the ar_flutter_plugin dependency to your project's pubspec.yaml file. Remember to run 'flutter pub get' after manual edits. ```yaml dependencies: ar_flutter_plugin: ^0.7.3 ``` -------------------------------- ### Add 3D Objects with ARObjectManager Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Demonstrates how to add various 3D models to the AR scene using ARObjectManager. Supports models from the web or local assets, and allows attaching them to anchors. Includes basic interaction setup for node taps and transformations. ```dart import 'package:ar_flutter_plugin/managers/ar_object_manager.dart'; import 'package:ar_flutter_plugin/models/ar_node.dart'; import 'package:ar_flutter_plugin/models/ar_anchor.dart'; import 'package:ar_flutter_plugin/datatypes/node_types.dart'; import 'package:vector_math/vector_math_64.dart'; // Add a 3D model from the web Future addWebModel(ARObjectManager objectManager) async { var node = ARNode( type: NodeType.webGLB, uri: "https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/Duck/glTF-Binary/Duck.glb", scale: Vector3(0.2, 0.2, 0.2), position: Vector3(0.0, 0.0, -0.5), // 50cm in front of origin rotation: Vector4(1.0, 0.0, 0.0, 0.0), ); bool? success = await objectManager.addNode(node); if (success == true) { print("Model added successfully"); } } // Add a local GLTF model from app assets Future addLocalModel(ARObjectManager objectManager) async { var node = ARNode( type: NodeType.localGLTF2, uri: "Models/Chicken_01/Chicken_01.gltf", // Path in assets folder scale: Vector3(0.1, 0.1, 0.1), eulerAngles: Vector3(0, 3.14159, 0), // Rotate 180° on Y-axis ); await objectManager.addNode(node); } // Attach object to an anchor Future addObjectToAnchor( ARObjectManager objectManager, ARPlaneAnchor anchor, ) async { var node = ARNode( type: NodeType.webGLB, uri: "https://example.com/model.glb", scale: Vector3(0.15, 0.15, 0.15), position: Vector3(0.0, 0.0, 0.0), // Relative to anchor data: {"customData": "myValue"}, // Store custom metadata ); bool? success = await objectManager.addNode(node, planeAnchor: anchor); if (success == true) { print("Node attached to anchor: ${anchor.name}"); } } // Handle node tap events void setupNodeInteraction(ARObjectManager objectManager) { objectManager.onNodeTap = (List nodeNames) { print("Tapped nodes: ${nodeNames.join(', ')}"); }; objectManager.onPanEnd = (String nodeName, Matrix4 newTransform) { Vector3 newPosition = newTransform.getTranslation(); print("Node $nodeName moved to: $newPosition"); }; objectManager.onRotationEnd = (String nodeName, Matrix4 newTransform) { print("Node $nodeName rotated"); }; } // Remove a node from the scene void removeObject(ARObjectManager objectManager, ARNode node) { objectManager.removeNode(node); } ``` -------------------------------- ### Initialize ARView Widget and AR Session in Flutter Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Demonstrates how to set up the ARView widget and initialize the AR session manager within a Flutter application. This includes configuring plane detection, showing feature points, world origin, and enabling tap handling. It uses the ar_flutter_plugin library. ```dart import 'package:ar_flutter_plugin/ar_flutter_plugin.dart'; import 'package:ar_flutter_plugin/datatypes/config_planedetection.dart'; import 'package:ar_flutter_plugin/managers/ar_session_manager.dart'; import 'package:ar_flutter_plugin/managers/ar_object_manager.dart'; import 'package:ar_flutter_plugin/managers/ar_anchor_manager.dart'; import 'package:ar_flutter_plugin/managers/ar_location_manager.dart'; import 'package:flutter/material.dart'; class MyARScreen extends StatefulWidget { @override _MyARScreenState createState() => _MyARScreenState(); } class _MyARScreenState extends State { ARSessionManager? arSessionManager; ARObjectManager? arObjectManager; ARAnchorManager? arAnchorManager; ARLocationManager? arLocationManager; @override Widget build(BuildContext context) { return Scaffold( body: ARView( onARViewCreated: onARViewCreated, planeDetectionConfig: PlaneDetectionConfig.horizontalAndVertical, ), ); } void onARViewCreated( ARSessionManager arSessionManager, ARObjectManager arObjectManager, ARAnchorManager arAnchorManager, ARLocationManager arLocationManager, ) { this.arSessionManager = arSessionManager; this.arObjectManager = arObjectManager; this.arAnchorManager = arAnchorManager; this.arLocationManager = arLocationManager; this.arSessionManager!.onInitialize( showFeaturePoints: false, showPlanes: true, showWorldOrigin: true, handleTaps: true, ); this.arObjectManager!.onInitialize(); } @override void dispose() { arSessionManager?.dispose(); super.dispose(); } } ``` -------------------------------- ### Configure iOS Permissions in Podfile (Ruby) Source: https://github.com/cariuslars/ar_flutter_plugin/blob/main/README.md Configures necessary preprocessor definitions for camera, photos, location, sensors, and Bluetooth permissions within the iOS Podfile. This is crucial for AR features that rely on these device capabilities. ```ruby post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| # Additional configuration options could already be set here # BEGINNING OF WHAT YOU SHOULD ADD config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ '$(inherited)', ## dart: PermissionGroup.camera 'PERMISSION_CAMERA=1', ## dart: PermissionGroup.photos 'PERMISSION_PHOTOS=1', ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse] 'PERMISSION_LOCATION=1', ## dart: PermissionGroup.sensors 'PERMISSION_SENSORS=1', ## dart: PermissionGroup.bluetooth 'PERMISSION_BLUETOOTH=1', # add additional permission groups if required ] # END OF WHAT YOU SHOULD ADD end end end ``` -------------------------------- ### Create and Manage ARPlaneAnchor - Dart Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Illustrates creating an ARPlaneAnchor using a world transform obtained from a hit test result. It also covers creating anchors with cloud IDs for cloud anchor functionality, tracking child nodes attached to an anchor, and serializing/deserializing anchors. ```dart import 'package:ar_flutter_plugin/models/ar_anchor.dart'; import 'package:vector_math/vector_math_64.dart'; // Create anchor from hit test result ARPlaneAnchor createAnchorFromHitTest(Matrix4 worldTransform) { return ARPlaneAnchor( transformation: worldTransform, name: "myAnchor", // Optional: auto-generated if not provided ttl: 1, // Time to live in days (for cloud anchors) childNodes: [], // Will be populated when objects are attached ); } // Anchor with cloud ID (after upload) ARPlaneAnchor createCloudAnchor(Matrix4 transform, String cloudId) { return ARPlaneAnchor( transformation: transform, cloudanchorid: cloudId, ttl: 7, // Store in cloud for 7 days ); } // Track child nodes attached to anchor void trackChildNodes(ARPlaneAnchor anchor, String nodeName) { anchor.childNodes.add(nodeName); print("Anchor ${anchor.name} now has ${anchor.childNodes.length} children"); } // Serialize and deserialize anchors Map serializeAnchor(ARPlaneAnchor anchor) { return anchor.toJson(); } ARPlaneAnchor deserializeAnchor(Map json) { return ARPlaneAnchor.fromJson(json); } ``` -------------------------------- ### Create and Transform ARNode - Dart Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Demonstrates creating an ARNode with various properties like type, URI, position, scale, rotation, and custom data. It also shows how to modify transformations (position, scale, rotation) after creation using both Euler angles and quaternions, and how to access the current transformation matrix. ```dart import 'package:ar_flutter_plugin/models/ar_node.dart'; import 'package:ar_flutter_plugin/datatypes/node_types.dart'; import 'package:vector_math/vector_math_64.dart'; // Create node with position and rotation ARNode createNode() { return ARNode( type: NodeType.webGLB, uri: "https://example.com/model.glb", name: "myCustomNode", // Optional: auto-generated if not provided position: Vector3(0.0, 0.0, -1.0), scale: Vector3(0.5, 0.5, 0.5), eulerAngles: Vector3(0, 1.57, 0), // 90° rotation on Y-axis (radians) data: { "itemId": "123", "category": "furniture", "onTapText": "You tapped a chair!", }, ); } // Modify node transformation after creation void transformNode(ARNode node) { // Change position node.position = Vector3(1.0, 0.0, 0.0); // Change scale node.scale = Vector3(2.0, 2.0, 2.0); // Change rotation using euler angles node.eulerAngles = Vector3(0, 3.14159, 0); // 180° on Y-axis // Or set rotation using quaternion node.rotationFromQuaternion = Quaternion.euler(0.5, 0.5, 0); // Access current transformation matrix Matrix4 currentTransform = node.transform; Vector3 currentPosition = node.position; Vector3 currentScale = node.scale; Vector3 currentAngles = node.eulerAngles; } // Create node with transformation matrix ARNode createNodeWithMatrix(Matrix4 transformation) { return ARNode( type: NodeType.localGLTF2, uri: "Models/MyModel.gltf", transformation: transformation, ); } // Load model from device storage ARNode createNodeFromDevice() { return ARNode( type: NodeType.fileSystemAppFolderGLB, uri: "model.glb", // File in app's documents directory scale: Vector3(0.3, 0.3, 0.3), ); } ``` -------------------------------- ### Configure Location Services (iOS Info.plist) Source: https://github.com/cariuslars/ar_flutter_plugin/blob/main/cloudAnchorSetup.md These XML snippets are to be added to the Info.plist file in an iOS project to request location permissions. NSLocationWhenInUseUsageDescription is for foreground access, and NSLocationAlwaysUsageDescription is for background access. ```xml NSLocationWhenInUseUsageDescription This app needs access to location when open. ``` ```xml NSLocationAlwaysUsageDescription This app needs access to location when in the background. ``` -------------------------------- ### Configure AR Node Types and Plane Detection Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Demonstrates how to configure different 3D model node types (local GLTF, web GLB, file system) and plane detection modes (none, horizontal, vertical, both) using the ar_flutter_plugin. This is essential for setting up the AR environment and defining how surfaces are detected. ```dart import 'package:ar_flutter_plugin/datatypes/node_types.dart'; import 'package:ar_flutter_plugin/datatypes/config_planedetection.dart'; // NodeType options void nodeTypeExamples() { // Local GLTF file in Flutter assets folder NodeType localGLTF = NodeType.localGLTF2; // GLB file loaded from web URL NodeType webGLB = NodeType.webGLB; // GLB file in app's documents directory NodeType deviceGLB = NodeType.fileSystemAppFolderGLB; // GLTF file in app's documents directory NodeType deviceGLTF = NodeType.fileSystemAppFolderGLTF2; } // PlaneDetectionConfig options void planeDetectionExamples() { // No plane detection PlaneDetectionConfig noPlanesConfig = PlaneDetectionConfig.none; // Only horizontal planes (floors, tables) PlaneDetectionConfig horizontalConfig = PlaneDetectionConfig.horizontal; // Only vertical planes (walls) PlaneDetectionConfig verticalConfig = PlaneDetectionConfig.vertical; // Both horizontal and vertical planes PlaneDetectionConfig bothConfig = PlaneDetectionConfig.horizontalAndVertical; } ``` -------------------------------- ### Apply Firebase Google Services Plugin (Android) Source: https://github.com/cariuslars/ar_flutter_plugin/blob/main/cloudAnchorSetup.md This snippet demonstrates applying the Google Services plugin to the app-level build.gradle file in an Android project. This enables Firebase configuration processing. ```gradle apply plugin: 'com.google.gms.google-services' ``` -------------------------------- ### ARAnchorManager - Anchor and Cloud Anchor Management Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Manages anchors for persistent object placement and cloud synchronization. It allows for creating, removing, and managing anchors, as well as integrating with cloud anchor services like Google Cloud Anchors. ```APIDOC ## ARAnchorManager - Anchor and Cloud Anchor Management ### Description Manages anchors for persistent object placement and cloud synchronization. It allows for creating, removing, and managing anchors, as well as integrating with cloud anchor services like Google Cloud Anchors. ### Methods - **addAnchor(ARAnchor anchor)**: Adds an anchor to the AR scene. - **removeAnchor(ARAnchor anchor)**: Removes a specified anchor and all attached objects from the AR scene. - **initGoogleCloudAnchorMode()**: Initializes the AR system to use Google Cloud Anchor functionality. - **uploadAnchor(ARPlaneAnchor anchor)**: Initiates the upload of an anchor to Google Cloud. - **downloadAnchor(String cloudAnchorId)**: Initiates the download of an anchor from Google Cloud using its cloud ID. - **onAnchorUploaded**: Callback function triggered when an anchor has been successfully uploaded to the cloud. - **onAnchorDownloaded**: Callback function triggered when an anchor has been successfully downloaded from the cloud. Returns a map representing the serialized anchor. ### Code Examples #### Add an anchor to the scene ```dart import 'package:ar_flutter_plugin/managers/ar_anchor_manager.dart'; import 'package:ar_flutter_plugin/models/ar_anchor.dart'; import 'package:vector_math/vector_math_64.dart'; Future createAnchor( ARAnchorManager anchorManager, Matrix4 transform, ) async { var anchor = ARPlaneAnchor( transformation: transform, ttl: 2, // Time to live: 2 days for cloud anchors ); bool? success = await anchorManager.addAnchor(anchor); if (success == true) { print("Anchor created: ${anchor.name}"); } } ``` #### Remove an anchor and all attached objects ```dart void removeAnchor(ARAnchorManager anchorManager, ARAnchor anchor) { anchorManager.removeAnchor(anchor); } ``` #### Setup cloud anchor functionality with Firebase ```dart void setupCloudAnchors(ARAnchorManager anchorManager) { // Initialize Google Cloud Anchor mode anchorManager.initGoogleCloudAnchorMode(); // Handle successful anchor upload anchorManager.onAnchorUploaded = (ARAnchor anchor) { if (anchor is ARPlaneAnchor) { String cloudId = anchor.cloudanchorid ?? ""; print("Anchor uploaded with cloud ID: $cloudId"); // Save cloudId to your database (Firebase, etc.) } }; // Handle anchor download and resolution anchorManager.onAnchorDownloaded = (Map serializedAnchor) { ARPlaneAnchor anchor = ARPlaneAnchor.fromJson(serializedAnchor); print("Anchor downloaded: ${anchor.cloudanchorid}"); return anchor; }; } ``` #### Upload anchor to Google Cloud ```dart Future uploadToCloud( ARAnchorManager anchorManager, ARPlaneAnchor anchor, ) async { bool? success = await anchorManager.uploadAnchor(anchor); if (success == true) { print("Upload initiated for anchor: ${anchor.name}"); // Callback onAnchorUploaded will be triggered when complete } } ``` #### Download anchor from Google Cloud ```dart Future downloadFromCloud( ARAnchorManager anchorManager, String cloudAnchorId, ) async { await anchorManager.downloadAnchor(cloudAnchorId); // Callback onAnchorDownloaded will be triggered when resolved } ``` ``` -------------------------------- ### Import ar_flutter_plugin (Dart) Source: https://github.com/cariuslars/ar_flutter_plugin/blob/main/README.md Imports the ar_flutter_plugin library into your Dart code, making its AR functionalities available for use in your Flutter application. ```dart import 'package:ar_flutter_plugin/ar_flutter_plugin.dart'; ``` -------------------------------- ### AR Object Placement in Flutter Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt This Dart code implements a full AR experience for placing 3D objects on detected planes. It utilizes ar_flutter_plugin for AR functionalities like plane detection, object management, and session handling. The code requires Flutter and the ar_flutter_plugin package. It takes user taps on detected planes to place a GLB model and handles object removal. ```dart import 'package:ar_flutter_plugin/ar_flutter_plugin.dart'; import 'package:ar_flutter_plugin/datatypes/config_planedetection.dart'; import 'package:ar_flutter_plugin/datatypes/node_types.dart'; import 'package:ar_flutter_plugin/datatypes/hittest_result_types.dart'; import 'package:ar_flutter_plugin/managers/ar_session_manager.dart'; import 'package:ar_flutter_plugin/managers/ar_object_manager.dart'; import 'package:ar_flutter_plugin/managers/ar_anchor_manager.dart'; import 'package:ar_flutter_plugin/managers/ar_location_manager.dart'; import 'package:ar_flutter_plugin/models/ar_node.dart'; import 'package:ar_flutter_plugin/models/ar_anchor.dart'; import 'package:ar_flutter_plugin/models/ar_hittest_result.dart'; import 'package:flutter/material.dart'; import 'package:vector_math/vector_math_64.dart'; class ARObjectPlacementScreen extends StatefulWidget { @override _ARObjectPlacementScreenState createState() => _ARObjectPlacementScreenState(); } class _ARObjectPlacementScreenState extends State { ARSessionManager? arSessionManager; ARObjectManager? arObjectManager; ARAnchorManager? arAnchorManager; List nodes = []; List anchors = []; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('AR Object Placement')), body: Stack( children: [ ARView( onARViewCreated: onARViewCreated, planeDetectionConfig: PlaneDetectionConfig.horizontalAndVertical, ), Positioned( bottom: 20, left: 0, right: 0, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: onRemoveEverything, child: Text("Clear All"), ), ], ), ), ], ), ); } void onARViewCreated( ARSessionManager arSessionManager, ARObjectManager arObjectManager, ARAnchorManager arAnchorManager, ARLocationManager arLocationManager, ) { this.arSessionManager = arSessionManager; this.arObjectManager = arObjectManager; this.arAnchorManager = arAnchorManager; // Initialize session this.arSessionManager!.onInitialize( showFeaturePoints: false, showPlanes: true, customPlaneTexturePath: "Images/triangle.png", showWorldOrigin: true, handleTaps: true, ); this.arObjectManager!.onInitialize(); // Setup callbacks this.arSessionManager!.onPlaneOrPointTap = onPlaneOrPointTapped; this.arObjectManager!.onNodeTap = onNodeTapped; } Future onPlaneOrPointTapped(List hitTestResults) async { // Find plane hit var planeHit = hitTestResults.firstWhere( (hit) => hit.type == ARHitTestResultType.plane, orElse: () => hitTestResults.first, ); // Create anchor at tap location var newAnchor = ARPlaneAnchor( transformation: planeHit.worldTransform, ); bool? didAddAnchor = await arAnchorManager!.addAnchor(newAnchor); if (didAddAnchor == true) { anchors.add(newAnchor); // Add 3D model to anchor var newNode = ARNode( type: NodeType.webGLB, uri: "https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/Duck/glTF-Binary/Duck.glb", scale: Vector3(0.2, 0.2, 0.2), position: Vector3(0.0, 0.0, 0.0), ); bool? didAddNode = await arObjectManager!.addNode( newNode, planeAnchor: newAnchor, ); if (didAddNode == true) { nodes.add(newNode); } else { arSessionManager!.onError("Failed to add object"); } } else { arSessionManager!.onError("Failed to create anchor"); } } Future onNodeTapped(List nodeNames) async { arSessionManager!.onError("Tapped ${nodeNames.length} object(s)"); } Future onRemoveEverything() async { for (var anchor in anchors) { arAnchorManager!.removeAnchor(anchor); } anchors.clear(); nodes.clear(); } @override void dispose() { arSessionManager?.dispose(); super.dispose(); } } ``` -------------------------------- ### Android ProGuard Configuration for Google Cloud Auth Source: https://github.com/cariuslars/ar_flutter_plugin/blob/main/cloudAnchorSetup.md This configuration is required for the Android part of the Flutter application when using ProGuard. It ensures that necessary Google Auth classes and their members are kept during the obfuscation and shrinking process, preventing runtime errors. ```java buildTypes { release { ... proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } ``` ```proguard -keep class com.google.android.gms.common.** { *; } -keep class com.google.android.gms.auth.** { *; } -keep class com.google.android.gms.tasks.** { *; } ``` -------------------------------- ### Serialize and Deserialize ARNode - Dart Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Shows how to convert an ARNode object into a map for serialization (e.g., for saving or sending over a network) and how to reconstruct an ARNode object from a map, enabling persistence and data transfer. ```dart import 'package:ar_flutter_plugin/models/ar_node.dart'; // Serialize and deserialize nodes Map serializeNode(ARNode node) { return node.toMap(); } ARNode deserializeNode(Map map) { return ARNode.fromMap(map); } ``` -------------------------------- ### ARObjectManager - 3D Object Management Source: https://context7.com/cariuslars/ar_flutter_plugin/llms.txt Handles adding, removing, and transforming 3D objects in the AR scene. It supports loading models from the web or local assets, attaching them to anchors, and managing user interactions like taps and gestures. ```APIDOC ## ARObjectManager - 3D Object Management ### Description Handles adding, removing, and transforming 3D objects in the AR scene. It supports loading models from the web or local assets, attaching them to anchors, and managing user interactions like taps and gestures. ### Methods - **addNode(ARNode node, {ARPlaneAnchor? planeAnchor})**: Adds a 3D node to the AR scene. Can optionally be attached to a specific plane anchor. - **removeNode(ARNode node)**: Removes a specified node from the AR scene. - **onNodeTap**: Callback function triggered when a node is tapped. Receives a list of tapped node names. - **onPanEnd**: Callback function triggered when a pan gesture ends on a node. Receives the node name and the new transformation matrix. - **onRotationEnd**: Callback function triggered when a rotation gesture ends on a node. Receives the node name and the new transformation matrix. ### Code Examples #### Add a 3D model from the web ```dart import 'package:ar_flutter_plugin/managers/ar_object_manager.dart'; import 'package:ar_flutter_plugin/models/ar_node.dart'; import 'package:ar_flutter_plugin/models/ar_anchor.dart'; import 'package:ar_flutter_plugin/datatypes/node_types.dart'; import 'package:vector_math/vector_math_64.dart'; Future addWebModel(ARObjectManager objectManager) async { var node = ARNode( type: NodeType.webGLB, uri: "https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/Duck/glTF-Binary/Duck.glb", scale: Vector3(0.2, 0.2, 0.2), position: Vector3(0.0, 0.0, -0.5), // 50cm in front of origin rotation: Vector4(1.0, 0.0, 0.0, 0.0), ); bool? success = await objectManager.addNode(node); if (success == true) { print("Model added successfully"); } } ``` #### Add a local GLTF model from app assets ```dart Future addLocalModel(ARObjectManager objectManager) async { var node = ARNode( type: NodeType.localGLTF2, uri: "Models/Chicken_01/Chicken_01.gltf", // Path in assets folder scale: Vector3(0.1, 0.1, 0.1), eulerAngles: Vector3(0, 3.14159, 0), // Rotate 180° on Y-axis ); await objectManager.addNode(node); } ``` #### Attach object to an anchor ```dart Future addObjectToAnchor( ARObjectManager objectManager, ARPlaneAnchor anchor, ) async { var node = ARNode( type: NodeType.webGLB, uri: "https://example.com/model.glb", scale: Vector3(0.15, 0.15, 0.15), position: Vector3(0.0, 0.0, 0.0), // Relative to anchor data: {"customData": "myValue"}, // Store custom metadata ); bool? success = await objectManager.addNode(node, planeAnchor: anchor); if (success == true) { print("Node attached to anchor: ${anchor.name}"); } } ``` #### Handle node tap events ```dart void setupNodeInteraction(ARObjectManager objectManager) { objectManager.onNodeTap = (List nodeNames) { print("Tapped nodes: ${nodeNames.join(', ')}"); }; objectManager.onPanEnd = (String nodeName, Matrix4 newTransform) { Vector3 newPosition = newTransform.getTranslation(); print("Node $nodeName moved to: $newPosition"); }; objectManager.onRotationEnd = (String nodeName, Matrix4 newTransform) { print("Node $nodeName rotated"); }; } ``` #### Remove a node from the scene ```dart void removeObject(ARObjectManager objectManager, ARNode node) { objectManager.removeNode(node); } ``` ``` -------------------------------- ### Add Firebase Google Services Dependency (Android) Source: https://github.com/cariuslars/ar_flutter_plugin/blob/main/cloudAnchorSetup.md This snippet shows how to add the Google Services plugin dependency to the top-level build.gradle file for Android. This is necessary for Firebase integration. ```gradle classpath 'com.google.gms:google-services:4.3.3' ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.