differentiate between setPosition/queuePositionUpdate (+rotate), use EntityId in collision callback, fix collisions + add skiing effect
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_filament/filament_controller.dart';
|
||||
import 'package:vector_math/vector_math_64.dart' as v;
|
||||
|
||||
@@ -79,7 +80,7 @@ class EntityTransformController {
|
||||
|
||||
double rads = 0.0;
|
||||
if (_rotY != 0) {
|
||||
rads = _rotY! * pi / 1000;
|
||||
rads = _rotY * pi / 1000;
|
||||
var rotY = v.Quaternion.axisAngle(v.Vector3(0, 1, 0), rads).normalized();
|
||||
_rotation = rotY;
|
||||
updateRotation = true;
|
||||
@@ -87,12 +88,13 @@ class EntityTransformController {
|
||||
}
|
||||
|
||||
if (updateTranslation) {
|
||||
await controller.setPosition(
|
||||
await controller.queuePositionUpdate(
|
||||
_entity, _position.x, _position.y, _position.z,
|
||||
relative: true);
|
||||
}
|
||||
if (updateRotation) {
|
||||
await controller.setRotationQuat(_entity, _rotation, relative: true);
|
||||
await controller.queueRotationUpdateQuat(_entity, _rotation,
|
||||
relative: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,43 +107,45 @@ class EntityTransformController {
|
||||
}
|
||||
|
||||
bool _playingForwardAnimation = false;
|
||||
bool _playingBackwardAnimation = false;
|
||||
|
||||
void forwardPressed() async {
|
||||
_forward = true;
|
||||
if (forwardAnimationIndex != null) {
|
||||
if (!_playingForwardAnimation) {
|
||||
await controller.playAnimation(_entity, forwardAnimationIndex!,
|
||||
loop: true);
|
||||
_playingForwardAnimation = true;
|
||||
}
|
||||
if (forwardAnimationIndex != null && !_playingForwardAnimation) {
|
||||
await controller.playAnimation(_entity, forwardAnimationIndex!,
|
||||
loop: true, replaceActive: false);
|
||||
_playingForwardAnimation = true;
|
||||
}
|
||||
}
|
||||
|
||||
Timer? _forwardTimer;
|
||||
Timer? _backwardsTimer;
|
||||
Timer? _strafeLeftTimer;
|
||||
Timer? _strafeRightTimer;
|
||||
|
||||
void forwardReleased() async {
|
||||
_forwardTimer?.cancel();
|
||||
_forwardTimer = Timer(Duration(milliseconds: 50), () async {
|
||||
_forward = false;
|
||||
_forward = false;
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
if (!_forward) {
|
||||
_playingForwardAnimation = false;
|
||||
if (forwardAnimationIndex != null) {
|
||||
await controller.stopAnimation(_entity, forwardAnimationIndex!);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void backPressed() {
|
||||
void backPressed() async {
|
||||
_back = true;
|
||||
if (forwardAnimationIndex != null) {
|
||||
if (!_playingBackwardAnimation) {
|
||||
await controller.playAnimation(_entity, forwardAnimationIndex!,
|
||||
loop: true, replaceActive: false, reverse: true);
|
||||
_playingBackwardAnimation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void backReleased() async {
|
||||
_backwardsTimer?.cancel();
|
||||
_backwardsTimer = Timer(Duration(milliseconds: 50), () {
|
||||
_back = false;
|
||||
});
|
||||
_back = false;
|
||||
if (forwardAnimationIndex != null) {
|
||||
await controller.stopAnimation(_entity, forwardAnimationIndex!);
|
||||
}
|
||||
_playingBackwardAnimation = false;
|
||||
}
|
||||
|
||||
void strafeLeftPressed() {
|
||||
@@ -149,10 +153,7 @@ class EntityTransformController {
|
||||
}
|
||||
|
||||
void strafeLeftReleased() async {
|
||||
_strafeLeftTimer?.cancel();
|
||||
_strafeLeftTimer = Timer(Duration(milliseconds: 50), () {
|
||||
_strafeLeft = false;
|
||||
});
|
||||
_strafeLeft = false;
|
||||
}
|
||||
|
||||
void strafeRightPressed() {
|
||||
@@ -160,9 +161,21 @@ class EntityTransformController {
|
||||
}
|
||||
|
||||
void strafeRightReleased() async {
|
||||
_strafeRightTimer?.cancel();
|
||||
_strafeRightTimer = Timer(Duration(milliseconds: 50), () {
|
||||
_strafeRight = false;
|
||||
});
|
||||
_strafeRight = false;
|
||||
}
|
||||
|
||||
void Function()? _mouse1DownCallback;
|
||||
void onMouse1Down(void Function() callback) {
|
||||
_mouse1DownCallback = callback;
|
||||
}
|
||||
|
||||
void mouse1Down() async {
|
||||
_mouse1DownCallback?.call();
|
||||
}
|
||||
|
||||
void mouse1Up() async {}
|
||||
|
||||
void mouse2Up() async {}
|
||||
|
||||
void mouse2Down() async {}
|
||||
}
|
||||
|
||||
@@ -449,9 +449,41 @@ abstract class FilamentController {
|
||||
Future transformToUnitCube(FilamentEntity entity);
|
||||
|
||||
///
|
||||
/// Sets the world space position for [entity] to the given coordinates.
|
||||
/// Directly sets the world space position for [entity] to the given coordinates, skipping all collision detection.
|
||||
///
|
||||
Future setPosition(FilamentEntity entity, double x, double y, double z,
|
||||
Future setPosition(FilamentEntity entity, double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Directly sets the scale for [entity], skipping all collision detection.
|
||||
///
|
||||
Future setScale(FilamentEntity entity, double scale);
|
||||
|
||||
///
|
||||
/// Directly sets the rotation for [entity] to [rads] around the axis {x,y,z}, skipping all collision detection.
|
||||
///
|
||||
Future setRotation(
|
||||
FilamentEntity entity, double rads, double x, double y, double z);
|
||||
|
||||
///
|
||||
/// Queues an update to the worldspace position for [entity] to {x,y,z}.
|
||||
/// The actual update will occur on the next frame, and will be subject to collision detection.
|
||||
///
|
||||
Future queuePositionUpdate(
|
||||
FilamentEntity entity, double x, double y, double z,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// Queues an update to the worldspace rotation for [entity].
|
||||
/// The actual update will occur on the next frame, and will be subject to collision detection.
|
||||
///
|
||||
Future queueRotationUpdate(
|
||||
FilamentEntity entity, double rads, double x, double y, double z,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// Same as [queueRotationUpdate].
|
||||
///
|
||||
Future queueRotationUpdateQuat(FilamentEntity entity, Quaternion quat,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
@@ -459,23 +491,10 @@ abstract class FilamentController {
|
||||
///
|
||||
Future setPostProcessing(bool enabled);
|
||||
|
||||
///
|
||||
/// Sets the scale for the given entity.
|
||||
///
|
||||
Future setScale(FilamentEntity entity, double scale);
|
||||
|
||||
///
|
||||
/// Sets the rotation for [entity] to [rads] around the axis {x,y,z}.
|
||||
///
|
||||
Future setRotation(
|
||||
FilamentEntity entity, double rads, double x, double y, double z,
|
||||
{bool relative = false});
|
||||
|
||||
///
|
||||
/// Sets the rotation for [entity] to the specified quaternion.
|
||||
///
|
||||
Future setRotationQuat(FilamentEntity entity, Quaternion rotation,
|
||||
{bool relative = false});
|
||||
Future setRotationQuat(FilamentEntity entity, Quaternion rotation);
|
||||
|
||||
///
|
||||
/// Reveal the node [meshName] under [entity]. Only applicable if [hide] had previously been called; this is a no-op otherwise.
|
||||
@@ -544,7 +563,8 @@ abstract class FilamentController {
|
||||
/// At the moment, this is only relevant when controlling a different entity's transform.
|
||||
/// If there is a collision between the controlled entity and [collidableEntity], the transform will not be updated.
|
||||
///
|
||||
Future addCollisionComponent(FilamentEntity collidableEntity);
|
||||
Future addCollisionComponent(FilamentEntity collidableEntity,
|
||||
{void Function(int entityId)? callback});
|
||||
|
||||
///
|
||||
/// Creates a (renderable) entity with the specified geometry and adds to the scene.
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'package:flutter_filament/filament_controller.dart';
|
||||
import 'package:flutter_filament/animations/animation_data.dart';
|
||||
import 'package:flutter_filament/generated_bindings.dart';
|
||||
import 'package:flutter_filament/hardware/hardware_keyboard_listener.dart';
|
||||
import 'package:flutter_filament/hardware/hardware_keyboard_poll.dart';
|
||||
import 'package:flutter_filament/rendering_surface.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
@@ -1051,13 +1052,33 @@ class FilamentControllerFFI extends FilamentController {
|
||||
}
|
||||
|
||||
@override
|
||||
Future setPosition(FilamentEntity entity, double x, double y, double z,
|
||||
{bool relative = false}) async {
|
||||
Future setPosition(
|
||||
FilamentEntity entity, double x, double y, double z) async {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
|
||||
set_position(_assetManager!, entity, x, y, z, relative);
|
||||
set_position(_assetManager!, entity, x, y, z);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setRotation(
|
||||
FilamentEntity entity, double rads, double x, double y, double z) async {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
var quat = Quaternion.axisAngle(Vector3(x, y, z), rads);
|
||||
await setRotationQuat(entity, quat);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setRotationQuat(FilamentEntity entity, Quaternion rotation,
|
||||
{bool relative = false}) async {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
set_rotation(_assetManager!, entity, rotation.radians, rotation.x,
|
||||
rotation.y, rotation.z, rotation.w);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1069,23 +1090,33 @@ class FilamentControllerFFI extends FilamentController {
|
||||
}
|
||||
|
||||
@override
|
||||
Future setRotation(
|
||||
Future queuePositionUpdate(
|
||||
FilamentEntity entity, double x, double y, double z,
|
||||
{bool relative = false}) async {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
|
||||
queue_position_update(_assetManager!, entity, x, y, z, relative);
|
||||
}
|
||||
|
||||
@override
|
||||
Future queueRotationUpdate(
|
||||
FilamentEntity entity, double rads, double x, double y, double z,
|
||||
{bool relative = false}) async {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
var quat = Quaternion.axisAngle(Vector3(x, y, z), rads);
|
||||
await setRotationQuat(entity, quat, relative: relative);
|
||||
await queueRotationUpdateQuat(entity, quat, relative: relative);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setRotationQuat(FilamentEntity entity, Quaternion rotation,
|
||||
Future queueRotationUpdateQuat(FilamentEntity entity, Quaternion rotation,
|
||||
{bool relative = false}) async {
|
||||
if (_viewer == null) {
|
||||
throw Exception("No viewer available, ignoring");
|
||||
}
|
||||
set_rotation(_assetManager!, entity, rotation.radians, rotation.x,
|
||||
queue_rotation_update(_assetManager!, entity, rotation.radians, rotation.x,
|
||||
rotation.y, rotation.z, rotation.w, relative);
|
||||
}
|
||||
|
||||
@@ -1359,12 +1390,20 @@ class FilamentControllerFFI extends FilamentController {
|
||||
}
|
||||
|
||||
@override
|
||||
Future addCollisionComponent(FilamentEntity entity) async {
|
||||
Future addCollisionComponent(FilamentEntity entity,
|
||||
{void Function(int entityId)? callback}) async {
|
||||
if (_assetManager == null) {
|
||||
throw Exception("AssetManager must be non-null");
|
||||
}
|
||||
// ignore: sdk_version_since
|
||||
|
||||
add_collision_component(_assetManager!, entity);
|
||||
if (callback != null) {
|
||||
var ptr =
|
||||
NativeCallable<Void Function(Int32 entityId)>.listener(callback);
|
||||
add_collision_component(_assetManager!, entity, ptr.nativeFunction);
|
||||
} else {
|
||||
add_collision_component(_assetManager!, entity, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user