update example project

This commit is contained in:
Nick Fisher
2024-02-15 13:47:22 +08:00
parent 0b315f3dfe
commit da123d6274
5 changed files with 108 additions and 19 deletions

View File

@@ -1,26 +1,36 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_filament/entities/entity_transform_controller.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament/widgets/entity_controller_mouse_widget.dart';
import 'package:flutter_filament/widgets/filament_gesture_detector.dart';
import 'package:flutter_filament/widgets/filament_widget.dart';
class ExampleViewport extends StatelessWidget {
final FilamentController? controller;
final EntityTransformController? entityTransformController;
final EdgeInsets padding;
final FocusNode keyboardFocusNode;
const ExampleViewport(
{super.key, required this.controller, required this.padding});
{super.key,
required this.controller,
required this.padding,
required this.keyboardFocusNode,
this.entityTransformController});
@override
Widget build(BuildContext context) {
return controller != null
? Padding(
padding: padding,
child: FilamentGestureDetector(
showControlOverlay: true,
controller: controller!,
child: FilamentWidget(
controller: controller!,
)))
child: EntityTransformMouseControllerWidget(
transformController: entityTransformController,
child: FilamentGestureDetector(
showControlOverlay: true,
controller: controller!,
child: FilamentWidget(
controller: controller!,
))))
: Container();
}
}

View File

