diff --git a/examples/flutter/camera_manipulation/lib/main.dart b/examples/flutter/camera_manipulation/lib/main.dart new file mode 100644 index 00000000..79747988 --- /dev/null +++ b/examples/flutter/camera_manipulation/lib/main.dart @@ -0,0 +1,103 @@ +import 'dart:async'; +import 'package:flutter/services.dart'; +import 'package:logging/logging.dart'; +import 'package:flutter/material.dart'; +import 'package:thermion_flutter/thermion_flutter.dart'; + +void main() { + runApp(const MyApp()); + Logger.root.onRecord.listen((record) { + print(record); + }); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Thermion Demo', + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const MyHomePage(title: 'Thermion Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + final String title; + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + + late DelegateInputHandler _fixedOrbitInputHandler; + late DelegateInputHandler _freeFlightInputHandler; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) async { + _thermionViewer = await ThermionFlutterPlugin.createViewer(); + var assetData = await rootBundle.load("assets/cube.glb"); + var asset = + await _thermionViewer!.loadGltfFromBuffer(assetData.buffer.asUint8List(assetData.offsetInBytes), keepData: true, loadResourcesAsync: true); + await _thermionViewer!.loadSkybox("assets/default_env_skybox.ktx"); + await _thermionViewer!.loadIbl("assets/default_env_ibl.ktx"); + await _thermionViewer!.setPostProcessing(true); + await _thermionViewer!.setRendering(true); + + _fixedOrbitInputHandler = + DelegateInputHandler.fixedOrbit(_thermionViewer!) + ..setActionForType(InputType.MMB_HOLD_AND_MOVE, InputAction.ROTATE) + ..setActionForType(InputType.SCALE1, InputAction.ROTATE) + ..setActionForType(InputType.SCALE2, InputAction.ZOOM) + ..setActionForType(InputType.SCROLLWHEEL, InputAction.ZOOM); + + _freeFlightInputHandler = + DelegateInputHandler.flight(_thermionViewer!) + ..setActionForType(InputType.MMB_HOLD_AND_MOVE, InputAction.ROTATE) + ..setActionForType(InputType.SCALE1, InputAction.ROTATE) + ..setActionForType(InputType.SCALE2, InputAction.ZOOM) + ..setActionForType(InputType.SCROLLWHEEL, InputAction.ZOOM); + + setState(() {}); + }); + } + + ThermionViewer? _thermionViewer; + + bool isOrbit = true; + + @override + Widget build(BuildContext context) { + return Stack(children: [ + if (_thermionViewer != null) ...[ + Positioned.fill( + child: ThermionListenerWidget( + inputHandler: isOrbit + ? _fixedOrbitInputHandler : _freeFlightInputHandler, + child:ThermionWidget( + viewer: _thermionViewer!, + ))), + Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + ElevatedButton( + onPressed: () { + isOrbit = !isOrbit; + setState(() {}); + }, + child: Text("Switch to ${isOrbit ? "Free Flight" : "Orbit"}")) + ], + ) + ], + ]); + } +}