doc: update camera_manipulation example project and docs
This commit is contained in:
@@ -16,14 +16,48 @@ This will generally wrap a `ThermionWidget`, meaning the entire viewport will ac
|
|||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: ThermionListenerWidget(
|
child: ThermionListenerWidget(
|
||||||
inputHandler:
|
inputHandler:
|
||||||
DelegateInputHandler.fixedOrbit(_thermionViewer!),
|
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),
|
||||||
child: ThermionWidget(
|
child: ThermionWidget(
|
||||||
viewer: _thermionViewer!,
|
viewer: _thermionViewer!,
|
||||||
))),
|
))),
|
||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
`ThermionListenerWidget` is a very simple widget; it simply forwards pointer, gesture and keyboard events to an instance of [InputHandler] that you provide.
|
`ThermionListenerWidget` is a very simple widget; it simply forwards pointer, gesture and keyboard events to the provided [InputHandler], which must decide how to interpret those events.
|
||||||
|
|
||||||
|
For example, one [InputHandler] implementation might interpret mouse pointer movement as "rotate the camera", whereas a separate implementation might interpret it as "translate this specific entity".
|
||||||
|
|
||||||
|
Thermion provides two default InputHandler implementations for manipulating the camera: [DelegateInputHandler.fixedOrbit] and [DelegateInputHandler.flight].
|
||||||
|
|
||||||
|
[DelegateInputHandler.fixedOrbit] will rotate the camera in a fixed orbit around a target point (the origin, by default), and also allow zooming in/out (subject to a minimum distance, which is configurable).
|
||||||
|
|
||||||
|
By default, [DelegateInputHandler.fixedOrbit] will:
|
||||||
|
- rotate the camera when the middle mouse button is held and the pointer is moved (on desktop), and when a single swipe left/right/up/down is detected (on mobile)
|
||||||
|
- zoom the camera when the scroll wheel is scrolled up/down (on desktop), and when a pinch gesture is detected (on mobile)
|
||||||
|
|
||||||
|
You can change the action for a specific input type by calling `setActionForType`; for example, if you wanted to rotate the camera by moving the mouse pointer while holding the left mouse button, you would call:
|
||||||
|
|
||||||
|
```
|
||||||
|
setActionForType(InputType.LMB_HOLD_AND_MOVE, InputAction.ROTATE)
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [InputType] and [InputAction] enums for available input types and actions.
|
||||||
|
|
||||||
|
[DelegateInputHandler.flight] will translate keyboard and mouse/touchscreen gestures to free flight camera manipulation.
|
||||||
|
|
||||||
|
By default:
|
||||||
|
- holding the middle mouse button will control the pitch/roll/yaw of the camera
|
||||||
|
- holding the left mouse button will pan the camera left/right/up/down
|
||||||
|
- the middle mouse button will zoom/dolly the camera in/out
|
||||||
|
- the WASD keys will pan the camera left/right/up/down and dolly the camera forward/backward
|
||||||
|
|
||||||
|
If these don't exactly fit your use case, you can create your own [InputHandler] implementation. If you think it would be useful to other users, please feel free to submit a PR for your implementation to be included in the base Thermion package.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ class MyHomePage extends StatefulWidget {
|
|||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
|
|
||||||
|
late DelegateInputHandler _fixedOrbitInputHandler;
|
||||||
|
late DelegateInputHandler _freeFlightInputHandler;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -48,27 +51,51 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
await _thermionViewer!.setPostProcessing(true);
|
await _thermionViewer!.setPostProcessing(true);
|
||||||
await _thermionViewer!.setRendering(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(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ThermionViewer? _thermionViewer;
|
ThermionViewer? _thermionViewer;
|
||||||
|
|
||||||
|
bool isOrbit = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Stack(children: [
|
return Stack(children: [
|
||||||
if (_thermionViewer != null)
|
if (_thermionViewer != null) ...[
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: ThermionListenerWidget(
|
child: ThermionListenerWidget(
|
||||||
inputHandler:
|
inputHandler: isOrbit
|
||||||
DelegateInputHandler.fixedOrbit(_thermionViewer!)
|
? _fixedOrbitInputHandler : _freeFlightInputHandler,
|
||||||
..setActionForType(InputType.MMB_HOLD_AND_MOVE, InputAction.ROTATE)
|
child:ThermionWidget(
|
||||||
..setActionForType(InputType.SCALE1, InputAction.ROTATE)
|
viewer: _thermionViewer!,
|
||||||
..setActionForType(InputType.SCALE2, InputAction.ZOOM)
|
))),
|
||||||
..setActionForType(InputType.SCROLLWHEEL, InputAction.ZOOM) ,
|
Column(
|
||||||
child: ThermionWidget(
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
viewer: _thermionViewer!,
|
children: [
|
||||||
))),
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
isOrbit = !isOrbit;
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Text("Switch to ${isOrbit ? "Free Flight" : "Orbit"}"))
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user