Merge pull request #13 from odd-io/feature-code-quality
Refactored /lib code to reduce analyze warnings
This commit is contained in:
@@ -25,8 +25,9 @@ class AnimationBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MorphAnimationData build() {
|
MorphAnimationData build() {
|
||||||
if (availableMorphs.isEmpty == 0 || _duration == 0 || _frameLengthInMs == 0)
|
if (availableMorphs.isEmpty || _duration == 0 || _frameLengthInMs == 0) {
|
||||||
throw Exception();
|
throw Exception();
|
||||||
|
}
|
||||||
|
|
||||||
int numFrames = _duration * 1000 ~/ _frameLengthInMs;
|
int numFrames = _duration * 1000 ~/ _frameLengthInMs;
|
||||||
|
|
||||||
@@ -64,10 +65,10 @@ class AnimationBuilder {
|
|||||||
|
|
||||||
AnimationBuilder interpolateMorphWeights(
|
AnimationBuilder interpolateMorphWeights(
|
||||||
double start, double end, double startValue, double endValue) {
|
double start, double end, double startValue, double endValue) {
|
||||||
this._interpMorphStart = start;
|
_interpMorphStart = start;
|
||||||
this._interpMorphEnd = end;
|
_interpMorphEnd = end;
|
||||||
this._interpMorphStartValue = startValue;
|
_interpMorphStartValue = startValue;
|
||||||
this._interpMorphEndValue = endValue;
|
_interpMorphEndValue = endValue;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +125,7 @@ class AnimationBuilder {
|
|||||||
|
|
||||||
// _BoneAnimationDatas!.add(DartBoneAnimationData([boneName], [meshName], animData));
|
// _BoneAnimationDatas!.add(DartBoneAnimationData([boneName], [meshName], animData));
|
||||||
|
|
||||||
return this;
|
// return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ abstract class FilamentController {
|
|||||||
Future rotateEnd();
|
Future rotateEnd();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set the weights for all morph targets under node [meshName] in [asset] to [weights].
|
/// Set the weights for all morph targets under node [meshName] in [entity] to [weights].
|
||||||
///
|
///
|
||||||
Future setMorphTargetWeights(
|
Future setMorphTargetWeights(
|
||||||
FilamentEntity entity, String meshName, List<double> weights);
|
FilamentEntity entity, String meshName, List<double> weights);
|
||||||
@@ -269,7 +269,7 @@ abstract class FilamentController {
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// Removes/destroys the specified entity from the scene.
|
/// Removes/destroys the specified entity from the scene.
|
||||||
/// [asset] will no longer be a valid handle after this method is called; ensure you immediately discard all references once this method is complete.
|
/// [entity] will no longer be a valid handle after this method is called; ensure you immediately discard all references once this method is complete.
|
||||||
///
|
///
|
||||||
Future removeAsset(FilamentEntity entity);
|
Future removeAsset(FilamentEntity entity);
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ abstract class FilamentController {
|
|||||||
Future zoomEnd();
|
Future zoomEnd();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Schedules the glTF animation at [index] in [asset] to start playing on the next frame.
|
/// Schedules the glTF animation at [index] in [entity] to start playing on the next frame.
|
||||||
///
|
///
|
||||||
Future playAnimation(FilamentEntity entity, int index,
|
Future playAnimation(FilamentEntity entity, int index,
|
||||||
{bool loop = false,
|
{bool loop = false,
|
||||||
@@ -308,7 +308,7 @@ abstract class FilamentController {
|
|||||||
Future stopAnimation(FilamentEntity entity, int animationIndex);
|
Future stopAnimation(FilamentEntity entity, int animationIndex);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sets the current scene camera to the glTF camera under [name] in [asset].
|
/// Sets the current scene camera to the glTF camera under [name] in [entity].
|
||||||
///
|
///
|
||||||
Future setCamera(FilamentEntity entity, String? name);
|
Future setCamera(FilamentEntity entity, String? name);
|
||||||
|
|
||||||
@@ -358,7 +358,7 @@ abstract class FilamentController {
|
|||||||
Future<Matrix3> getCameraRotation();
|
Future<Matrix3> getCameraRotation();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Repositions the camera to the last vertex of the bounding box of [asset], looking at the penultimate vertex.
|
/// Repositions the camera to the last vertex of the bounding box of [entity], looking at the penultimate vertex.
|
||||||
///
|
///
|
||||||
Future moveCameraToAsset(FilamentEntity entity);
|
Future moveCameraToAsset(FilamentEntity entity);
|
||||||
|
|
||||||
@@ -390,12 +390,12 @@ abstract class FilamentController {
|
|||||||
FilamentEntity entity, String meshName, int materialIndex, Color color);
|
FilamentEntity entity, String meshName, int materialIndex, Color color);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Scale [asset] to fit within the unit cube.
|
/// Scale [entity] to fit within the unit cube.
|
||||||
///
|
///
|
||||||
Future transformToUnitCube(FilamentEntity entity);
|
Future transformToUnitCube(FilamentEntity entity);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sets the world space position for [asset] to the given coordinates.
|
/// Sets the world space position for [entity] to the given coordinates.
|
||||||
///
|
///
|
||||||
Future setPosition(FilamentEntity entity, double x, double y, double z);
|
Future setPosition(FilamentEntity entity, double x, double y, double z);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
import 'dart:developer' as dev;
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
@@ -69,7 +69,7 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
_resizingWidth = call.arguments[0];
|
_resizingWidth = call.arguments[0];
|
||||||
_resizingHeight = call.arguments[1];
|
_resizingHeight = call.arguments[1];
|
||||||
_resizeTimer = Timer(const Duration(milliseconds: 500), () async {
|
_resizeTimer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
this.rect.value = Offset.zero &
|
rect.value = Offset.zero &
|
||||||
ui.Size(_resizingWidth!.toDouble(), _resizingHeight!.toDouble());
|
ui.Size(_resizingWidth!.toDouble(), _resizingHeight!.toDouble());
|
||||||
await resize();
|
await resize();
|
||||||
});
|
});
|
||||||
@@ -115,10 +115,10 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setDimensions(Rect rect, double ratio) async {
|
Future setDimensions(Rect rect, double pixelRatio) async {
|
||||||
this.rect.value = Rect.fromLTWH(rect.left, rect.top,
|
this.rect.value = Rect.fromLTWH(rect.left, rect.top,
|
||||||
rect.width * _pixelRatio, rect.height * _pixelRatio);
|
rect.width * _pixelRatio, rect.height * _pixelRatio);
|
||||||
_pixelRatio = ratio;
|
_pixelRatio = pixelRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -147,7 +147,7 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
await _channel.invokeMethod(
|
await _channel.invokeMethod(
|
||||||
"destroyTexture", textureDetails.value!.textureId);
|
"destroyTexture", textureDetails.value!.textureId);
|
||||||
}
|
}
|
||||||
print("Texture destroyed");
|
dev.log("Texture destroyed");
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -188,16 +188,16 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
|
|
||||||
var renderingSurface = await _createRenderingSurface();
|
var renderingSurface = await _createRenderingSurface();
|
||||||
|
|
||||||
print("Got rendering surface");
|
dev.log("Got rendering surface");
|
||||||
|
|
||||||
_viewer = _lib.create_filament_viewer_ffi(
|
_viewer = _lib.create_filament_viewer_ffi(
|
||||||
Pointer<Void>.fromAddress(renderingSurface.sharedContext ?? 0),
|
Pointer<Void>.fromAddress(renderingSurface.sharedContext),
|
||||||
_driver,
|
_driver,
|
||||||
uberArchivePath?.toNativeUtf8().cast<Char>() ?? nullptr,
|
uberArchivePath?.toNativeUtf8().cast<Char>() ?? nullptr,
|
||||||
loader,
|
loader,
|
||||||
renderCallback,
|
renderCallback,
|
||||||
renderCallbackOwner);
|
renderCallbackOwner);
|
||||||
print("Created viewer");
|
dev.log("Created viewer");
|
||||||
if (_viewer!.address == 0) {
|
if (_viewer!.address == 0) {
|
||||||
throw Exception("Failed to create viewer. Check logs for details");
|
throw Exception("Failed to create viewer. Check logs for details");
|
||||||
}
|
}
|
||||||
@@ -206,19 +206,19 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
|
|
||||||
_lib.create_swap_chain_ffi(_viewer!, renderingSurface.surface,
|
_lib.create_swap_chain_ffi(_viewer!, renderingSurface.surface,
|
||||||
rect.value!.width.toInt(), rect.value!.height.toInt());
|
rect.value!.width.toInt(), rect.value!.height.toInt());
|
||||||
print("Created swap chain");
|
dev.log("Created swap chain");
|
||||||
if (renderingSurface.textureHandle != 0) {
|
if (renderingSurface.textureHandle != 0) {
|
||||||
print(
|
dev.log(
|
||||||
"Creating render target from native texture ${renderingSurface.textureHandle}");
|
"Creating render target from native texture ${renderingSurface.textureHandle}");
|
||||||
_lib.create_render_target_ffi(_viewer!, renderingSurface.textureHandle,
|
_lib.create_render_target_ffi(_viewer!, renderingSurface.textureHandle,
|
||||||
rect.value!.width.toInt(), rect.value!.height.toInt());
|
rect.value!.width.toInt(), rect.value!.height.toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
textureDetails.value = TextureDetails(
|
textureDetails.value = TextureDetails(
|
||||||
textureId: renderingSurface.flutterTextureId!,
|
textureId: renderingSurface.flutterTextureId,
|
||||||
width: rect.value!.width.toInt(),
|
width: rect.value!.width.toInt(),
|
||||||
height: rect.value!.height.toInt());
|
height: rect.value!.height.toInt());
|
||||||
print("texture details ${textureDetails.value}");
|
dev.log("texture details ${textureDetails.value}");
|
||||||
_lib.update_viewport_and_camera_projection_ffi(
|
_lib.update_viewport_and_camera_projection_ffi(
|
||||||
_viewer!, rect.value!.width.toInt(), rect.value!.height.toInt(), 1.0);
|
_viewer!, rect.value!.width.toInt(), rect.value!.height.toInt(), 1.0);
|
||||||
hasViewer.value = true;
|
hasViewer.value = true;
|
||||||
@@ -322,7 +322,7 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
"destroyTexture", textureDetails.value!.textureId);
|
"destroyTexture", textureDetails.value!.textureId);
|
||||||
}
|
}
|
||||||
} else if (Platform.isWindows) {
|
} else if (Platform.isWindows) {
|
||||||
print("Resizing window with rect $rect");
|
dev.log("Resizing window with rect $rect");
|
||||||
await _channel.invokeMethod("resizeWindow", [
|
await _channel.invokeMethod("resizeWindow", [
|
||||||
rect.value!.width,
|
rect.value!.width,
|
||||||
rect.value!.height,
|
rect.value!.height,
|
||||||
@@ -345,14 +345,14 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (renderingSurface.textureHandle != 0) {
|
if (renderingSurface.textureHandle != 0) {
|
||||||
print(
|
dev.log(
|
||||||
"Creating render target from native texture ${renderingSurface.textureHandle}");
|
"Creating render target from native texture ${renderingSurface.textureHandle}");
|
||||||
_lib.create_render_target_ffi(_viewer!, renderingSurface.textureHandle,
|
_lib.create_render_target_ffi(_viewer!, renderingSurface.textureHandle,
|
||||||
rect.value!.width.toInt(), rect.value!.height.toInt());
|
rect.value!.width.toInt(), rect.value!.height.toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
textureDetails.value = TextureDetails(
|
textureDetails.value = TextureDetails(
|
||||||
textureId: renderingSurface.flutterTextureId!,
|
textureId: renderingSurface.flutterTextureId,
|
||||||
width: rect.value!.width.toInt(),
|
width: rect.value!.width.toInt(),
|
||||||
height: rect.value!.height.toInt());
|
height: rect.value!.height.toInt());
|
||||||
|
|
||||||
@@ -558,7 +558,7 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setMorphTargetWeights(
|
Future setMorphTargetWeights(
|
||||||
FilamentEntity asset, String meshName, List<double> weights) async {
|
FilamentEntity entity, String meshName, List<double> weights) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
@@ -567,23 +567,23 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
for (int i = 0; i < weights.length; i++) {
|
for (int i = 0; i < weights.length; i++) {
|
||||||
weightsPtr.elementAt(i).value = weights[i];
|
weightsPtr.elementAt(i).value = weights[i];
|
||||||
}
|
}
|
||||||
_lib.set_morph_target_weights_ffi(_assetManager!, asset,
|
_lib.set_morph_target_weights_ffi(_assetManager!, entity,
|
||||||
meshName.toNativeUtf8().cast<Char>(), weightsPtr, weights.length);
|
meshName.toNativeUtf8().cast<Char>(), weightsPtr, weights.length);
|
||||||
calloc.free(weightsPtr);
|
calloc.free(weightsPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getMorphTargetNames(
|
Future<List<String>> getMorphTargetNames(
|
||||||
FilamentEntity asset, String meshName) async {
|
FilamentEntity entity, String meshName) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
var names = <String>[];
|
var names = <String>[];
|
||||||
var count = _lib.get_morph_target_name_count_ffi(
|
var count = _lib.get_morph_target_name_count_ffi(
|
||||||
_assetManager!, asset, meshName.toNativeUtf8().cast<Char>());
|
_assetManager!, entity, meshName.toNativeUtf8().cast<Char>());
|
||||||
var outPtr = calloc<Char>(255);
|
var outPtr = calloc<Char>(255);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
_lib.get_morph_target_name(_assetManager!, asset,
|
_lib.get_morph_target_name(_assetManager!, entity,
|
||||||
meshName.toNativeUtf8().cast<Char>(), outPtr, i);
|
meshName.toNativeUtf8().cast<Char>(), outPtr, i);
|
||||||
names.add(outPtr.cast<Utf8>().toDartString());
|
names.add(outPtr.cast<Utf8>().toDartString());
|
||||||
}
|
}
|
||||||
@@ -592,15 +592,15 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getAnimationNames(FilamentEntity asset) async {
|
Future<List<String>> getAnimationNames(FilamentEntity entity) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
var animationCount = _lib.get_animation_count(_assetManager!, asset);
|
var animationCount = _lib.get_animation_count(_assetManager!, entity);
|
||||||
var names = <String>[];
|
var names = <String>[];
|
||||||
var outPtr = calloc<Char>(255);
|
var outPtr = calloc<Char>(255);
|
||||||
for (int i = 0; i < animationCount; i++) {
|
for (int i = 0; i < animationCount; i++) {
|
||||||
_lib.get_animation_name_ffi(_assetManager!, asset, outPtr, i);
|
_lib.get_animation_name_ffi(_assetManager!, entity, outPtr, i);
|
||||||
names.add(outPtr.cast<Utf8>().toDartString());
|
names.add(outPtr.cast<Utf8>().toDartString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,12 +609,12 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<double> getAnimationDuration(
|
Future<double> getAnimationDuration(
|
||||||
FilamentEntity asset, int animationIndex) async {
|
FilamentEntity entity, int animationIndex) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
var duration =
|
var duration =
|
||||||
_lib.get_animation_duration(_assetManager!, asset, animationIndex);
|
_lib.get_animation_duration(_assetManager!, entity, animationIndex);
|
||||||
|
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
@@ -644,7 +644,7 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
calloc.free(dataPtr);
|
calloc.free(dataPtr);
|
||||||
calloc.free(idxPtr);
|
calloc.free(idxPtr);
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Morph target ${animation.morphTargets[i]} is specified in the animation but could not be found in the mesh ${animation.meshName} under entity ${entity}");
|
"Morph target ${animation.morphTargets[i]} is specified in the animation but could not be found in the mesh ${animation.meshName} under entity $entity");
|
||||||
}
|
}
|
||||||
idxPtr.elementAt(i).value = index;
|
idxPtr.elementAt(i).value = index;
|
||||||
}
|
}
|
||||||
@@ -664,7 +664,7 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future setBoneAnimation(
|
Future setBoneAnimation(
|
||||||
FilamentEntity asset, BoneAnimationData animation) async {
|
FilamentEntity entity, BoneAnimationData animation) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
@@ -701,11 +701,11 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future removeAsset(FilamentEntity asset) async {
|
Future removeAsset(FilamentEntity entity) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.remove_asset_ffi(_viewer!, asset);
|
_lib.remove_asset_ffi(_viewer!, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -741,7 +741,7 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future playAnimation(FilamentEntity asset, int index,
|
Future playAnimation(FilamentEntity entity, int index,
|
||||||
{bool loop = false,
|
{bool loop = false,
|
||||||
bool reverse = false,
|
bool reverse = false,
|
||||||
bool replaceActive = true,
|
bool replaceActive = true,
|
||||||
@@ -750,33 +750,33 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.play_animation_ffi(
|
_lib.play_animation_ffi(
|
||||||
_assetManager!, asset, index, loop, reverse, replaceActive, crossfade);
|
_assetManager!, entity, index, loop, reverse, replaceActive, crossfade);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setAnimationFrame(
|
Future setAnimationFrame(
|
||||||
FilamentEntity asset, int index, int animationFrame) async {
|
FilamentEntity entity, int index, int animationFrame) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.set_animation_frame(_assetManager!, asset, index, animationFrame);
|
_lib.set_animation_frame(_assetManager!, entity, index, animationFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future stopAnimation(FilamentEntity asset, int animationIndex) async {
|
Future stopAnimation(FilamentEntity entity, int animationIndex) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.stop_animation(_assetManager!, asset, animationIndex);
|
_lib.stop_animation(_assetManager!, entity, animationIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setCamera(FilamentEntity asset, String? name) async {
|
Future setCamera(FilamentEntity entity, String? name) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
var result = _lib.set_camera(
|
var result = _lib.set_camera(
|
||||||
_viewer!, asset, name?.toNativeUtf8()?.cast<Char>() ?? nullptr);
|
_viewer!, entity, name?.toNativeUtf8().cast<Char>() ?? nullptr);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw Exception("Failed to set camera");
|
throw Exception("Failed to set camera");
|
||||||
}
|
}
|
||||||
@@ -833,11 +833,11 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future moveCameraToAsset(FilamentEntity asset) async {
|
Future moveCameraToAsset(FilamentEntity entity) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.move_camera_to_asset(_viewer!, asset);
|
_lib.move_camera_to_asset(_viewer!, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -880,75 +880,76 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setMaterialColor(FilamentEntity asset, String meshName,
|
Future setMaterialColor(FilamentEntity entity, String meshName,
|
||||||
int materialIndex, Color color) async {
|
int materialIndex, Color color) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
var result = _lib.set_material_color(
|
var result = _lib.set_material_color(
|
||||||
_assetManager!,
|
_assetManager!,
|
||||||
asset,
|
entity,
|
||||||
meshName.toNativeUtf8().cast<Char>(),
|
meshName.toNativeUtf8().cast<Char>(),
|
||||||
materialIndex,
|
materialIndex,
|
||||||
color.red.toDouble() / 255.0,
|
color.red.toDouble() / 255.0,
|
||||||
color.green.toDouble() / 255.0,
|
color.green.toDouble() / 255.0,
|
||||||
color.blue.toDouble() / 255.0,
|
color.blue.toDouble() / 255.0,
|
||||||
color.alpha.toDouble() / 255.0);
|
color.alpha.toDouble() / 255.0);
|
||||||
if (result != 1) {
|
if (!result) {
|
||||||
throw Exception("Failed to set material color");
|
throw Exception("Failed to set material color");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future transformToUnitCube(FilamentEntity asset) async {
|
Future transformToUnitCube(FilamentEntity entity) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.transform_to_unit_cube(_assetManager!, asset);
|
_lib.transform_to_unit_cube(_assetManager!, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setPosition(FilamentEntity asset, double x, double y, double z) async {
|
Future setPosition(
|
||||||
|
FilamentEntity entity, double x, double y, double z) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.set_position(_assetManager!, asset, x, y, z);
|
_lib.set_position(_assetManager!, entity, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setScale(FilamentEntity asset, double scale) async {
|
Future setScale(FilamentEntity entity, double scale) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.set_scale(_assetManager!, asset, scale);
|
_lib.set_scale(_assetManager!, entity, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setRotation(
|
Future setRotation(
|
||||||
FilamentEntity asset, double rads, double x, double y, double z) async {
|
FilamentEntity entity, double rads, double x, double y, double z) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
_lib.set_rotation(_assetManager!, asset, rads, x, y, z);
|
_lib.set_rotation(_assetManager!, entity, rads, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future hide(FilamentEntity asset, String meshName) async {
|
Future hide(FilamentEntity entity, String meshName) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
if (_lib.hide_mesh(
|
if (_lib.hide_mesh(
|
||||||
_assetManager!, asset, meshName.toNativeUtf8().cast<Char>()) !=
|
_assetManager!, entity, meshName.toNativeUtf8().cast<Char>()) !=
|
||||||
1) {}
|
1) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future reveal(FilamentEntity asset, String meshName) async {
|
Future reveal(FilamentEntity entity, String meshName) async {
|
||||||
if (_viewer == null) {
|
if (_viewer == null) {
|
||||||
throw Exception("No viewer available, ignoring");
|
throw Exception("No viewer available, ignoring");
|
||||||
}
|
}
|
||||||
if (_lib.reveal_mesh(
|
if (_lib.reveal_mesh(
|
||||||
_assetManager!, asset, meshName.toNativeUtf8().cast<Char>()) !=
|
_assetManager!, entity, meshName.toNativeUtf8().cast<Char>()) !=
|
||||||
1) {
|
1) {
|
||||||
throw Exception("Failed to reveal mesh $meshName");
|
throw Exception("Failed to reveal mesh $meshName");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||||
//
|
//
|
||||||
// Generated by `package:ffigen`.
|
// Generated by `package:ffigen`.
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint, unused_element, unused_field
|
||||||
import 'dart:ffi' as ffi;
|
import 'dart:ffi' as ffi;
|
||||||
|
|
||||||
class NativeLibrary {
|
class NativeLibrary {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
|
import 'dart:developer' as dev;
|
||||||
|
|
||||||
class RenderingSurface {
|
class RenderingSurface {
|
||||||
final int flutterTextureId;
|
final int flutterTextureId;
|
||||||
@@ -15,22 +16,23 @@ class RenderingSurface {
|
|||||||
// null on iOS/Android, void* on MacOS (pointer to metal texture), GLuid on Windows/Linux
|
// null on iOS/Android, void* on MacOS (pointer to metal texture), GLuid on Windows/Linux
|
||||||
var nativeTexture = platformMessage[2] as int? ?? 0;
|
var nativeTexture = platformMessage[2] as int? ?? 0;
|
||||||
|
|
||||||
if(nativeTexture != 0) {
|
if (nativeTexture != 0) {
|
||||||
assert(surfaceAddress == 0);
|
assert(surfaceAddress == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var sharedContext = platformMessage[3] as int? ?? 0;
|
var sharedContext = platformMessage[3] as int? ?? 0;
|
||||||
|
|
||||||
print(
|
dev.log(
|
||||||
"Using flutterTextureId $flutterTextureId, surface $surfaceAddress nativeTexture $nativeTexture and sharedContext $sharedContext");
|
"Using flutterTextureId $flutterTextureId, surface $surfaceAddress nativeTexture $nativeTexture and sharedContext $sharedContext");
|
||||||
return RenderingSurface(
|
return RenderingSurface(
|
||||||
sharedContext: sharedContext,
|
sharedContext: sharedContext,
|
||||||
flutterTextureId: flutterTextureId,
|
flutterTextureId: flutterTextureId,
|
||||||
surface: Pointer<Void>.fromAddress(surfaceAddress),
|
surface: Pointer<Void>.fromAddress(surfaceAddress),
|
||||||
textureHandle: nativeTexture);
|
textureHandle: nativeTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingSurface({required this.sharedContext,
|
RenderingSurface(
|
||||||
|
{required this.sharedContext,
|
||||||
required this.flutterTextureId,
|
required this.flutterTextureId,
|
||||||
required this.surface,
|
required this.surface,
|
||||||
required this.textureHandle});
|
required this.textureHandle});
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_filament/widgets/filament_gesture_detector_desktop.dart';
|
import 'package:flutter_filament/widgets/filament_gesture_detector_desktop.dart';
|
||||||
import 'package:flutter_filament/widgets/filament_gesture_detector_mobile.dart';
|
import 'package:flutter_filament/widgets/filament_gesture_detector_mobile.dart';
|
||||||
import '../filament_controller.dart';
|
import '../filament_controller.dart';
|
||||||
|
|
||||||
enum GestureType { RotateCamera, PanCamera, PanBackground }
|
enum GestureType { rotateCamera, panCamera, panBackground }
|
||||||
|
|
||||||
///
|
///
|
||||||
/// A widget that translates finger/mouse gestures to zoom/pan/rotate actions.
|
/// A widget that translates finger/mouse gestures to zoom/pan/rotate actions.
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ class _FilamentGestureDetectorDesktopState
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
bool _scaling = false;
|
// ignore: unused_field
|
||||||
|
final bool _scaling = false;
|
||||||
|
|
||||||
bool _pointerMoving = false;
|
bool _pointerMoving = false;
|
||||||
|
|
||||||
@@ -78,7 +79,7 @@ class _FilamentGestureDetectorDesktopState
|
|||||||
|
|
||||||
// we don't want to end the zoom in the same frame, because this will destroy the camera manipulator (and cancel the zoom update).
|
// we don't want to end the zoom in the same frame, because this will destroy the camera manipulator (and cancel the zoom update).
|
||||||
// here, we just defer calling [zoomEnd] for 100ms to ensure the update is propagated through.
|
// here, we just defer calling [zoomEnd] for 100ms to ensure the update is propagated through.
|
||||||
_scrollTimer = Timer(Duration(milliseconds: 100), () async {
|
_scrollTimer = Timer(const Duration(milliseconds: 100), () async {
|
||||||
await widget.controller.zoomEnd();
|
await widget.controller.zoomEnd();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../filament_controller.dart';
|
import '../filament_controller.dart';
|
||||||
|
|
||||||
enum GestureType { RotateCamera, PanCamera, PanBackground }
|
enum GestureType { rotateCamera, panCamera, panBackground }
|
||||||
|
|
||||||
///
|
///
|
||||||
/// A widget that translates finger/mouse gestures to zoom/pan/rotate actions.
|
/// A widget that translates finger/mouse gestures to zoom/pan/rotate actions.
|
||||||
@@ -49,12 +49,12 @@ class FilamentGestureDetectorMobile extends StatefulWidget {
|
|||||||
|
|
||||||
class _FilamentGestureDetectorMobileState
|
class _FilamentGestureDetectorMobileState
|
||||||
extends State<FilamentGestureDetectorMobile> {
|
extends State<FilamentGestureDetectorMobile> {
|
||||||
GestureType gestureType = GestureType.PanCamera;
|
GestureType gestureType = GestureType.panCamera;
|
||||||
|
|
||||||
final _icons = {
|
final _icons = {
|
||||||
GestureType.PanBackground: Icons.image,
|
GestureType.panBackground: Icons.image,
|
||||||
GestureType.PanCamera: Icons.pan_tool,
|
GestureType.panCamera: Icons.pan_tool,
|
||||||
GestureType.RotateCamera: Icons.rotate_90_degrees_ccw
|
GestureType.rotateCamera: Icons.rotate_90_degrees_ccw
|
||||||
};
|
};
|
||||||
|
|
||||||
// on mobile, we can't differentiate between pointer down events like we do on desktop with primary/secondary/tertiary buttons
|
// on mobile, we can't differentiate between pointer down events like we do on desktop with primary/secondary/tertiary buttons
|
||||||
@@ -69,8 +69,11 @@ class _FilamentGestureDetectorMobileState
|
|||||||
// to avoid duplicating code for pan/rotate (panStart, panUpdate, panEnd, rotateStart, rotateUpdate etc)
|
// to avoid duplicating code for pan/rotate (panStart, panUpdate, panEnd, rotateStart, rotateUpdate etc)
|
||||||
// we have only a single function for start/update/end.
|
// we have only a single function for start/update/end.
|
||||||
// when the gesture type is changed, these properties are updated to point to the correct function.
|
// when the gesture type is changed, these properties are updated to point to the correct function.
|
||||||
|
// ignore: unused_field
|
||||||
late Function(double x, double y) _functionStart;
|
late Function(double x, double y) _functionStart;
|
||||||
|
// ignore: unused_field
|
||||||
late Function(double x, double y) _functionUpdate;
|
late Function(double x, double y) _functionUpdate;
|
||||||
|
// ignore: unused_field
|
||||||
late Function() _functionEnd;
|
late Function() _functionEnd;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -81,18 +84,18 @@ class _FilamentGestureDetectorMobileState
|
|||||||
|
|
||||||
void _setFunction() {
|
void _setFunction() {
|
||||||
switch (gestureType) {
|
switch (gestureType) {
|
||||||
case GestureType.RotateCamera:
|
case GestureType.rotateCamera:
|
||||||
_functionStart = widget.controller.rotateStart;
|
_functionStart = widget.controller.rotateStart;
|
||||||
_functionUpdate = widget.controller.rotateUpdate;
|
_functionUpdate = widget.controller.rotateUpdate;
|
||||||
_functionEnd = widget.controller.rotateEnd;
|
_functionEnd = widget.controller.rotateEnd;
|
||||||
break;
|
break;
|
||||||
case GestureType.PanCamera:
|
case GestureType.panCamera:
|
||||||
_functionStart = widget.controller.panStart;
|
_functionStart = widget.controller.panStart;
|
||||||
_functionUpdate = widget.controller.panUpdate;
|
_functionUpdate = widget.controller.panUpdate;
|
||||||
_functionEnd = widget.controller.panEnd;
|
_functionEnd = widget.controller.panEnd;
|
||||||
break;
|
break;
|
||||||
// TODO
|
// TODO
|
||||||
case GestureType.PanBackground:
|
case GestureType.panBackground:
|
||||||
_functionStart = (x, y) async {};
|
_functionStart = (x, y) async {};
|
||||||
_functionUpdate = (x, y) async {};
|
_functionUpdate = (x, y) async {};
|
||||||
_functionEnd = () async {};
|
_functionEnd = () async {};
|
||||||
@@ -109,6 +112,7 @@ class _FilamentGestureDetectorMobileState
|
|||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
Timer? _scrollTimer;
|
Timer? _scrollTimer;
|
||||||
double _lastScale = 0;
|
double _lastScale = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
import 'dart:developer' as dev;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -110,8 +111,7 @@ class _SizedFilamentWidget extends StatefulWidget {
|
|||||||
final FilamentController controller;
|
final FilamentController controller;
|
||||||
|
|
||||||
const _SizedFilamentWidget(
|
const _SizedFilamentWidget(
|
||||||
{super.key,
|
{required this.width,
|
||||||
required this.width,
|
|
||||||
required this.height,
|
required this.height,
|
||||||
this.initial,
|
this.initial,
|
||||||
required this.controller});
|
required this.controller});
|
||||||
@@ -145,7 +145,7 @@ class _SizedFilamentWidgetState extends State<_SizedFilamentWidget> {
|
|||||||
_pixelRatio = MediaQuery.of(context).devicePixelRatio;
|
_pixelRatio = MediaQuery.of(context).devicePixelRatio;
|
||||||
widget.controller.setDimensions(_rect, _pixelRatio);
|
widget.controller.setDimensions(_rect, _pixelRatio);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
print("Fatal error : $err");
|
dev.log("Fatal error : $err");
|
||||||
_error = err.toString();
|
_error = err.toString();
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@@ -158,7 +158,7 @@ class _SizedFilamentWidgetState extends State<_SizedFilamentWidget> {
|
|||||||
bool _resizing = false;
|
bool _resizing = false;
|
||||||
|
|
||||||
Future _resize() {
|
Future _resize() {
|
||||||
print("Resizing widget");
|
dev.log("Resizing widget");
|
||||||
final completer = Completer();
|
final completer = Completer();
|
||||||
// resizing the window can be sluggish (particular in debug mode), exacerbated when simultaneously recreating the swapchain and resize the window.
|
// resizing the window can be sluggish (particular in debug mode), exacerbated when simultaneously recreating the swapchain and resize the window.
|
||||||
// to address this, whenever the widget is resized, we set a timer for Xms in the future.
|
// to address this, whenever the widget is resized, we set a timer for Xms in the future.
|
||||||
@@ -186,7 +186,7 @@ class _SizedFilamentWidgetState extends State<_SizedFilamentWidget> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
_resizing = false;
|
_resizing = false;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
print("Error resizing FilamentWidget: $err");
|
dev.log("Error resizing FilamentWidget: $err");
|
||||||
} finally {
|
} finally {
|
||||||
completer.complete();
|
completer.complete();
|
||||||
}
|
}
|
||||||
@@ -215,21 +215,21 @@ class _SizedFilamentWidgetState extends State<_SizedFilamentWidget> {
|
|||||||
void _handleStateChange(AppLifecycleState state) async {
|
void _handleStateChange(AppLifecycleState state) async {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case AppLifecycleState.detached:
|
case AppLifecycleState.detached:
|
||||||
print("Detached");
|
dev.log("Detached");
|
||||||
if (!_wasRenderingOnInactive) {
|
if (!_wasRenderingOnInactive) {
|
||||||
_wasRenderingOnInactive = widget.controller.rendering;
|
_wasRenderingOnInactive = widget.controller.rendering;
|
||||||
}
|
}
|
||||||
await widget.controller.setRendering(false);
|
await widget.controller.setRendering(false);
|
||||||
break;
|
break;
|
||||||
case AppLifecycleState.hidden:
|
case AppLifecycleState.hidden:
|
||||||
print("Hidden");
|
dev.log("Hidden");
|
||||||
if (!_wasRenderingOnInactive) {
|
if (!_wasRenderingOnInactive) {
|
||||||
_wasRenderingOnInactive = widget.controller.rendering;
|
_wasRenderingOnInactive = widget.controller.rendering;
|
||||||
}
|
}
|
||||||
await widget.controller.setRendering(false);
|
await widget.controller.setRendering(false);
|
||||||
break;
|
break;
|
||||||
case AppLifecycleState.inactive:
|
case AppLifecycleState.inactive:
|
||||||
print("Inactive");
|
dev.log("Inactive");
|
||||||
if (!_wasRenderingOnInactive) {
|
if (!_wasRenderingOnInactive) {
|
||||||
_wasRenderingOnInactive = widget.controller.rendering;
|
_wasRenderingOnInactive = widget.controller.rendering;
|
||||||
}
|
}
|
||||||
@@ -238,14 +238,14 @@ class _SizedFilamentWidgetState extends State<_SizedFilamentWidget> {
|
|||||||
await widget.controller.setRendering(false);
|
await widget.controller.setRendering(false);
|
||||||
break;
|
break;
|
||||||
case AppLifecycleState.paused:
|
case AppLifecycleState.paused:
|
||||||
print("Paused");
|
dev.log("Paused");
|
||||||
if (!_wasRenderingOnInactive) {
|
if (!_wasRenderingOnInactive) {
|
||||||
_wasRenderingOnInactive = widget.controller.rendering;
|
_wasRenderingOnInactive = widget.controller.rendering;
|
||||||
}
|
}
|
||||||
await widget.controller.setRendering(false);
|
await widget.controller.setRendering(false);
|
||||||
break;
|
break;
|
||||||
case AppLifecycleState.resumed:
|
case AppLifecycleState.resumed:
|
||||||
print("Resumed");
|
dev.log("Resumed");
|
||||||
await widget.controller.setRendering(_wasRenderingOnInactive);
|
await widget.controller.setRendering(_wasRenderingOnInactive);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user