ViewerWidget Documentation
ViewerWidget
is a simplified wrapper around the Thermion 3D viewer that makes it easy to display 3D models in your Flutter application.
Overview
ViewerWidget
handles the setup and configuration of a Thermion viewer, including:
- Loading 3D models (glTF assets)
- Configuring skyboxes and image-based lighting
- Setting up camera positions and manipulators
- Managing the rendering lifecycle
Installation
First, make sure you have the Thermion Flutter plugin added to your dependencies:
dependencies:
thermion_flutter: ^latest_version
Basic Usage
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 viewManipulatorType.ORBIT
: Orbit controls (pinch to zoom, swipe to rotate)ManipulatorType.FREE_FLIGHT
: Free flight controls for unrestricted movement
Example:
ViewerWidget(
assetPath: 'assets/model.glb',
manipulatorType: ManipulatorType.FREE_FLIGHT,
)
Image-Based Lighting
ViewerWidget(
assetPath: 'assets/model.glb',
iblPath: 'assets/environment.ktx',
)
Accessing the Viewer
You can get access to the underlying ThermionViewer
object for more advanced control:
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:
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:
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!');
},
),
);
}
}