CariusLars / ar_flutter_plugin

Flutter Plugin for AR (Augmented Reality) - Supports ARKit on iOS and ARCore on Android devices
MIT License
322 stars 233 forks source link

Help: How can I delete the selected object? #58

Closed raysonlim77 closed 2 years ago

raysonlim77 commented 2 years ago

I was able to delete the last insert object with the code below, but i wanted to delect the current selected object, it would be appreciated if you can provide me a sample code of delete current selected object, thanks.

Future onRemoveSingle() async { this.arAnchorManager.removeAnchor(this.anchors.last); }

CariusLars commented 2 years ago

Hey @raysonlim77 , you just need to keep track of your nodes, e.g. in a list:

List<ARNode> nodes = [];
ARNode|null selectedNode = null;

and add the nodes to this list whenever you add them to the scene:


    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:
                "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),
            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");
      }
    }
  }

Then, when a node is tapped (a.k.a. selected in your contex), you can simply obtain its reference by the name that the onNodeTapped function returns:

this.arObjectManager.onNodeTap = onNodeTapped;
Future<void> onNodeTapped(List<String> nodes) async {
  this.selectedNode = this.nodes.firstWhereOrNull((element) => element.name == nodes.first)
}

Then, whenever you want to delete the node (could be instantly in the function above):

this.arObjectManager.remove(this.selectedNode)
raysonlim77 commented 2 years ago

Not working, after i tap the delete button the node won't remove and my dubug console keep spaming E/native (18564): E1124 04:52:56.900078 18564 hit_test.cc:428] generic::internal: No point hit. I/GRALLOC (18564): LockFlexLayout: baseFormat: 11, uOffset: 307200, vOffset: 307200,uStride: 640

please find the code below for your reference.

List<ARNode> nodes = []; late ARNode selectedNode;

Future<void> onPlaneOrPointTapped( List<ARHitTestResult> hitTestResults) async { var singleHitTestResult = hitTestResults.firstWhere( (hitTestResult) => hitTestResult.type == ARHitTestResultType.plane); if (singleHitTestResult != null) { var newAnchor = ARPlaneAnchor( transformation: singleHitTestResult.worldTransform, ttl: 2); bool? didAddAnchor = await this.arAnchorManager.addAnchor(newAnchor); if (didAddAnchor == true) { this.anchors.add(newAnchor); var newNode = ARNode( type: NodeType.webGLB, uri: widget.models[indexModel].modelUrl!, scale: VectorMath.Vector3(0.4, 0.4, 0.4), position: VectorMath.Vector3(0.0, 0.0, 0.0), rotation: VectorMath.Vector4(1.0, 0.0, 0.0, 0.0), data: {"onTapText": widget.models[indexModel].eWord}); bool? didAddNodeToAnchor = await this.arObjectManager.addNode(newNode, planeAnchor: newAnchor); if (didAddNodeToAnchor == true) { this.nodes.add(newNode); setState(() { readyToUpload = true; }); } else { this.arSessionManager.onError("Adding Node to Anchor failed"); } } else { this.arSessionManager.onError("Adding Anchor failed"); } } }

Future<void> onRemoveSingle() async {this.arObjectManager.removeNode(this.selectedNode); }

Future<void> onNodeTapped(List<String> nodes) async { selectedNode = this.nodes.firstWhereOrNull((element) => element.name == nodes.first)!; }

Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 2.5.3, on macOS 12.0.1 21A559 darwin-arm, locale en-GB) [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3) [✓] Xcode - develop for iOS and macOS [✓] Chrome - develop for the web [✓] Android Studio (version 4.2) [✓] VS Code (version 1.62.0) [✓] Connected device (2 available)

CariusLars commented 2 years ago

hey @raysonlim77 ,

at a first glance, I can see that you're not setting this.arObjectManager.onNodeTap = onNodeTapped, so the function will never get called. Make sure to do that and then set some breakpoints to check that the function actually gets called and that when onRemoveSingle() is called, check that the variable this.selectedNode has the correct value

as a side note: your code is really hard to read this way, please add some line breaks next time.

raysonlim77 commented 2 years ago

The code is inside OnARViewCreated as below but still not working, The rotate function and I even created the scale function by myself ,both are working, only the delete is not working right now , maybe I should use this.arAnchorManager to remove ? Because the remove everything is working too

this.arSessionManager.onPlaneOrPointTap = onPlaneOrPointTapped; this.arObjectManager.onNodeTap = onNodeTapped; this.arObjectManager.onPanStart = onPanStarted; this.arObjectManager.onPanChange = onPanChanged; this.arObjectManager.onPanEnd = onPanEnded; this.arObjectManager.onRotationStart = onRotationStarted; this.arObjectManager.onRotationChange = onRotationChanged; this.arObjectManager.onRotationEnd = onRotationEnded;

CariusLars commented 2 years ago

First of all, good job on creating the scale function, could you open a PR to the develop branch so I can include the feature in the new release?

As to your problem: It's really weird, could you set some breakpoints in your code to make sure this.selectedNode has the correct value before you pass it to the arObjectManager? Of course you could also use the arAnchorManager as a workaround to remove the anchor the node is attached to (or remove everything), as this will loop through the anchor's children and remove all of them

samatzp commented 2 years ago

@CariusLars Hello! arObjectManager.removeNode(selectedNode) does work(

We have other way to remove selected object?