olexale / arkit_flutter_plugin

ARKit Flutter Plugin
MIT License
797 stars 225 forks source link

Flutter arkit_plugin: ^0.6.0 rotate image error #124

Open davidRuland1234 opened 3 years ago

davidRuland1234 commented 3 years ago

Hi, I am using arkit_plugin: ^0.6.0 and I want my image to follow camera in portrait mode. But when I align my image in ArkitSceneView with worldAlignment: ARWorldAlignment.camera its rotate my image to landscape. How do I fix so that my image always follow camera in portrait mode instead of landscape?

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;

class WidgetProjectionPage extends StatefulWidget {
  @override
  _WidgetProjectionPageState createState() => _WidgetProjectionPageState();
}
class _WidgetProjectionPageState extends State<WidgetProjectionPage> {

ARKitController arkitController; bool anchorWasFound = false; Widget imageHolder; bool visible = true; ARKitPlane plane; double imageWidth = 0.4; double imageHeight = 0.5; double x = 0, y = 0, z = -1.5; String anchorId; Matrix4 transform = Matrix4.identity(); vector.Vector3 position; vector.Vector4 rotation;

  @override
  void dispose() {
    arkitController?.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) => Scaffold(
      appBar: AppBar(
        title: const Text('Widget Projection'),
      ),
      body: Container(
    child: Stack(fit: StackFit.expand, children: [
      InteractiveViewer(
        minScale: 0.5,
        maxScale: 5.0,
        panEnabled: true,
        scaleEnabled: true,
        child: imageHolder = ARKitSceneView(
          detectionImagesGroupName: 'AR Resources',
          onARKitViewCreated: onARKitViewCreated,
          enablePanRecognizer: true,
          enablePinchRecognizer: true,
          enableRotationRecognizer: true,
          worldAlignment: ARWorldAlignment.camera,
          planeDetection: ARPlaneDetection.horizontalAndVertical,
     ]),
  ),
);

} void onARKitViewCreated(ARKitController arkitController) { this.arkitController = arkitController; this.arkitController.add(_addImage()); this.arkitController.onAddNodeForAnchor = _handleAddAnchor; this.arkitController.onUpdateNodeForAnchor = _handleUpdateAnchor; } void _handleAddAnchor(ARKitAnchor anchor) { if (anchor is ARKitImageAnchor) { anchorId = anchor.identifier; _updatePosition(anchor); _updateRotation(anchor); } } Future _updateRotation(ARKitAnchor anchor) async { final t = anchor.transform.clone(); t.invertRotation(); t.rotateZ(math.pi / 2); t.rotateX(math.pi / 2); setState(() { transform = t; }); } void _handleUpdateAnchor(ARKitAnchor anchor) { if (anchor.identifier == anchorId) { _updatePosition(anchor); _updateRotation(anchor); } } Future _updatePosition(ARKitImageAnchor anchor) async { final transform = anchor.transform; final vector.Vector4 topRight = vector.Vector4(imageWidth, 0, -imageHeight, 1)..applyMatrix4(transform); final vector.Vector4 bottomRight = vector.Vector4(imageWidth, 0, imageHeight, 1)..applyMatrix4(transform); final vector.Vector4 bottomLeft = vector.Vector4(-imageWidth, 0, -imageHeight, 1) ..applyMatrix4(transform); final vector.Vector4 topLeft = vector.Vector4(-imageWidth, 0, imageHeight, 1)..applyMatrix4(transform); final pointsWorldSpace = [topRight, bottomRight, bottomLeft, topLeft]; final pointsViewportSpace = pointsWorldSpace.map( (p) => arkitController.projectPoint(vector.Vector3(p.x, p.y, p.z))); final pointsViewportSpaceResults = await Future.wait(pointsViewportSpace); setState(() { x = pointsViewportSpaceResults[2].x; y = pointsViewportSpaceResults[2].y; this.imageWidth = pointsViewportSpaceResults[0] .distanceTo(pointsViewportSpaceResults[3]); this.imageHeight = pointsViewportSpaceResults[1] .distanceTo(pointsViewportSpaceResults[2]); }); } ARKitNode _addImage() { plane = ARKitPlane( width: imageWidth, height: imageHeight, materials: [ ARKitMaterial( diffuse: ARKitMaterialProperty( image: 'assets/images/test.png'), ) ], ); return ARKitNode( geometry: plane, position: position); } } import 'package:arkit_plugin_example/check_support_page.dart'; import 'package:arkit_plugin_example/custom_animation_page.dart'; import 'package:arkit_plugin_example/custom_object_page.dart'; import 'package:arkit_plugin_example/distance_tracking_page.dart'; import 'package:arkit_plugin_example/custom_light_page.dart'; import 'package:arkit_plugin_example/earth_page.dart'; import 'package:arkit_plugin_example/hello_world.dart'; import 'package:arkit_plugin_example/image_detection_page.dart'; import 'package:arkit_plugin_example/light_estimate_page.dart'; import 'package:arkit_plugin_example/manipulation_page.dart'; import 'package:arkit_plugin_example/measure_page.dart'; import 'package:arkit_plugin_example/network_image_detection.dart'; import 'package:arkit_plugin_example/occlusion_page.dart'; import 'package:arkit_plugin_example/physics_page.dart'; import 'package:arkit_plugin_example/plane_detection_page.dart'; import 'package:arkit_plugin_example/tap_page.dart'; import 'package:arkit_plugin_example/face_detection_page.dart'; import 'package:arkit_plugin_example/panorama_page.dart'; import 'package:arkit_plugin_example/widget_projection.dart'; import 'package:arkit_plugin_example/real_time_updates.dart'; import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: MyApp()));

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final samples = [ Sample( 'Widget Projection', 'Flutter widgets in AR', Icons.widgets, () => Navigator.of(context).push( MaterialPageRoute(builder: (c) => WidgetProjectionPage())), ), Sample( 'Real Time Updates', 'Calls a function once per frame', Icons.timer, () => Navigator.of(context).push( MaterialPageRoute(builder: (c) => RealTimeUpdatesPage())), ), ];

return Scaffold(
  appBar: AppBar(
    title: const Text('ARKit Demo'),
  ),
  body:
      ListView(children: samples.map((s) => SampleItem(item: s)).toList()),
);

} }

class SampleItem extends StatelessWidget { const SampleItem({Key key, this.item}) : super(key: key); final Sample item;

@override Widget build(BuildContext context) { return Card( child: InkWell( onTap: () => item.onTap(), child: ListTile( leading: Icon(item.icon), title: Text( item.title, style: Theme.of(context).textTheme.subtitle1, ), subtitle: Text( item.description, style: Theme.of(context).textTheme.subtitle2, ), ), ), ); } }

class Sample { const Sample(this.title, this.description, this.icon, this.onTap); final String title; final String description; final IconData icon; final Function onTap; }