Files
cup_edit/docs/quickstart.mdx
2025-07-17 10:54:00 +08:00

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!');
},
),
);
}
}
```