import 'package:ar_flutter_plugin/managers/ar_location_manager.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/models/ar_anchor.dart'; import 'package:flutter/material.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/models/ar_node.dart'; import 'package:ar_flutter_plugin/models/ar_hittest_result.dart'; import 'package:flutter/services.dart'; import 'package:vector_math/vector_math_64.dart'; import 'dart:math'; class ObjectGesturesWidget extends StatefulWidget { ObjectGesturesWidget({Key? key}) : super(key: key); @override _ObjectGesturesWidgetState createState() => _ObjectGesturesWidgetState(); } class _ObjectGesturesWidgetState extends State { ARSessionManager? arSessionManager; ARObjectManager? arObjectManager; ARAnchorManager? arAnchorManager; List nodes = []; List anchors = []; @override void dispose() { super.dispose(); arSessionManager!.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Object Transformation Gestures'), ), body: Container( child: Stack(children: [ ARView( onARViewCreated: onARViewCreated, planeDetectionConfig: PlaneDetectionConfig.horizontalAndVertical, ), Align( alignment: FractionalOffset.bottomCenter, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton( onPressed: onRemoveEverything, child: Text("Remove Everything")), ]), ) ]))); } void onARViewCreated( ARSessionManager arSessionManager, ARObjectManager arObjectManager, ARAnchorManager arAnchorManager, ARLocationManager arLocationManager) { this.arSessionManager = arSessionManager; this.arObjectManager = arObjectManager; this.arAnchorManager = arAnchorManager; this.arSessionManager!.onInitialize( showFeaturePoints: false, showPlanes: true, customPlaneTexturePath: "Images/triangle.png", showWorldOrigin: true, handlePans: true, handleRotation: true, ); this.arObjectManager!.onInitialize(); this.arSessionManager!.onPlaneOrPointTap = onPlaneOrPointTapped; this.arObjectManager!.onPanStart = onPanStarted; this.arObjectManager!.onPanChange = onPanChanged; this.arObjectManager!.onPanEnd = onPanEnded; this.arObjectManager!.onRotationStart = onRotationStarted; this.arObjectManager!.onRotationChange = onRotationChanged; this.arObjectManager!.onRotationEnd = onRotationEnded; } Future onRemoveEverything() async { /*nodes.forEach((node) { this.arObjectManager.removeNode(node); });*/ anchors.forEach((anchor) { this.arAnchorManager!.removeAnchor(anchor); }); anchors = []; } Future onPlaneOrPointTapped( List hitTestResults) async { var singleHitTestResult = hitTestResults.firstWhere( (hitTestResult) => hitTestResult.type == ARHitTestResultType.plane); if (singleHitTestResult != null) { var newAnchor = ARPlaneAnchor(transformation: singleHitTestResult.worldTransform); bool? didAddAnchor = await this.arAnchorManager!.addAnchor(newAnchor); if (didAddAnchor!) { this.anchors.add(newAnchor); // Add note to anchor var newNode = ARNode( type: NodeType.webGLB, uri: "assets/files/Duck.glb", scale: Vector3(0.2, 0.2, 0.2), position: Vector3(0.0, 0.0, 0.0), rotation: Vector4(1.0, 0.0, 0.0, 0.0)); bool? didAddNodeToAnchor = await this.arObjectManager!.addNode(newNode, planeAnchor: newAnchor); if (didAddNodeToAnchor!) { this.nodes.add(newNode); } else { this.arSessionManager!.onError("Adding Node to Anchor failed"); } } else { this.arSessionManager!.onError("Adding Anchor failed"); } } } onPanStarted(String nodeName) { print("Started panning node " + nodeName); } onPanChanged(String nodeName) { print("Continued panning node " + nodeName); } onPanEnded(String nodeName, Matrix4 newTransform) { print("Ended panning node " + nodeName); final pannedNode = this.nodes.firstWhere((element) => element.name == nodeName); /* * Uncomment the following command if you want to keep the transformations of the Flutter representations of the nodes up to date * (e.g. if you intend to share the nodes through the cloud) */ //pannedNode.transform = newTransform; } onRotationStarted(String nodeName) { print("Started rotating node " + nodeName); } onRotationChanged(String nodeName) { print("Continued rotating node " + nodeName); } onRotationEnded(String nodeName, Matrix4 newTransform) { print("Ended rotating node " + nodeName); final rotatedNode = this.nodes.firstWhere((element) => element.name == nodeName); /* * Uncomment the following command if you want to keep the transformations of the Flutter representations of the nodes up to date * (e.g. if you intend to share the nodes through the cloud) */ //rotatedNode.transform = newTransform; } }