update example project
This commit is contained in:
@@ -1,26 +1,36 @@
|
|||||||
import 'package:flutter/widgets.dart';
|
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/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_gesture_detector.dart';
|
||||||
import 'package:flutter_filament/widgets/filament_widget.dart';
|
import 'package:flutter_filament/widgets/filament_widget.dart';
|
||||||
|
|
||||||
class ExampleViewport extends StatelessWidget {
|
class ExampleViewport extends StatelessWidget {
|
||||||
final FilamentController? controller;
|
final FilamentController? controller;
|
||||||
|
final EntityTransformController? entityTransformController;
|
||||||
final EdgeInsets padding;
|
final EdgeInsets padding;
|
||||||
|
final FocusNode keyboardFocusNode;
|
||||||
|
|
||||||
const ExampleViewport(
|
const ExampleViewport(
|
||||||
{super.key, required this.controller, required this.padding});
|
{super.key,
|
||||||
|
required this.controller,
|
||||||
|
required this.padding,
|
||||||
|
required this.keyboardFocusNode,
|
||||||
|
this.entityTransformController});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return controller != null
|
return controller != null
|
||||||
? Padding(
|
? Padding(
|
||||||
padding: padding,
|
padding: padding,
|
||||||
child: FilamentGestureDetector(
|
child: EntityTransformMouseControllerWidget(
|
||||||
showControlOverlay: true,
|
transformController: entityTransformController,
|
||||||
controller: controller!,
|
child: FilamentGestureDetector(
|
||||||
child: FilamentWidget(
|
showControlOverlay: true,
|
||||||
controller: controller!,
|
controller: controller!,
|
||||||
)))
|
child: FilamentWidget(
|
||||||
|
controller: controller!,
|
||||||
|
))))
|
||||||
: Container();
|
: Container();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
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/filament_controller_ffi.dart';
|
||||||
import 'package:flutter_filament_example/camera_matrix_overlay.dart';
|
import 'package:flutter_filament_example/camera_matrix_overlay.dart';
|
||||||
import 'package:flutter_filament_example/menus/controller_menu.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';
|
import 'package:flutter_filament/filament_controller.dart';
|
||||||
|
|
||||||
const loadDefaultScene = bool.hasEnvironment('--load-default-scene');
|
const loadDefaultScene = bool.hasEnvironment('--load-default-scene');
|
||||||
|
const foo = String.fromEnvironment('foo');
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
print(loadDefaultScene);
|
print(loadDefaultScene);
|
||||||
|
print(foo);
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +102,9 @@ class ExampleWidgetState extends State<ExampleWidget> {
|
|||||||
await _filamentController!.loadGlb("assets/shapes/shapes.glb"));
|
await _filamentController!.loadGlb("assets/shapes/shapes.glb"));
|
||||||
ExampleWidgetState.animations =
|
ExampleWidgetState.animations =
|
||||||
await _filamentController!.getAnimationNames(assets.first);
|
await _filamentController!.getAnimationNames(assets.first);
|
||||||
|
await _filamentController!
|
||||||
|
.setCameraManipulatorOptions(zoomSpeed: 1.0);
|
||||||
|
|
||||||
hasSkybox = true;
|
hasSkybox = true;
|
||||||
rendering = true;
|
rendering = true;
|
||||||
});
|
});
|
||||||
@@ -112,6 +118,10 @@ class ExampleWidgetState extends State<ExampleWidget> {
|
|||||||
_listener.cancel();
|
_listener.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityTransformController? _transformController;
|
||||||
|
FilamentEntity? _controlled;
|
||||||
|
final _sharedFocusNode = FocusNode();
|
||||||
|
|
||||||
Widget _assetEntry(FilamentEntity entity) {
|
Widget _assetEntry(FilamentEntity entity) {
|
||||||
return Row(children: [
|
return Row(children: [
|
||||||
Text("Asset ${entity}"),
|
Text("Asset ${entity}"),
|
||||||
@@ -121,13 +131,28 @@ class ExampleWidgetState extends State<ExampleWidget> {
|
|||||||
await _filamentController!.transformToUnitCube(entity);
|
await _filamentController!.transformToUnitCube(entity);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.settings_overscan_outlined)),
|
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(
|
IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await _filamentController!.removeAsset(entity);
|
await _filamentController!.removeAsset(entity);
|
||||||
assets.remove(entity);
|
assets.remove(entity);
|
||||||
setState(() {});
|
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: [
|
return Stack(children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: ExampleViewport(
|
child: ExampleViewport(
|
||||||
controller: _filamentController,
|
controller: _filamentController,
|
||||||
padding: _viewportMargin,
|
entityTransformController: _transformController,
|
||||||
),
|
padding: _viewportMargin,
|
||||||
|
keyboardFocusNode: _sharedFocusNode),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 80,
|
bottom: 80,
|
||||||
@@ -147,7 +173,7 @@ class ExampleWidgetState extends State<ExampleWidget> {
|
|||||||
height: 200,
|
height: 200,
|
||||||
width: 300,
|
width: 300,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 10),
|
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 10),
|
||||||
height: 100,
|
height: 100,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(30),
|
borderRadius: BorderRadius.circular(30),
|
||||||
@@ -169,6 +195,7 @@ class ExampleWidgetState extends State<ExampleWidget> {
|
|||||||
child:
|
child:
|
||||||
Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||||
ControllerMenu(
|
ControllerMenu(
|
||||||
|
sharedFocusNode: _sharedFocusNode,
|
||||||
controller: _filamentController,
|
controller: _filamentController,
|
||||||
onControllerDestroyed: () {},
|
onControllerDestroyed: () {},
|
||||||
onControllerCreated: (controller) {
|
onControllerCreated: (controller) {
|
||||||
@@ -188,6 +215,7 @@ class ExampleWidgetState extends State<ExampleWidget> {
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
SceneMenu(
|
SceneMenu(
|
||||||
|
sharedFocusNode: _sharedFocusNode,
|
||||||
controller: _filamentController,
|
controller: _filamentController,
|
||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'dart:math';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_filament/animations/animation_data.dart';
|
import 'package:flutter_filament/animations/animation_data.dart';
|
||||||
|
|
||||||
import 'package:flutter_filament/filament_controller.dart';
|
import 'package:flutter_filament/filament_controller.dart';
|
||||||
import 'package:flutter_filament_example/main.dart';
|
import 'package:flutter_filament_example/main.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
@@ -27,8 +28,22 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
|
|||||||
Widget _shapesSubmenu() {
|
Widget _shapesSubmenu() {
|
||||||
var children = [
|
var children = [
|
||||||
MenuItemButton(
|
MenuItemButton(
|
||||||
|
closeOnActivate: false,
|
||||||
onPressed: () async {
|
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(
|
await widget.controller.setBoneTransform(
|
||||||
ExampleWidgetState.assets.last,
|
ExampleWidgetState.assets.last,
|
||||||
"Cylinder",
|
"Cylinder",
|
||||||
@@ -143,11 +158,40 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
|
|||||||
return SubmenuButton(menuChildren: children, child: const Text("Shapes"));
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SubmenuButton(
|
return SubmenuButton(
|
||||||
menuChildren: [
|
menuChildren: [
|
||||||
_shapesSubmenu(),
|
_shapesSubmenu(),
|
||||||
|
_geometrySubmenu(),
|
||||||
MenuItemButton(
|
MenuItemButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
ExampleWidgetState.directionalLight = await widget.controller
|
ExampleWidgetState.directionalLight = await widget.controller
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ class ControllerMenu extends StatefulWidget {
|
|||||||
final FilamentController? controller;
|
final FilamentController? controller;
|
||||||
final void Function(FilamentController controller) onControllerCreated;
|
final void Function(FilamentController controller) onControllerCreated;
|
||||||
final void Function() onControllerDestroyed;
|
final void Function() onControllerDestroyed;
|
||||||
|
final FocusNode sharedFocusNode;
|
||||||
|
|
||||||
ControllerMenu(
|
ControllerMenu(
|
||||||
{this.controller,
|
{this.controller,
|
||||||
required this.onControllerCreated,
|
required this.onControllerCreated,
|
||||||
required this.onControllerDestroyed});
|
required this.onControllerDestroyed,
|
||||||
|
required this.sharedFocusNode});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _ControllerMenuState();
|
State<StatefulWidget> createState() => _ControllerMenuState();
|
||||||
@@ -21,7 +23,6 @@ class ControllerMenu extends StatefulWidget {
|
|||||||
|
|
||||||
class _ControllerMenuState extends State<ControllerMenu> {
|
class _ControllerMenuState extends State<ControllerMenu> {
|
||||||
FilamentController? _filamentController;
|
FilamentController? _filamentController;
|
||||||
final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Camera Menu');
|
|
||||||
|
|
||||||
void _createController({String? uberArchivePath}) {
|
void _createController({String? uberArchivePath}) {
|
||||||
if (_filamentController != null) {
|
if (_filamentController != null) {
|
||||||
@@ -57,8 +58,10 @@ class _ControllerMenuState extends State<ControllerMenu> {
|
|||||||
child: const Text("Create FilamentViewer"),
|
child: const Text("Create FilamentViewer"),
|
||||||
onPressed: _filamentController == null
|
onPressed: _filamentController == null
|
||||||
? null
|
? null
|
||||||
: () {
|
: () async {
|
||||||
_filamentController!.createViewer();
|
await _filamentController!.createViewer();
|
||||||
|
await _filamentController!
|
||||||
|
.setCameraManipulatorOptions(zoomSpeed: 1.0);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MenuItemButton(
|
MenuItemButton(
|
||||||
@@ -96,7 +99,7 @@ class _ControllerMenuState extends State<ControllerMenu> {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return MenuAnchor(
|
return MenuAnchor(
|
||||||
childFocusNode: _buttonFocusNode,
|
childFocusNode: widget.sharedFocusNode,
|
||||||
menuChildren: items,
|
menuChildren: items,
|
||||||
builder:
|
builder:
|
||||||
(BuildContext context, MenuController controller, Widget? child) {
|
(BuildContext context, MenuController controller, Widget? child) {
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import 'package:flutter_filament_example/menus/rendering_submenu.dart';
|
|||||||
|
|
||||||
class SceneMenu extends StatefulWidget {
|
class SceneMenu extends StatefulWidget {
|
||||||
final FilamentController? controller;
|
final FilamentController? controller;
|
||||||
|
final FocusNode sharedFocusNode;
|
||||||
|
|
||||||
const SceneMenu({super.key, required this.controller});
|
const SceneMenu(
|
||||||
|
{super.key, required this.controller, required this.sharedFocusNode});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
@@ -34,6 +36,8 @@ class _SceneMenuState extends State<SceneMenu> {
|
|||||||
widget.controller?.hasViewer ?? ValueNotifier<bool>(false),
|
widget.controller?.hasViewer ?? ValueNotifier<bool>(false),
|
||||||
builder: (BuildContext ctx, bool hasViewer, Widget? child) {
|
builder: (BuildContext ctx, bool hasViewer, Widget? child) {
|
||||||
return MenuAnchor(
|
return MenuAnchor(
|
||||||
|
onClose: () {},
|
||||||
|
childFocusNode: widget.sharedFocusNode,
|
||||||
menuChildren: widget.controller == null
|
menuChildren: widget.controller == null
|
||||||
? []
|
? []
|
||||||
: <Widget>[
|
: <Widget>[
|
||||||
|
|||||||
Reference in New Issue
Block a user