Skip to content

Rotation and Scaling not working on GLB file. #232

@Michael-Lyon

Description

@Michael-Lyon

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 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions