199 lines
6.0 KiB
Plaintext
199 lines
6.0 KiB
Plaintext
# Quick Start
|
|
|
|
If all you need is a quick and easy route to rendering a single 3D model in your Flutter application, start with `ViewerWidget`.
|
|
|
|
This is a simplified, Flutter-only wrapper around the underlying 3D rendering API with sane defaults for most people.
|
|
|
|
`ViewerWidget` handles all the setup and configuration of the underlying Thermion API, including:
|
|
- Loading 3D models (glTF assets)
|
|
- Configuring skyboxes and image-based lighting
|
|
- Setting up camera positions and manipulators
|
|
- Managing the rendering lifecycle
|
|
|
|
## Setup
|
|
|
|
Follow the steps listed in [Getting Started](./getting_started) to configure your Flutter installation and project.
|
|
|
|
If you're running Windows, delete the `examples/flutter/quickstart/assets` symlink and copy the `assets` folder from `examples/assets` to `examples/flutter/quickstart/assets`.
|
|
|
|
## Basic Usage
|
|
|
|
```dart
|
|
import 'package:flutter/material.dart';
|
|
import 'package:thermion_flutter/thermion_flutter.dart';
|
|
import 'path_to_your_viewer_widget.dart';
|
|
|
|
class MyApp extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
home: Scaffold(
|
|
body: ViewerWidget(
|
|
assetPath: 'assets/my_model.glb',
|
|
initialCameraPosition: Vector3(0, 0, 5),
|
|
manipulatorType: ManipulatorType.ORBIT,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Properties
|
|
|
|
| Property | Type | Default | Description |
|
|
|----------|------|---------|-------------|
|
|
| `initial` | `Widget` | Red decorated box | Widget to display while the viewer is loading |
|
|
| `initialCameraPosition` | `Vector3` | `Vector3(0, 0, 5)` | The starting position for the camera (looking towards origin) |
|
|
| `showFpsCounter` | `bool` | `false` | Whether to show an FPS counter overlay |
|
|
| `assetPath` | `String?` | `null` | Path to the glTF asset to load |
|
|
| `skyboxPath` | `String?` | `null` | Path to a KTX skybox image |
|
|
| `iblPath` | `String?` | `null` | Path to a KTX image for image-based lighting |
|
|
| `directLightType` | `LightType?` | `null` | Type of direct light to add to the scene |
|
|
| `transformToUnitCube` | `bool` | `true` | If true, rescales the model to fit within a 1x1x1 cube |
|
|
| `postProcessing` | `bool` | `true` | Enables ACES tone mapping and basic anti-aliasing |
|
|
| `background` | `Color?` | `null` | Background color (not visible when skybox is provided) |
|
|
| `destroyEngineOnUnload` | `bool` | `false` | If true, disposes the engine when widget is disposed |
|
|
| `manipulatorType` | `ManipulatorType` | `ORBIT` | Type of camera control to use |
|
|
| `onViewerAvailable` | `Future Function(ThermionViewer)?` | `null` | Callback when viewer is ready |
|
|
|
|
## Camera Manipulators
|
|
|
|
`ViewerWidget` supports three different camera manipulation modes:
|
|
|
|
- `ManipulatorType.NONE`: No camera controls, static view
|
|
- `ManipulatorType.ORBIT`: Orbit controls (pinch to zoom, swipe to rotate)
|
|
- `ManipulatorType.FREE_FLIGHT`: Free flight controls for unrestricted movement
|
|
|
|
Example:
|
|
|
|
```dart
|
|
ViewerWidget(
|
|
assetPath: 'assets/model.glb',
|
|
manipulatorType: ManipulatorType.FREE_FLIGHT,
|
|
)
|
|
```
|
|
|
|
## Lighting
|
|
|
|
You can set up lighting in multiple ways:
|
|
|
|
### Image-Based Lighting
|
|
|
|
```dart
|
|
ViewerWidget(
|
|
assetPath: 'assets/model.glb',
|
|
iblPath: 'assets/environment.ktx',
|
|
)
|
|
```
|
|
|
|
### Direct Light
|
|
|
|
```dart
|
|
ViewerWidget(
|
|
assetPath: 'assets/model.glb',
|
|
directLightType: LightType.SUN,
|
|
)
|
|
```
|
|
|
|
## Advanced Usage
|
|
|
|
### Accessing the Viewer
|
|
|
|
You can get access to the underlying `ThermionViewer` object for more advanced control:
|
|
|
|
```dart
|
|
ViewerWidget(
|
|
assetPath: 'assets/model.glb',
|
|
onViewerAvailable: (viewer) async {
|
|
// Now you can use the viewer directly
|
|
final camera = await viewer.getActiveCamera();
|
|
await camera.lookAt(Vector3(0, 1, 5));
|
|
|
|
// Add custom lights, manipulate materials, etc.
|
|
},
|
|
)
|
|
```
|
|
|
|
### Changing Manipulator at Runtime
|
|
|
|
The `manipulatorType` is the only property that can be changed after the widget is created:
|
|
|
|
```dart
|
|
class _MyWidgetState extends State<MyWidget> {
|
|
ManipulatorType _manipulatorType = ManipulatorType.ORBIT;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
Expanded(
|
|
child: ViewerWidget(
|
|
assetPath: 'assets/model.glb',
|
|
manipulatorType: _manipulatorType,
|
|
),
|
|
),
|
|
Row(
|
|
children: [
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
setState(() {
|
|
_manipulatorType = ManipulatorType.ORBIT;
|
|
});
|
|
},
|
|
child: Text('Orbit'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
setState(() {
|
|
_manipulatorType = ManipulatorType.FREE_FLIGHT;
|
|
});
|
|
},
|
|
child: Text('Free Flight'),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Limitations
|
|
|
|
- Only the `manipulatorType` property can be changed at runtime. For any other property changes, create a new widget.
|
|
- The widget requires that you have the correct environment setup for Thermion (Flutter master channel with native assets enabled).
|
|
|
|
## Example
|
|
|
|
Here's a complete example showing how to use `ViewerWidget` with multiple configuration options:
|
|
|
|
```dart
|
|
import 'package:flutter/material.dart';
|
|
import 'package:thermion_flutter/thermion_flutter.dart';
|
|
import 'package:vector_math/vector_math_64.dart';
|
|
|
|
class ModelViewer extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: Text('3D Model Viewer')),
|
|
body: ViewerWidget(
|
|
assetPath: 'assets/robot.glb',
|
|
skyboxPath: 'assets/studio_skybox.ktx',
|
|
iblPath: 'assets/studio_ibl.ktx',
|
|
initialCameraPosition: Vector3(0, 1.5, 3),
|
|
manipulatorType: ManipulatorType.ORBIT,
|
|
showFpsCounter: true,
|
|
background: Colors.grey,
|
|
postProcessing: true,
|
|
transformToUnitCube: true,
|
|
onViewerAvailable: (viewer) async {
|
|
// You can perform additional setup here
|
|
print('Viewer is ready!');
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
``` |