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

Fix #9 #15

Merged
merged 1 commit into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.4] - 2022-03-14

### Changed

- `/lib/src/model_viewer_plus_mobile.dart`, update according to the [newest document](https://developers.google.com/ar/develop/scene-viewer#3d-or-ar). Fix [#9](https://github.com/omchiii/model_viewer_plus.dart/issues/9).
- Insted of `com.google.ar.core`, now we use `com.google.android.googlequicksearchbox`. This should support the widest possible range of devices.
- Mode defaults to `ar_preferred`. Scene Viewer launches in AR native mode as the entry mode. If Google Play Services for AR isn't present, Scene Viewer gracefully falls back to 3D mode as the entry mode.
- Add `arModes` to example, closer to [modelviewer.dev](https://modelviewer.dev)'s offical example.
- Update `example\android\app\build.gradle` `compileSdkVersion` to 31
- Update `android_intent_plus` to `3.1.1`
- Update `android_intent_plus to` `3.0.1`

### Removed

- `/lib/src/http_proxy.dart`: empty file

## [1.1.3] - 2022-03-14

### Changed
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ web component in a [WebView](https://pub.dev/packages/webview_flutter).

Android, iOS, Web, with [a recent system browser version](https://modelviewer.dev/#section-browser-support).

## Notes

We use the [Google APP](https://play.google.com/store/apps/details?id=com.google.android.googlequicksearchbox), `com.google.android.googlequicksearchbox` to display interactive 3D models on Android. The model displays in 'ar_preferred' mode by default, Scene Viewer launches in AR native mode as the entry mode. If [Google Play Services for AR (ARCore, `com.google.ar.core`)](https://play.google.com/store/apps/details?id=com.google.ar.core) isn't present, Scene Viewer gracefully falls back to 3D mode as the entry mode.

## Installation

### `pubspec.yaml`

```yaml
dependencies:
model_viewer_plus: ^1.0.0
model_viewer_plus: ^(newest from https://pub.dev/packages/model_viewer_plus)
```

### `AndroidManifest.xml` (Android 9+ only)
Expand Down
2 changes: 1 addition & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 28
compileSdkVersion 31

lintOptions {
disable 'InvalidPackage'
Expand Down
3 changes: 2 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ class MyApp extends StatelessWidget {
appBar: AppBar(title: Text("Model Viewer")),
body: ModelViewer(
backgroundColor: Color.fromARGB(0xFF, 0xEE, 0xEE, 0xEE),
//src: 'https://modelviewer.dev/shared-assets/models/Astronaut.glb',
// src: 'https://modelviewer.dev/shared-assets/models/Astronaut.glb',
src: 'assets/Astronaut.glb', // a bundled asset file
alt: "A 3D model of an astronaut",
ar: true,
arModes: ['scene-viewer', 'webxr', 'quick-look'],
autoRotate: true,
cameraControls: true,
),
Expand Down
Empty file removed lib/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions lib/src/html_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ abstract class HTMLBuilder {
// TODO: shadow-intensity
// TODO: shadow-softness
html.writeln('></model-viewer>');

// print(html.toString()); // DEBUG

return html.toString();
}
}
1 change: 0 additions & 1 deletion lib/src/http_proxy.dart

This file was deleted.

63 changes: 49 additions & 14 deletions lib/src/model_viewer_plus_mobile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'dart:convert' show utf8;
import 'dart:io'
show File, HttpRequest, HttpServer, HttpStatus, InternetAddress, Platform;
import 'dart:typed_data' show Uint8List;
import 'package:path/path.dart' as p;

import 'package:android_intent_plus/flag.dart';
import 'package:flutter/material.dart';
Expand All @@ -21,6 +22,7 @@ class ModelViewerState extends State<ModelViewer> {
Completer<WebViewController>();

HttpServer? _proxy;
late String _proxyURL;

@override
void initState() {
Expand Down Expand Up @@ -59,35 +61,65 @@ class ModelViewerState extends State<ModelViewer> {
initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow,
onWebViewCreated: (final WebViewController webViewController) async {
_controller.complete(webViewController);
final host = _proxy!.address.address;
final port = _proxy!.port;
final url = "http://$host:$port/";
print('>>>> ModelViewer initializing... <$url>'); // DEBUG
await webViewController.loadUrl(url);
print('>>>> ModelViewer initializing... <$_proxyURL>'); // DEBUG
await webViewController.loadUrl(_proxyURL);
},
navigationDelegate: (final NavigationRequest navigation) async {
//print('>>>> ModelViewer wants to load: <${navigation.url}>'); // DEBUG
print('>>>> ModelViewer wants to load: <${navigation.url}>'); // DEBUG
if (!Platform.isAndroid) {
return NavigationDecision.navigate;
}
if (!navigation.url.startsWith("intent://")) {
return NavigationDecision.navigate;
}
try {
// Original, just keep as a backup
// See: https://developers.google.com/ar/develop/java/scene-viewer
// final intent = android_content.AndroidIntent(
// action: "android.intent.action.VIEW", // Intent.ACTION_VIEW
// data: "https://arvr.google.com/scene-viewer/1.0",
// arguments: <String, dynamic>{
// 'file': widget.src,
// 'mode': 'ar_preferred',
// },
// package: "com.google.ar.core",
// flags: <int>[
// Flag.FLAG_ACTIVITY_NEW_TASK
// ], // Intent.FLAG_ACTIVITY_NEW_TASK,
// );

// 2022-03-14 update
final String fileURL;
if (['http', 'https'].contains(Uri.parse(widget.src).scheme)) {
fileURL = widget.src;
} else {
fileURL = p.joinAll([_proxyURL, 'model']);
}
final intent = android_content.AndroidIntent(
action: "android.intent.action.VIEW", // Intent.ACTION_VIEW
data: "https://arvr.google.com/scene-viewer/1.0",
// See https://developers.google.com/ar/develop/scene-viewer#3d-or-ar
// data should be something like "https://arvr.google.com/scene-viewer/1.0?file=https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Avocado/glTF/Avocado.gltf"
data: Uri(
scheme: 'https',
host: 'arvr.google.com',
path: '/scene-viewer/1.0',
queryParameters: {
// 'title': '', // TODO: maybe set by the user
// TODO: further test, and make it 'ar_preferred'
'mode': 'ar_preferred',
'file': fileURL,
}).toString(),
// package changed to com.google.android.googlequicksearchbox
// to support the widest possible range of devices
package: "com.google.android.googlequicksearchbox",
arguments: <String, dynamic>{
'file': widget.src,
'mode': 'ar_only',
'browser_fallback_url':
'market://details?id=com.google.android.googlequicksearchbox'
},
package: "com.google.ar.core",
flags: <int>[
Flag.FLAG_ACTIVITY_NEW_TASK
], // Intent.FLAG_ACTIVITY_NEW_TASK,
);
await intent.launch();
await intent.launch().onError((error, stackTrace) {
print('>>>> ModelViewer Intent Error: $error'); // DEBUG
});
} catch (error) {
print('>>>> ModelViewer failed to launch AR: $error'); // DEBUG
}
Expand Down Expand Up @@ -130,6 +162,9 @@ class ModelViewerState extends State<ModelViewer> {

setState(() {
_proxy;
final host = _proxy!.address.address;
final port = _proxy!.port;
_proxyURL = "http://$host:$port/";
});

_proxy!.listen((final HttpRequest request) async {
Expand Down
3 changes: 0 additions & 3 deletions lib/src/model_viewer_plus_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import 'package:flutter/services.dart' show rootBundle;

import 'html_builder.dart';

// import 'dart:ui' as ui;
import 'shim/dart_ui_fake.dart' if (dart.library.html) 'dart:ui' as ui;
import 'shim/dart_html_fake.dart' if (dart.library.html) 'dart:html';
// import 'dart:html';

import 'model_viewer_plus.dart';

Expand Down Expand Up @@ -40,7 +38,6 @@ class ModelViewerState extends State<ModelViewer> {
'src',
'alt',
'poster',
'poster',
'seamless-poster',
'loading',
'reveal',
Expand Down
6 changes: 3 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# See: https://dart.dev/tools/pub/pubspec
name: model_viewer_plus
version: 1.1.3
version: 1.1.4
description: >-
A Flutter widget for rendering interactive 3D models in the glTF and GLB
formats.
Expand All @@ -14,8 +14,8 @@ platforms:
dependencies:
flutter:
sdk: flutter
android_intent_plus: ^3.0.2
webview_flutter: ^3.0.0
android_intent_plus: ^3.1.1
webview_flutter: ^3.0.1
dev_dependencies:
flutter_test:
sdk: flutter
Expand Down