@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_filament/entities/entity_transform_controller.dart';
import 'package:flutter_filament/filament_controller_ffi.dart';
import 'package:flutter_filament_example/camera_matrix_overlay.dart';
import 'package:flutter_filament_example/menus/controller_menu.dart';
@@ -11,9 +12,11 @@ import 'package:flutter_filament_example/menus/scene_menu.dart';
import 'package:flutter_filament/filament_controller.dart';
const loadDefaultScene = bool.hasEnvironment('--load-default-scene');
const foo = String.fromEnvironment('foo');
void main() async {
print(loadDefaultScene);
print(foo);
runApp(const MyApp());
}
@@ -99,6 +102,9 @@ class ExampleWidgetState extends State<ExampleWidget> {
await _filamentController!.loadGlb("assets/shapes/shapes.glb"));
ExampleWidgetState.animations =
await _filamentController!.getAnimationNames(assets.first);
await _filamentController!
.setCameraManipulatorOptions(zoomSpeed: 1.0);
hasSkybox = true;
rendering = true;
});
@@ -112,6 +118,10 @@ class ExampleWidgetState extends State<ExampleWidget> {
_listener.cancel();
}
EntityTransformController? _transformController;
FilamentEntity? _controlled;
final _sharedFocusNode = FocusNode();
Widget _assetEntry(FilamentEntity entity) {
return Row(children: [
Text("Asset ${entity}"),
@@ -121,13 +131,28 @@ class ExampleWidgetState extends State<ExampleWidget> {
await _filamentController!.transformToUnitCube(entity);
},
icon: const Icon(Icons.settings_overscan_outlined)),
IconButton(
onPressed: () async {
_transformController?.dispose();
if (_controlled == entity) {
_controlled = null;
} else {
_controlled = entity;
_transformController?.dispose();
_transformController =
EntityTransformController(_filamentController!, entity);
}
setState(() {});
},
icon: Icon(Icons.control_camera,
color: _controlled == entity ? Colors.green : Colors.black)),
IconButton(
onPressed: () async {
await _filamentController!.removeAsset(entity);
assets.remove(entity);
setState(() {});
},
icon: const Icon(Icons.cancel_sharp))
icon: const Icon(Icons.cancel_sharp)),
]);
;
}
@@ -137,9 +162,10 @@ class ExampleWidgetState extends State<ExampleWidget> {
return Stack(children: [
Positioned.fill(
child: ExampleViewport(
controller: _filamentController,
padding: _viewportMargin,
),
controller: _filamentController,
entityTransformController: _transformController,
padding: _viewportMargin,
keyboardFocusNode: _sharedFocusNode),
),
Positioned(
bottom: 80,
@@ -147,7 +173,7 @@ class ExampleWidgetState extends State<ExampleWidget> {
height: 200,
width: 300,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 10),
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 10),
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
@@ -169,6 +195,7 @@ class ExampleWidgetState extends State<ExampleWidget> {
child:
Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
ControllerMenu(
sharedFocusNode: _sharedFocusNode,
controller: _filamentController,
onControllerDestroyed: () {},
onControllerCreated: (controller) {
@@ -188,6 +215,7 @@ class ExampleWidgetState extends State<ExampleWidget> {
});
}),
SceneMenu(
sharedFocusNode: _sharedFocusNode,
controller: _filamentController,
),
GestureDetector(

View File

@@ -4,6 +4,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_filament/animations/animation_data.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament_example/main.dart';
import 'package:permission_handler/permission_handler.dart';
@@ -27,8 +28,22 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
Widget _shapesSubmenu() {
var children = [
MenuItemButton(
closeOnActivate: false,
onPressed: () async {
Timer.periodic(Duration(milliseconds: 50), (_) async {
var entity = await widget.controller
.getChildEntity(ExampleWidgetState.assets.last, "Cylinder");
await showDialog(
context: context,
builder: (BuildContext context) {
return Center(
child: Container(
color: Colors.white, child: Text(entity.toString())));
});
},
child: const Text('Find Cylinder entity by name')),
MenuItemButton(
onPressed: () async {
Timer.periodic(const Duration(milliseconds: 50), (_) async {
await widget.controller.setBoneTransform(
ExampleWidgetState.assets.last,
"Cylinder",
@@ -143,11 +158,40 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
return SubmenuButton(menuChildren: children, child: const Text("Shapes"));
}
Widget _geometrySubmenu() {
return MenuItemButton(
onPressed: () async {
await widget.controller.createGeometry([
-1,
0,
-1,
-1,
0,
1,
1,
0,
1,
1,
0,
-1,
], [
0,
1,
2,
2,
3,
0
], "asset://assets/solidcolor.filamat");
},
child: const Text("Custom geometry"));
}
@override
Widget build(BuildContext context) {
return SubmenuButton(
menuChildren: [
_shapesSubmenu(),
_geometrySubmenu(),
MenuItemButton(
onPressed: () async {
ExampleWidgetState.directionalLight = await widget.controller

View File

@@ -9,11 +9,13 @@ class ControllerMenu extends StatefulWidget {
final FilamentController? controller;
final void Function(FilamentController controller) onControllerCreated;
final void Function() onControllerDestroyed;
final FocusNode sharedFocusNode;
ControllerMenu(
{this.controller,
required this.onControllerCreated,
required this.onControllerDestroyed});
required this.onControllerDestroyed,
required this.sharedFocusNode});
@override
State<StatefulWidget> createState() => _ControllerMenuState();
@@ -21,7 +23,6 @@ class ControllerMenu extends StatefulWidget {
class _ControllerMenuState extends State<ControllerMenu> {
FilamentController? _filamentController;
final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Camera Menu');
void _createController({String? uberArchivePath}) {
if (_filamentController != null) {
@@ -57,8 +58,10 @@ class _ControllerMenuState extends State<ControllerMenu> {
child: const Text("Create FilamentViewer"),
onPressed: _filamentController == null
? null
: () {
_filamentController!.createViewer();
: () async {
await _filamentController!.createViewer();
await _filamentController!
.setCameraManipulatorOptions(zoomSpeed: 1.0);
},
),
MenuItemButton(
@@ -96,7 +99,7 @@ class _ControllerMenuState extends State<ControllerMenu> {
]);
}
return MenuAnchor(
childFocusNode: _buttonFocusNode,
childFocusNode: widget.sharedFocusNode,
menuChildren: items,
builder:
(BuildContext context, MenuController controller, Widget? child) {

View File

@@ -7,8 +7,10 @@ import 'package:flutter_filament_example/menus/rendering_submenu.dart';
class SceneMenu extends StatefulWidget {
final FilamentController? controller;
final FocusNode sharedFocusNode;
const SceneMenu({super.key, required this.controller});
const SceneMenu(
{super.key, required this.controller, required this.sharedFocusNode});
@override
State<StatefulWidget> createState() {
@@ -34,6 +36,8 @@ class _SceneMenuState extends State<SceneMenu> {
widget.controller?.hasViewer ?? ValueNotifier<bool>(false),
builder: (BuildContext ctx, bool hasViewer, Widget? child) {
return MenuAnchor(
onClose: () {},
childFocusNode: widget.sharedFocusNode,
menuChildren: widget.controller == null
? []
: <Widget>[