rename camera_manipulation sample to picking
This commit is contained in:
1 parent
8311c95100
commit
90f17e3bc9
135 files changed
+196
-107
No files matched your search
@@ -1,101 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
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<MyHomePage> createState() => _MyHomePageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
|
||||||
|
|
||||||
late DelegateInputHandler _fixedOrbitInputHandler;
|
|
||||||
late DelegateInputHandler _freeFlightInputHandler;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
|
||||||
_thermionViewer = await ThermionFlutterPlugin.createViewer();
|
|
||||||
var entity =
|
|
||||||
await _thermionViewer!.loadGltf("assets/cube.glb", keepData: 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"}"))
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,190 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:flutter/material.dart' hide View;
|
||||||
|
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<MyHomePage> createState() => _MyHomePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
|
late DelegateInputHandler _inputHandler;
|
||||||
|
|
||||||
|
String? overlay;
|
||||||
|
final vectors = <Vector2>[];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
_thermionViewer = await ThermionFlutterPlugin.createViewer();
|
||||||
|
var asset = await _thermionViewer!
|
||||||
|
.loadGltf("assets/cube.glb", keepData: true, numInstances: 4);
|
||||||
|
var instances = <ThermionAsset>[
|
||||||
|
await asset.getInstance(0),
|
||||||
|
await asset.createInstance(),
|
||||||
|
await asset.createInstance(),
|
||||||
|
await asset.createInstance()
|
||||||
|
];
|
||||||
|
|
||||||
|
var vectors = <Vector2>[
|
||||||
|
Vector2(1, 1),
|
||||||
|
Vector2(1, -1),
|
||||||
|
Vector2(-1, 1),
|
||||||
|
Vector2(-1, -1),
|
||||||
|
];
|
||||||
|
|
||||||
|
final speed = 0.03;
|
||||||
|
|
||||||
|
FilamentApp.instance!.registerRequestFrameHook(() async {
|
||||||
|
for (int i = 0; i < instances.length; i++) {
|
||||||
|
final instance = instances[i];
|
||||||
|
final vector = vectors[i];
|
||||||
|
var transform = await instance.getWorldTransform();
|
||||||
|
var translation = transform.getTranslation();
|
||||||
|
var delta = vector.scaled(speed)
|
||||||
|
..clamp(Vector2(-1, -1), Vector2(1, 1));
|
||||||
|
translation.x += delta.x;
|
||||||
|
translation.y += delta.y;
|
||||||
|
if (translation.x.abs() >= 3) {
|
||||||
|
vectors[i].x *= -1;
|
||||||
|
}
|
||||||
|
if (translation.y.abs() >= 3) {
|
||||||
|
vectors[i].y *= -1;
|
||||||
|
}
|
||||||
|
transform.setTranslation(translation);
|
||||||
|
await instance.setTransform(transform);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final camera = await _thermionViewer!.getActiveCamera();
|
||||||
|
await camera.lookAt(Vector3(0, 0, 10));
|
||||||
|
|
||||||
|
await _thermionViewer!.loadSkybox("assets/default_env_skybox.ktx");
|
||||||
|
await _thermionViewer!.loadIbl("assets/default_env_ibl.ktx");
|
||||||
|
await _thermionViewer!.setPostProcessing(true);
|
||||||
|
await _thermionViewer!.setRendering(true);
|
||||||
|
|
||||||
|
var delegate = _InputHandlerDelegate(_thermionViewer!.view,
|
||||||
|
(ThermionEntity entity, int x, int y) async {
|
||||||
|
for (int i = 0; i < instances.length; i++) {
|
||||||
|
var instance = instances[i];
|
||||||
|
var children = await instance.getChildEntities();
|
||||||
|
if (entity == instance.entity || children.contains(entity)) {
|
||||||
|
overlay = "Instance ${i} selected at viewport coordinates ($x, $y)";
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_inputHandler =
|
||||||
|
DelegateInputHandler(viewer: _thermionViewer!, delegates: [delegate]);
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ThermionViewer? _thermionViewer;
|
||||||
|
|
||||||
|
bool isOrbit = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (_thermionViewer == null) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
return Stack(children: [
|
||||||
|
Positioned.fill(
|
||||||
|
child: ThermionListenerWidget(
|
||||||
|
inputHandler: _inputHandler,
|
||||||
|
child: ThermionWidget(
|
||||||
|
viewer: _thermionViewer!,
|
||||||
|
))),
|
||||||
|
if (overlay != null)
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(5),
|
||||||
|
margin: const EdgeInsets.all(5),
|
||||||
|
color: Colors.black,
|
||||||
|
child: Text(
|
||||||
|
overlay!,
|
||||||
|
style: const TextStyle(color: Colors.white, fontSize: 12),
|
||||||
|
)))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _InputHandlerDelegate extends InputHandlerDelegate {
|
||||||
|
final View view;
|
||||||
|
final void Function(ThermionEntity, int x, int y) onPick;
|
||||||
|
|
||||||
|
_InputHandlerDelegate(this.view, this.onPick);
|
||||||
|
|
||||||
|
void _onPickResult(PickResult result) {
|
||||||
|
onPick.call(result.entity, result.x, result.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future handle(List<InputEvent> events) async {
|
||||||
|
for (final event in events) {
|
||||||
|
switch (event) {
|
||||||
|
case TouchEvent(
|
||||||
|
type: final type,
|
||||||
|
localPosition: final localPosition,
|
||||||
|
delta: final delta
|
||||||
|
):
|
||||||
|
await view.pick(localPosition!.x.toInt(), localPosition!.y.toInt(),
|
||||||
|
_onPickResult);
|
||||||
|
break;
|
||||||
|
case MouseEvent(
|
||||||
|
type: final type,
|
||||||
|
localPosition: final localPosition,
|
||||||
|
delta: final delta
|
||||||
|
):
|
||||||
|
switch (type) {
|
||||||
|
case MouseEventType.buttonDown:
|
||||||
|
await view.pick(localPosition!.x.toInt(),
|
||||||
|
localPosition!.y.toInt(), _onPickResult);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -14,7 +14,7 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter/ephemeral/.symlinks/plugins/thermion_flutter/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/thermion_flutter/macos
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
|
||||||
thermion_flutter: debb51a861788780ce40e11e4400c2e5a8681fdf
|
thermion_flutter: debb51a861788780ce40e11e4400c2e5a8681fdf
|
||||||
|
|
||||||
PODFILE CHECKSUM: 1888651be91a8ad58692c1add9ce24279fd4e950
|
PODFILE CHECKSUM: 1888651be91a8ad58692c1add9ce24279fd4e950
|
||||||
+3
-3
@@ -556,7 +556,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
@@ -639,7 +639,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
@@ -689,7 +689,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 135 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user