olexale / arkit_flutter_plugin

ARKit Flutter Plugin
MIT License
800 stars 228 forks source link

Unable to manipulate external 3D model #233

Open emeleonufavour opened 2 months ago

emeleonufavour commented 2 months ago

I have been trying to manipulate a 3D model from my assets folder. It neither detects the model when I tap it nor when I try to manipulate it. I can successfully manipulate a node if it's the default node eg sphere but all efforts to do the same to an external 3D model have seemed futile.

emeleonufavour commented 2 months ago

Here is my code

`import 'dart:async'; import 'dart:developer'; import 'dart:math' as math;

import 'package:arkit_plugin/arkit_plugin.dart'; import 'package:flutter/material.dart';

import 'package:vector_math/vector_math_64.dart' as vector;

import 'package:collection/collection.dart';

class TapPage extends StatefulWidget { @override _TapPageState createState() => _TapPageState(); }

class _TapPageState extends State { late ARKitController arkitController; ARKitSphere? sphere; ARKitNode? duckNode; ARKitNode? boxNode; ARKitBox? box; Timer? timer;

ARKitGltfNode _getNodeFromFlutterAsset() => ARKitGltfNode( name: "duck", assetType: AssetType.flutterAsset, url: 'assets/models/Duck.glb', scale: vector.Vector3(0.05, 0.05, 0.05), position: vector.Vector3(0, 0, -0.5));

@override void dispose() { timer?.cancel(); arkitController.dispose(); super.dispose(); }

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar(title: const Text('Tap Gesture Sample')), body: Container( child: ARKitSceneView( showFeaturePoints: true, enableTapRecognizer: true, enablePinchRecognizer: true, enablePanRecognizer: true, enableRotationRecognizer: true, onARKitViewCreated: onARKitViewCreated, ), ), );

void onARKitViewCreated(ARKitController arkitController) { this.arkitController = arkitController; this.arkitController.onNodeTap = (nodes) => onNodeTapHandler(nodes); this.arkitController.onNodePinch = (pinch) => _onPinchHandler(pinch); this.arkitController.onNodePan = (pan) => _onPanHandler(pan); this.arkitController.onNodeRotation = (rotation) => _onRotationHandler(rotation);

final material = ARKitMaterial(
  lightingModelName: ARKitLightingModel.lambert,
  diffuse: ARKitMaterialProperty.image('assets/models/IMG_0254.jpg'),
);
sphere = ARKitSphere(
  materials: [material],
  radius: 0.1,
);

box = ARKitBox(width: 10, height: 10, length: 10, materials: [material]);

// final node = _getNodeFromFlutterAsset();
duckNode = ARKitGltfNode(
    name: "duck",
    assetType: AssetType.flutterAsset,
    url: 'assets/models/Duck.glb',
    scale: vector.Vector3(0.05, 0.05, 0.05),
    position: vector.Vector3(0, 0, -0.5));

boxNode = ARKitNode(
  name: 'box',
  geometry: sphere,
  position: vector.Vector3(0, 0, -0.5),
  eulerAngles: vector.Vector3.zero(),
);
this.arkitController.add(boxNode!);

timer = Timer.periodic(const Duration(milliseconds: 50), (timer) {
  final rotation = boxNode!.eulerAngles;
  rotation.x += 0.01;
  boxNode!.eulerAngles = rotation;
});
// duckNode = node;
log(duckNode.toString());

}

void _onPinchHandler(List pinch) { log("Pinch detected: ${pinch.toString()}"); final pinchNode = pinch.firstWhereOrNull( (e) => e.nodeName == duckNode?.name, ); if (pinchNode != null) { final scale = vector.Vector3.all(pinchNode.scale); duckNode?.scale = scale; } }

void _onPanHandler(List pan) { final panNode = pan.firstWhereOrNull((e) => e.nodeName == duckNode?.name); if (panNode != null) { final old = duckNode?.eulerAngles; final newAngleY = panNode.translation.x * math.pi / 180; duckNode?.eulerAngles = vector.Vector3(old?.x ?? 0, newAngleY, old?.z ?? 0); } }

void _onRotationHandler(List rotation) { final rotationNode = rotation.firstWhereOrNull( (e) => e.nodeName == duckNode?.name, ); if (rotationNode != null) { final rotation = duckNode?.eulerAngles ?? vector.Vector3.zero() + vector.Vector3.all(rotationNode.rotation); duckNode?.eulerAngles = rotation; } }

void onNodeTapHandler(List nodesList) { log(nodesList.toString()); final name = nodesList.first; final color = (box!.materials.value!.first.diffuse as ARKitMaterialColor).color == Colors.yellow ? Colors.blue : Colors.yellow; box!.materials.value = [ ARKitMaterial(diffuse: ARKitMaterialProperty.color(color)) ];

showDialog<void>(
  context: context,
  builder: (BuildContext context) =>
      AlertDialog(content: Text('You tapped on $name')),
);

} } `

Michael-Lyon commented 2 months ago

I'm also experiencing the same issue @leeprobert