Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotation and Scaling not working on GLB file. #232

Open
Michael-Lyon opened this issue Aug 17, 2024 · 1 comment
Open

Rotation and Scaling not working on GLB file. #232

Michael-Lyon opened this issue Aug 17, 2024 · 1 comment

Comments

@Michael-Lyon
Copy link

Michael-Lyon commented Aug 17, 2024

I'm unable to implement Rotation or Pinching and it doesn't show me error.
I'm really grateful that you had put this project together it's been awesome. Thank you.
I'd appreciate some help or guidance to make this work please.

Here's my code

import 'dart:io';

import 'package:arkit_plugin/arkit_plugin.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:path_provider/path_provider.dart';
import 'package:vector_math/vector_math_64.dart' as vector;
import 'package:collection/collection.dart';
import 'dart:math' as math;

class ARGlbManipulationPage extends StatefulWidget {
  final String modelUrl;

  const ARGlbManipulationPage({Key? key, required this.modelUrl})
      : super(key: key);
  @override
  _ARGlbManipulationPageState createState() => _ARGlbManipulationPageState();
}

class _ARGlbManipulationPageState extends State<ARGlbManipulationPage> {
  late ARKitController arkitController;
  ARKitNode? modelNode;
  final Logger logger = Logger();
  @override
  void dispose() {
    arkitController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(title: const Text('Load and Manipulate GLB')),
        body: ARKitSceneView(
          showFeaturePoints: true,
          enableTapRecognizer: true,
          enablePinchRecognizer: true,
          enablePanRecognizer: true,
          enableRotationRecognizer: true,
          planeDetection: ARPlaneDetection.horizontal,
          onARKitViewCreated: onARKitViewCreated,
        ),
      );

  void onARKitViewCreated(ARKitController arkitController) {
    this.arkitController = arkitController;

    // Set up gesture handlers
    this.arkitController.onNodePinch = _onPinchHandler;
    this.arkitController.onNodePan = _onPanHandler;
    this.arkitController.onNodeRotation = _onRotationHandler;

    this.arkitController.onARTap = (ar) {
      final point = ar.firstWhereOrNull(
        (o) => o.type == ARKitHitTestResultType.featurePoint,
      );
      if (point != null) {
        _onARTapHandler(point);
      }
    };
  }

  void _onARTapHandler(ARKitTestResult point) {
    final position = vector.Vector3(
      point.worldTransform.getColumn(3).x,
      point.worldTransform.getColumn(3).y,
      point.worldTransform.getColumn(3).z,
    );

    _loadGLBModel(position);
  }

  Future<void> _loadGLBModel(vector.Vector3 position) async {
    final node = await _getNodeFromNetwork(position);
    arkitController.add(node);
    modelNode = node;
  }

  Future<ARKitGltfNode> _getNodeFromNetwork(vector.Vector3 position) async {
    // Assume this method downloads the GLB file and returns an ARKitGltfNode
    final file = await _downloadFile(widget.modelUrl); // Update with your URL
    if (file.existsSync()) {
      return ARKitGltfNode(
        assetType: AssetType.documents,
        url: file.path.split('/').last,
        scale: vector.Vector3(0.5, 0.5, 0.5),
        position: position,
      );
    }
    throw Exception('Failed to load $file');
  }

  Future<File> _downloadFile(String url) async {
    try {
      final dir = await getApplicationDocumentsDirectory();
      final filePath = '${dir.path}/${url.split("/").last}';
      await Dio().download(url, filePath);
      final file = File(filePath);
      print('Download completed!! path = $filePath');
      return file;
    } catch (e) {
      print('Caught an exception: $e');
      rethrow;
    }
  }

  void _onPinchHandler(List<ARKitNodePinchResult> pinchResults) {
    final pinch = pinchResults.firstWhereOrNull(
      (e) => e.nodeName == modelNode?.name,
    );
    if (pinch != null) {
      logger.d('Pinch detected: ${pinch.scale}'); // Debugging line
      final scale = vector.Vector3.all(pinch.scale);
      logger.d('Setting new scale: $scale'); // Debugging line
      modelNode?.scale = scale;
    } else {
      logger.d('Pinch not applied to the correct node.'); // Debugging line
    }
  }

  void _onPanHandler(List<ARKitNodePanResult> panResults) {
    final pan = panResults.firstWhereOrNull(
      (e) => e.nodeName == modelNode?.name,
    );
    if (pan != null) {
      final old = modelNode?.eulerAngles;
      final newAngleY = pan.translation.x * math.pi / 180;
      modelNode?.eulerAngles =
          vector.Vector3(old?.x ?? 0, newAngleY, old?.z ?? 0);
      logger.d('Pan detected: ${pan.translation}'); // Debugging line
      logger.d(
          'Setting new eulerAngles: ${modelNode?.eulerAngles}'); // Debugging line
    } else {
      logger.d("No pan found");
    }
  }

  void _onRotationHandler(List<ARKitNodeRotationResult> rotationResults) {
    final rotation = rotationResults.firstWhereOrNull(
      (e) => e.nodeName == modelNode?.name,
    );
    if (rotation != null) {
      final eulerAngles = modelNode?.eulerAngles ??
          vector.Vector3.zero() + vector.Vector3.all(rotation.rotation);
      modelNode?.eulerAngles = eulerAngles;
      logger.d('Rotation detected: ${rotation.rotation}'); // Debugging line
      logger.d(
          'Setting new eulerAngles: ${modelNode?.eulerAngles}'); // Debugging line
    } else {
      logger.d("No rotation found");
    }
  }
}
``` @OleksiiShvachenko @mribbons @leeprobert @dokkaebi 
@lecanhhiep
Copy link

There is actually a bug in GTLF code, I have issue with onNodeTap event .
Have you resolved your above issue ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants